mirror of https://github.com/apache/cloudstack.git
Open vSwitch tunnel manager
Applying patch with new ovs-tunnel-manager on top of cloudstack oss-master
This commit is contained in:
parent
a1a615e018
commit
9f321ffeac
|
|
@ -48,6 +48,7 @@ public interface Network extends ControlledEntity {
|
|||
public static final Service StaticNat = new Service("StaticNat", Capability.ElasticIp);
|
||||
public static final Service PortForwarding = new Service("PortForwarding");
|
||||
public static final Service SecurityGroup = new Service("SecurityGroup");
|
||||
public static final Service Connectivity = new Service("Connectivity");
|
||||
|
||||
private String name;
|
||||
private Capability[] caps;
|
||||
|
|
@ -109,6 +110,7 @@ public interface Network extends ControlledEntity {
|
|||
public static final Provider ExternalGateWay = new Provider("ExternalGateWay", true);
|
||||
public static final Provider ElasticLoadBalancerVm = new Provider("ElasticLoadBalancerVm", false);
|
||||
public static final Provider SecurityGroupProvider = new Provider("SecurityGroupProvider", false);
|
||||
public static final Provider OvsConnectivityProvider = new Provider("OvsConnectivityProvider", false);
|
||||
public static final Provider None = new Provider("None", false);
|
||||
|
||||
private String name;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import com.cloud.agent.api.Command;
|
|||
public class OvsCreateTunnelAnswer extends Answer {
|
||||
Long from;
|
||||
Long to;
|
||||
long account;
|
||||
long networkId;
|
||||
String inPortName;
|
||||
|
||||
//for debug info
|
||||
|
|
@ -32,7 +32,7 @@ public class OvsCreateTunnelAnswer extends Answer {
|
|||
OvsCreateTunnelCommand c = (OvsCreateTunnelCommand)cmd;
|
||||
from = c.getFrom();
|
||||
to = c.getTo();
|
||||
account = c.getAccount();
|
||||
networkId = c.getNetworkId();
|
||||
inPortName = "[]";
|
||||
fromIp = c.getFromIp();
|
||||
toIp = c.getRemoteIp();
|
||||
|
|
@ -54,8 +54,8 @@ public class OvsCreateTunnelAnswer extends Answer {
|
|||
return to;
|
||||
}
|
||||
|
||||
public long getAccount() {
|
||||
return account;
|
||||
public long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
public String getInPortName() {
|
||||
|
|
@ -78,3 +78,4 @@ public class OvsCreateTunnelAnswer extends Answer {
|
|||
return bridge;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public class OvsCreateTunnelCommand extends Command {
|
|||
String remoteIp;
|
||||
Long from;
|
||||
Long to;
|
||||
long account;
|
||||
long networkId;
|
||||
|
||||
// for debug info
|
||||
String fromIp;
|
||||
|
|
@ -29,12 +29,12 @@ public class OvsCreateTunnelCommand extends Command {
|
|||
return true;
|
||||
}
|
||||
|
||||
public OvsCreateTunnelCommand(String remoteIp, String key, Long from, Long to, long account, String fromIp) {
|
||||
public OvsCreateTunnelCommand(String remoteIp, String key, Long from, Long to, long networkId, String fromIp) {
|
||||
this.remoteIp = remoteIp;
|
||||
this.key = key;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.account = account;
|
||||
this.networkId = networkId;
|
||||
this.fromIp = fromIp;
|
||||
}
|
||||
|
||||
|
|
@ -54,8 +54,8 @@ public class OvsCreateTunnelCommand extends Command {
|
|||
return to;
|
||||
}
|
||||
|
||||
public long getAccount() {
|
||||
return account;
|
||||
public long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
public String getFromIp() {
|
||||
|
|
|
|||
|
|
@ -15,16 +15,16 @@ package com.cloud.network.ovs;
|
|||
import com.cloud.agent.api.Command;
|
||||
|
||||
public class OvsDestroyTunnelCommand extends Command {
|
||||
long account;
|
||||
long networkId;
|
||||
String inPortName;
|
||||
|
||||
public OvsDestroyTunnelCommand(long account, String inPortName) {
|
||||
this.account = account;
|
||||
public OvsDestroyTunnelCommand(long networkId, String inPortName) {
|
||||
this.networkId = networkId;
|
||||
this.inPortName = inPortName;
|
||||
}
|
||||
|
||||
public long getAccount() {
|
||||
return account;
|
||||
public long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
public String getInPortName() {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ public interface NetworkOffering {
|
|||
|
||||
public final static String DefaultSharedNetworkOfferingWithSGService = "DefaultSharedNetworkOfferingWithSGService";
|
||||
public final static String DefaultIsolatedNetworkOfferingWithSourceNatService = "DefaultIsolatedNetworkOfferingWithSourceNatService";
|
||||
public final static String OvsIsolatedNetworkOfferingWithSourceNatService = "OvsIsolatedNetworkOfferingWithSourceNatService";
|
||||
public final static String DefaultSharedNetworkOffering = "DefaultSharedNetworkOffering";
|
||||
public final static String DefaultIsolatedNetworkOffering = "DefaultIsolatedNetworkOffering";
|
||||
public final static String DefaultSharedEIPandELBNetworkOffering = "DefaultSharedNetscalerEIPandELBNetworkOffering";
|
||||
|
|
|
|||
181
core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
Executable file → Normal file
181
core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
Executable file → Normal file
|
|
@ -177,6 +177,7 @@ import com.cloud.network.ovs.OvsCreateGreTunnelCommand;
|
|||
import com.cloud.network.ovs.OvsCreateTunnelAnswer;
|
||||
import com.cloud.network.ovs.OvsCreateTunnelCommand;
|
||||
import com.cloud.network.ovs.OvsDeleteFlowCommand;
|
||||
import com.cloud.network.ovs.OvsDestroyBridgeCommand;
|
||||
import com.cloud.network.ovs.OvsDestroyTunnelCommand;
|
||||
import com.cloud.network.ovs.OvsSetTagAndFlowAnswer;
|
||||
import com.cloud.network.ovs.OvsSetTagAndFlowCommand;
|
||||
|
|
@ -488,6 +489,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
return execute((NetworkRulesSystemVmCommand)cmd);
|
||||
} else if (clazz == OvsCreateTunnelCommand.class) {
|
||||
return execute((OvsCreateTunnelCommand)cmd);
|
||||
} else if (clazz == OvsDestroyBridgeCommand.class) {
|
||||
return execute((OvsDestroyBridgeCommand)cmd);
|
||||
} else if (clazz == OvsDestroyTunnelCommand.class) {
|
||||
return execute((OvsDestroyTunnelCommand)cmd);
|
||||
} else if (clazz == UpdateHostPasswordCommand.class) {
|
||||
|
|
@ -549,21 +552,33 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
VIF dom0vif = null;
|
||||
Pair<VM, VM.Record> vm = getControlDomain(conn);
|
||||
VM dom0 = vm.first();
|
||||
|
||||
s_logger.debug("Create a vif on dom0 for " + networkDesc);
|
||||
VIF.Record vifr = new VIF.Record();
|
||||
vifr.VM = dom0;
|
||||
vifr.device = getLowestAvailableVIFDeviceNum(conn, dom0);
|
||||
if (vifr.device == null) {
|
||||
s_logger.debug("Failed to create " + networkDesc + ", no vif available");
|
||||
return;
|
||||
// Create a VIF unless there's not already another VIF
|
||||
Set<VIF> dom0Vifs = dom0.getVIFs(conn);
|
||||
for (VIF vif:dom0Vifs) {
|
||||
vif.getRecord(conn);
|
||||
if (vif.getNetwork(conn).getUuid(conn) == nw.getUuid(conn)) {
|
||||
dom0vif = vif;
|
||||
s_logger.debug("### A dom0 VIF has already been found - No need to create one");
|
||||
}
|
||||
}
|
||||
Map<String, String> config = new HashMap<String, String>();
|
||||
config.put("nameLabel", vifNameLabel);
|
||||
vifr.otherConfig = config;
|
||||
vifr.MAC = "FE:FF:FF:FF:FF:FF";
|
||||
vifr.network = nw;
|
||||
dom0vif = VIF.create(conn, vifr);
|
||||
if (dom0vif == null) {
|
||||
s_logger.debug("Create a vif on dom0 for " + networkDesc);
|
||||
VIF.Record vifr = new VIF.Record();
|
||||
vifr.VM = dom0;
|
||||
vifr.device = getLowestAvailableVIFDeviceNum(conn, dom0);
|
||||
if (vifr.device == null) {
|
||||
s_logger.debug("Failed to create " + networkDesc + ", no vif available");
|
||||
return;
|
||||
}
|
||||
Map<String, String> config = new HashMap<String, String>();
|
||||
config.put("nameLabel", vifNameLabel);
|
||||
vifr.otherConfig = config;
|
||||
vifr.MAC = "FE:FF:FF:FF:FF:FF";
|
||||
vifr.network = nw;
|
||||
|
||||
dom0vif = VIF.create(conn, vifr);
|
||||
}
|
||||
// At this stage we surely have a VIF
|
||||
dom0vif.plug(conn);
|
||||
dom0vif.unplug(conn);
|
||||
synchronized(_tmpDom0Vif) {
|
||||
|
|
@ -599,30 +614,115 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
return null;
|
||||
}
|
||||
|
||||
private synchronized Network createTunnelNetwork(Connection conn, long account) {
|
||||
/**
|
||||
* This method just creates a XenServer network following the tunnel network naming convention
|
||||
*/
|
||||
private synchronized Network createTunnelNetwork(Connection conn, long networkId) {
|
||||
try {
|
||||
String nwName = "OVSTunnel" + account;
|
||||
String nwName = "OVSTunnel" + networkId;
|
||||
Network nw = null;
|
||||
Network.Record rec = new Network.Record();
|
||||
Set<Network> networks = Network.getByNameLabel(conn, nwName);
|
||||
|
||||
if (networks.size() == 0) {
|
||||
rec.nameDescription = "tunnel network for account " + account;
|
||||
rec.nameDescription = "tunnel network id# " + networkId;
|
||||
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);
|
||||
} else {
|
||||
nw = networks.iterator().next();
|
||||
}
|
||||
|
||||
enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + account);
|
||||
enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + networkId);
|
||||
s_logger.debug("### Xen Server network for tunnels created:" + nwName);
|
||||
return nw;
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("create tunnel network failed", e);
|
||||
s_logger.warn("createTunnelNetwork failed", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method creates a XenServer network and configures it for being used as a L2-in-L3 tunneled network
|
||||
*/
|
||||
private synchronized Network createAndConfigureTunnelNetwork(Connection conn, long networkId, long hostId) {
|
||||
try {
|
||||
Network nw = createTunnelNetwork(conn, networkId);
|
||||
//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);
|
||||
String configuredHosts = nwOtherConfig.get("ovs-host-setup");
|
||||
boolean configured = false;
|
||||
if (configuredHosts!=null) {
|
||||
String hostIdsStr[] = configuredHosts.split(",");
|
||||
for (String hostIdStr:hostIdsStr) {
|
||||
if (hostIdStr.equals(((Long)hostId).toString())) {
|
||||
configured = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!configured) {
|
||||
String result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge,
|
||||
"key", String.valueOf(networkId),
|
||||
"xs_nw_uuid", nw.getUuid(conn),
|
||||
"cs_host_id", ((Long)hostId).toString());
|
||||
//Note down the fact that the ovs bridge has been setup
|
||||
String[] res = result.split(":");
|
||||
if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) {
|
||||
//TODO: Should make this error not fatal?
|
||||
throw new CloudRuntimeException("Unable to pre-configure OVS bridge " + bridge + " for network ID:" + networkId +
|
||||
" - " + res);
|
||||
}
|
||||
}
|
||||
return nw;
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("createandConfigureTunnelNetwork failed", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized Network findTunnelNetwork(Connection conn, long networkId) {
|
||||
try {
|
||||
String nwName = "OVSTunnel" + networkId;
|
||||
Network nw = null;
|
||||
Set<Network> networks = Network.getByNameLabel(conn, nwName);
|
||||
if (networks.size() == 0) {
|
||||
String errorMessage = "Unable to find OVS bridge for network:" + networkId;
|
||||
s_logger.error(errorMessage);
|
||||
throw new CloudRuntimeException(errorMessage);
|
||||
} else {
|
||||
nw = networks.iterator().next();
|
||||
}
|
||||
s_logger.debug("### Xen Server network for tunnels found:" + nwName);
|
||||
return nw;
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("findTunnelNetwork failed:", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void destroyTunnelNetwork(Connection conn, long networkId) {
|
||||
try {
|
||||
Network nw = findTunnelNetwork(conn, networkId);
|
||||
String bridge = nw.getBridge(conn);
|
||||
String result = callHostPlugin(conn, "ovstunnel", "destroy_ovs_bridge", "bridge", bridge);
|
||||
String[] res = result.split(":");
|
||||
if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) {
|
||||
//TODO: Should make this error not fatal?
|
||||
//Can Concurrent VM shutdown/migration/reboot events can cause this method
|
||||
//to be executed on a bridge which has already been removed?
|
||||
throw new CloudRuntimeException("Unable to remove OVS bridge " + bridge + ":" + res);
|
||||
}
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("destroyTunnelNetwork failed:", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected Network getNetwork(Connection conn, NicTO nic) throws XenAPIException, XmlRpcException {
|
||||
String name = nic.getName();
|
||||
XsLocalNetwork network = getNativeNetworkForTraffic(conn, nic.getType(), name);
|
||||
|
|
@ -646,8 +746,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
_isOvs = true;
|
||||
return setupvSwitchNetwork(conn);
|
||||
} else {
|
||||
long account = Long.parseLong(nic.getBroadcastUri().getHost());
|
||||
return createTunnelNetwork(conn, account);
|
||||
long networkId = Long.parseLong(nic.getBroadcastUri().getHost());
|
||||
return createTunnelNetwork(conn, networkId);
|
||||
}
|
||||
} else if (nic.getBroadcastType() == BroadcastDomainType.Storage) {
|
||||
URI broadcastUri = nic.getBroadcastUri();
|
||||
|
|
@ -1111,6 +1211,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
|
||||
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()));
|
||||
|
|
@ -4701,16 +4802,28 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
return Boolean.valueOf(callHostPlugin(conn, "vmops", "can_bridge_firewall", "host_uuid", _host.uuid, "instance", _instance));
|
||||
}
|
||||
|
||||
private Answer execute(OvsDestroyBridgeCommand cmd) {
|
||||
Connection conn = getConnection();
|
||||
s_logger.debug("### About to destroy OVS bridge");
|
||||
destroyTunnelNetwork(conn, cmd.getNetworkId());
|
||||
s_logger.debug("### Bridge destroyed");
|
||||
return new Answer(cmd, true, null);
|
||||
}
|
||||
|
||||
private Answer execute(OvsDestroyTunnelCommand cmd) {
|
||||
Connection conn = getConnection();
|
||||
s_logger.debug("### About to destroy tunnel network");
|
||||
try {
|
||||
Network nw = createTunnelNetwork(conn, cmd.getAccount());
|
||||
Network nw = findTunnelNetwork(conn, cmd.getNetworkId());
|
||||
if (nw == null) {
|
||||
s_logger.warn("### Unable to find tunnel network");
|
||||
return new Answer(cmd, false, "No network found");
|
||||
}
|
||||
|
||||
String bridge = nw.getBridge(conn);
|
||||
s_logger.debug("### About to remove tunnel named:" + cmd.getInPortName());
|
||||
String result = callHostPlugin(conn, "ovstunnel", "destroy_tunnel", "bridge", bridge, "in_port", cmd.getInPortName());
|
||||
s_logger.debug("### Tunnel removed");
|
||||
if (result.equalsIgnoreCase("SUCCESS")) {
|
||||
return new Answer(cmd, true, result);
|
||||
} else {
|
||||
|
|
@ -4732,15 +4845,18 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
Connection conn = getConnection();
|
||||
String bridge = "unknown";
|
||||
try {
|
||||
Network nw = createTunnelNetwork(conn, cmd.getAccount());
|
||||
s_logger.debug("### About to create tunnel network");
|
||||
Network nw = createAndConfigureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getFrom());
|
||||
if (nw == null) {
|
||||
s_logger.debug("### SOMETHING WENT WRONG DURING NETWORK SETUP");
|
||||
return new OvsCreateTunnelAnswer(cmd, false, "Cannot create network", bridge);
|
||||
}
|
||||
|
||||
|
||||
bridge = nw.getBridge(conn);
|
||||
s_logger.debug("### The bridge is:" + bridge);
|
||||
String result = callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", cmd.getRemoteIp(), "key", cmd.getKey(), "from", cmd.getFrom().toString(), "to", cmd
|
||||
.getTo().toString());
|
||||
|
||||
s_logger.debug("### Result from create tunnel operation:" + result);
|
||||
String[] res = result.split(":");
|
||||
if (res.length == 2 && res[0].equalsIgnoreCase("SUCCESS")) {
|
||||
return new OvsCreateTunnelAnswer(cmd, true, result, res[1], bridge);
|
||||
|
|
@ -4748,7 +4864,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
return new OvsCreateTunnelAnswer(cmd, false, result, bridge);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("caught execption when creating ovs tunnel", e);
|
||||
s_logger.debug("### SOMETHING WENT WRONG DURING TUNNEL SETUP");
|
||||
s_logger.warn("caught execption when creating ovs tunnel", e);
|
||||
return new OvsCreateTunnelAnswer(cmd, false, e.getMessage(), bridge);
|
||||
}
|
||||
}
|
||||
|
|
@ -5131,12 +5248,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
VDI vdi = null;
|
||||
try {
|
||||
SR poolSr = getStorageRepository(conn, pool);
|
||||
|
||||
s_logger.debug("### STORAGE CREATE - Template URL:" + cmd.getTemplateUrl());
|
||||
if (cmd.getTemplateUrl() != null) {
|
||||
VDI tmpltvdi = null;
|
||||
|
||||
|
||||
tmpltvdi = getVDIbyUuid(conn, cmd.getTemplateUrl());
|
||||
s_logger.debug("### STORAGE CREATE - ABOUT TO CLONE VDI:" + tmpltvdi.getUuid(conn));
|
||||
vdi = tmpltvdi.createClone(conn, new HashMap<String, String>());
|
||||
s_logger.debug("### STORAGE CREATE - CLoned VDI:" + vdi.getUuid(conn));
|
||||
vdi.setNameLabel(conn, dskch.getName());
|
||||
} else {
|
||||
VDI.Record vdir = new VDI.Record();
|
||||
|
|
@ -5145,7 +5264,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
vdir.type = Types.VdiType.USER;
|
||||
|
||||
vdir.virtualSize = dskch.getSize();
|
||||
s_logger.debug("### STORAGE CREATE - Creating VDI with size:" + dskch.getSize());
|
||||
vdi = VDI.create(conn, vdir);
|
||||
s_logger.debug("### STORAGE CREATE - VDI created:" + vdi.getUuid(conn));
|
||||
}
|
||||
|
||||
VDI.Record vdir;
|
||||
|
|
|
|||
|
|
@ -4,4 +4,7 @@
|
|||
<pydev_project>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.6</pydev_property>
|
||||
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
||||
<path>/scripts</path>
|
||||
</pydev_pathproperty>
|
||||
</pydev_project>
|
||||
|
|
|
|||
|
|
@ -3,28 +3,94 @@
|
|||
#
|
||||
# A plugin for executing script needed by vmops cloud
|
||||
|
||||
import cloudstack_pluginlib as lib
|
||||
import logging
|
||||
import os, sys, time
|
||||
import subprocess
|
||||
import XenAPIPlugin
|
||||
sys.path.append("/opt/xensource/sm/")
|
||||
import util
|
||||
from util import CommandException
|
||||
import hostvmstats
|
||||
import socket
|
||||
import stat
|
||||
import base64
|
||||
import tempfile
|
||||
from os.path import exists as _exists
|
||||
from time import localtime as _localtime, asctime as _asctime
|
||||
|
||||
vSwitchDBPidFile = "/var/run/openvswitch/ovsdb-server.pid"
|
||||
vSwitchDBDaemonName = "ovsdb-server"
|
||||
vSwitchPidFile = "/var/run/openvswitch/ovs-vswitchd.pid"
|
||||
vsctlPath = "/usr/bin/ovs-vsctl"
|
||||
ofctlPath = "/usr/bin/ovs-ofctl"
|
||||
vSwitchDaemonName = "ovs-vswitchd"
|
||||
xePath= "/opt/xensource/bin/xe"
|
||||
lib.setup_logging("/var/log/ovstunnel.log")
|
||||
|
||||
def find_vifs_v5(xs_nw_uuid):
|
||||
logging.debug("Fetching vifs on networks - for XS version 5.x")
|
||||
vif_uuids_cmd = [xePath, 'network-list', 'uuid=%s' %xs_nw_uuid,
|
||||
'params=VIF-uuids', '--minimal']
|
||||
vif_uuids_str = lib.do_cmd(vif_uuids_cmd)
|
||||
vif_uuids = vif_uuids_str.split(';')
|
||||
vifs = []
|
||||
for vif_uuid in vif_uuids:
|
||||
vif_uuid = vif_uuid.strip()
|
||||
is_attached_cmd = [xePath, 'vif-list', 'uuid=%s' %vif_uuid,
|
||||
'params=currently-attached', '--minimal']
|
||||
is_attached = lib.do_cmd(is_attached_cmd)
|
||||
# Consider only attached VIFs
|
||||
if is_attached == 'false':
|
||||
continue
|
||||
vm_uuid_cmd = [xePath, 'vif-list', 'uuid=%s' %vif_uuid,
|
||||
'params=vm-uuid', '--minimal']
|
||||
vm_uuid = lib.do_cmd(vm_uuid_cmd)
|
||||
dom_id_cmd = [xePath, 'vm-list', 'uuid=%s' %vm_uuid,
|
||||
'params=dom-id', '--minimal']
|
||||
dom_id = lib.do_cmd(dom_id_cmd)
|
||||
device_cmd = [xePath, 'vif-list', 'uuid=%s' %vif_uuid,
|
||||
'params=device', '--minimal']
|
||||
device = lib.do_cmd(device_cmd)
|
||||
vifs.append("vif%s.%s" % (dom_id, device))
|
||||
logging.debug("Vifs on network:%s" %vifs)
|
||||
vif_ofports = []
|
||||
for vif in vifs:
|
||||
vif_ofport_cmd=[lib.VSCTL_PATH, 'get', 'interface', vif, 'ofport']
|
||||
vif_ofport = lib.do_cmd(vif_ofport_cmd).strip()
|
||||
if vif_ofport.endswith('\n'):
|
||||
vif_ofport = vif_ofport[:-1]
|
||||
vif_ofports.append(vif_ofport.strip())
|
||||
return vif_ofports
|
||||
|
||||
|
||||
def find_vifs_v6(xs_nw_uuid):
|
||||
logging.debug("Fetching vifs on networks - for XS version 6.x")
|
||||
cmd_vif_ofports = [lib.VSCTL_PATH, "--", "--columns=ofport",
|
||||
"find", "interface",
|
||||
"external_ids:xs-network-uuid=%s" % xs_nw_uuid,
|
||||
"type!=gre"]
|
||||
vif_ofports_str = lib.do_cmd(cmd_vif_ofports)
|
||||
vif_ofports = []
|
||||
for line in vif_ofports_str.split('\n'):
|
||||
elements = line.split(':')
|
||||
if len(elements)==2:
|
||||
# ensure no trailing \n is returned
|
||||
if elements[1].endswith('\n'):
|
||||
elements[1] = elements[1][:-1]
|
||||
vif_ofports.append(elements[1].strip())
|
||||
return vif_ofports
|
||||
|
||||
vif_ofport_list_handlers = {
|
||||
'5': find_vifs_v5,
|
||||
'6': find_vifs_v6}
|
||||
|
||||
|
||||
def block_ipv6_v5(bridge):
|
||||
lib.add_flow(bridge, priority=65000, dl_type='0x86dd', actions='drop')
|
||||
|
||||
|
||||
def block_ipv6_v6(bridge):
|
||||
lib.add_flow(bridge, priority=65000, proto='ipv6', actions='drop')
|
||||
|
||||
|
||||
block_ipv6_handlers = {
|
||||
'5': block_ipv6_v5,
|
||||
'6': block_ipv6_v6}
|
||||
|
||||
|
||||
class PluginError(Exception):
|
||||
"""Base Exception class for all plugin errors."""
|
||||
def __init__(self, *args):
|
||||
Exception.__init__(self, *args)
|
||||
|
||||
logFile = "/var/log/ovstunnel.log"
|
||||
fLog = None
|
||||
|
||||
def echo(fn):
|
||||
def wrapped(*v, **k):
|
||||
|
|
@ -35,229 +101,201 @@ def echo(fn):
|
|||
return res
|
||||
return wrapped
|
||||
|
||||
def open_log ():
|
||||
global fLog
|
||||
|
||||
try:
|
||||
if fLog == None:
|
||||
fLog = open (logFile, "a")
|
||||
except IOError, e:
|
||||
#print e
|
||||
pass
|
||||
|
||||
def pr (str):
|
||||
global fLog
|
||||
|
||||
if fLog != None:
|
||||
str = "[%s]:" % _asctime (_localtime()) + str + "\n"
|
||||
fLog.write (str)
|
||||
|
||||
def close_log ():
|
||||
global fLog
|
||||
|
||||
if fLog != None:
|
||||
fLog.close ()
|
||||
|
||||
def is_process_run (pidFile, name):
|
||||
try:
|
||||
fpid = open (pidFile, "r")
|
||||
pid = fpid.readline ()
|
||||
fpid.close ()
|
||||
except IOError, e:
|
||||
return -1
|
||||
|
||||
pid = pid[:-1]
|
||||
ps = os.popen ("ps -ae")
|
||||
for l in ps:
|
||||
if pid in l and name in l:
|
||||
ps.close ()
|
||||
return 0
|
||||
|
||||
ps.close ()
|
||||
return -2
|
||||
|
||||
def is_tool_exist (name):
|
||||
if _exists (name):
|
||||
return 0
|
||||
return -1
|
||||
|
||||
|
||||
def check_switch ():
|
||||
global result
|
||||
|
||||
ret = is_process_run (vSwitchDBPidFile, vSwitchDBDaemonName);
|
||||
if ret < 0:
|
||||
if ret == -1: return "NO_DB_PID_FILE"
|
||||
if ret == -2: return "DB_NOT_RUN"
|
||||
|
||||
ret = is_process_run (vSwitchPidFile, vSwitchDaemonName)
|
||||
if ret < 0:
|
||||
if ret == -1: return "NO_SWITCH_PID_FILE"
|
||||
if ret == -2: return "SWITCH_NOT_RUN"
|
||||
|
||||
if is_tool_exist (vsctlPath) < 0:
|
||||
return "NO_VSCTL"
|
||||
|
||||
if is_tool_exist (ofctlPath) < 0:
|
||||
return "NO_OFCTL"
|
||||
|
||||
return "SUCCESS"
|
||||
|
||||
def do_cmd (cmds, lines=False):
|
||||
cmd = ""
|
||||
for i in cmds:
|
||||
cmd += " "
|
||||
cmd += i
|
||||
|
||||
pr("do command '%s'" % cmd)
|
||||
f = os.popen (cmd)
|
||||
if lines == True:
|
||||
res = f.readlines ()
|
||||
else:
|
||||
res = f.readline ()
|
||||
res = res[:-1]
|
||||
f.close ()
|
||||
|
||||
if lines == False:
|
||||
pr("command output '%s'" % res)
|
||||
return res
|
||||
|
||||
######################## GRE creation utils ##########################
|
||||
# UUID's format is 8-4-4-4-12
|
||||
def is_uuid (uuid):
|
||||
list = uuid.split ("-")
|
||||
|
||||
if len (list) != 5:
|
||||
return -1
|
||||
|
||||
if len (list[0]) != 8 or len (list[1]) != 4 \
|
||||
or len (list[2]) != 4 or len (list[3]) != 4 \
|
||||
or len (list[4]) != 12:
|
||||
return -1
|
||||
|
||||
return 0
|
||||
|
||||
def set_flood_flow(bridge, inport):
|
||||
flow = "in_port=%s idle_timeout=0 hard_timeout=0 priority=10000 actions=flood" % inport
|
||||
add_flow(bridge, flow)
|
||||
|
||||
@echo
|
||||
def create_tunnel (session, args):
|
||||
def setup_ovs_bridge(session, args):
|
||||
bridge = args.pop("bridge")
|
||||
remoteIP = args.pop("remote_ip")
|
||||
greKey = args.pop("key")
|
||||
srcHost = args.pop("from")
|
||||
dstHost = args.pop("to")
|
||||
key = args.pop("key")
|
||||
xs_nw_uuid = args.pop("xs_nw_uuid")
|
||||
cs_host_id = args.pop("cs_host_id")
|
||||
|
||||
res = lib.check_switch()
|
||||
if res != "SUCCESS":
|
||||
return "FAILURE:%s" %res
|
||||
|
||||
res = check_switch()
|
||||
logging.debug("About to manually create the bridge:%s" %bridge)
|
||||
# create a bridge with the same name as the xapi network
|
||||
# also associate gre key in other config attribute
|
||||
res = lib.do_cmd([lib.VSCTL_PATH, "--", "--may-exist", "add-br", bridge,
|
||||
"--", "set", "bridge", bridge,
|
||||
"other_config:gre_key=%s" % key])
|
||||
logging.debug("Bridge has been manually created:%s" %res)
|
||||
# TODO: Make sure xs-network-uuid is set into external_ids
|
||||
lib.do_cmd([lib.VSCTL_PATH, "set", "Bridge", bridge,
|
||||
"external_ids:xs-network-uuid=%s" % xs_nw_uuid])
|
||||
# Non empty result means something went wrong
|
||||
if res:
|
||||
result = "FAILURE:%s" %res
|
||||
else:
|
||||
# Verify the bridge actually exists, with the gre_key properly set
|
||||
res = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge",
|
||||
bridge, "other_config:gre_key"])
|
||||
if key in res:
|
||||
result = "SUCCESS:%s" %bridge
|
||||
else:
|
||||
result = "FAILURE:%s" %res
|
||||
# Finally note in the xenapi network object that the network has
|
||||
# been configured
|
||||
xs_nw_uuid = lib.do_cmd([lib.XE_PATH, "network-list",
|
||||
"bridge=%s" % bridge, "--minimal"])
|
||||
lib.do_cmd([lib.XE_PATH,"network-param-set", "uuid=%s" % xs_nw_uuid,
|
||||
"other-config:is-ovs-tun-network=True"])
|
||||
conf_hosts = lib.do_cmd([lib.XE_PATH,"network-param-get",
|
||||
"uuid=%s" % xs_nw_uuid,
|
||||
"param-name=other-config",
|
||||
"param-key=ovs-host-setup", "--minimal"])
|
||||
conf_hosts = conf_hosts + ",%s" %cs_host_id
|
||||
lib.do_cmd([lib.XE_PATH,"network-param-set", "uuid=%s" % xs_nw_uuid,
|
||||
"other-config:ovs-host-setup=%s" %conf_hosts])
|
||||
|
||||
# BLOCK IPv6 - Flow spec changes with ovs version
|
||||
host_list_cmd = [lib.XE_PATH, 'host-list', '--minimal']
|
||||
host_list_str = lib.do_cmd(host_list_cmd)
|
||||
host_uuid = host_list_str.split(',')[0].strip()
|
||||
version_cmd = [lib.XE_PATH, 'host-param-get', 'uuid=%s' % host_uuid,
|
||||
'param-name=software-version',
|
||||
'param-key=product_version']
|
||||
version = lib.do_cmd(version_cmd)
|
||||
block_ipv6_handlers[version](bridge)
|
||||
lib.add_flow(bridge, priority=65000, proto='ipv6', actions='drop')
|
||||
logging.debug("Setup_ovs_bridge completed with result:%s" %result)
|
||||
return result
|
||||
|
||||
|
||||
@echo
|
||||
def destroy_ovs_bridge(session, args):
|
||||
bridge = args.pop("bridge")
|
||||
res = lib.check_switch()
|
||||
# TODO: Must complete this routine
|
||||
if res != "SUCCESS":
|
||||
return res
|
||||
|
||||
name = "%s-%s-%s-%s" % (bridge, srcHost, dstHost, greKey)
|
||||
|
||||
wait = [vsctlPath, "--timeout=30 wait-until bridge %s -- get bridge %s name" % \
|
||||
(bridge, bridge)]
|
||||
res = do_cmd(wait)
|
||||
if bridge not in res:
|
||||
pr("WARNIING:Can't find bridge %s for creating tunnel!" % bridge)
|
||||
result = "COMMAND_FAILED_NO_BRIDGE"
|
||||
return result
|
||||
|
||||
createInterface = [vsctlPath, "create interface", "name=%s" % name, \
|
||||
'type=gre options:remote_ip=%s options:key=%s' % (remoteIP, greKey)]
|
||||
ifaceUUID = do_cmd (createInterface)
|
||||
if is_uuid (ifaceUUID) < 0:
|
||||
pr("create interface failed, %s is not UUID" % ifaceUUID)
|
||||
result = "COMMAND_FAILED_CREATE_INTERFACE_FAILED"
|
||||
return result
|
||||
|
||||
createPort = [vsctlPath, "create port", "name=%s" % name, \
|
||||
"interfaces=[%s]" % ifaceUUID]
|
||||
portUUID = do_cmd (createPort)
|
||||
if is_uuid (portUUID) < 0:
|
||||
pr("create port failed, %s is not UUID" % portUUID)
|
||||
result = "COMMAND_FAILED_CREATE_PORT_FAILED"
|
||||
return result
|
||||
|
||||
addBridge = [vsctlPath, "add bridge %s" % bridge, "ports %s" % portUUID]
|
||||
do_cmd (addBridge)
|
||||
|
||||
wait = [vsctlPath, "--timeout=30 wait-until port %s -- get port %s name" % \
|
||||
(name, name)]
|
||||
res = do_cmd(wait)
|
||||
if name in res:
|
||||
port = get_field_of_interface(name, "ofport");
|
||||
if port == "[]":
|
||||
return "COMMAND_FAILED_PORT_IS_[]"
|
||||
|
||||
noFlood = [ofctlPath, "mod-port %s %s noflood" % (bridge, \
|
||||
port)]
|
||||
do_cmd(noFlood)
|
||||
|
||||
set_flood_flow(bridge, port)
|
||||
pr("create tunnel successful(bridge=%s, remote_ip=%s, key=%s, from=%s, to=%s" % \
|
||||
(bridge, remoteIP, greKey, srcHost, dstHost))
|
||||
result = "SUCCESS:%s" % name
|
||||
res = lib.do_cmd([lib.VSCTL_PATH, "del-br", bridge])
|
||||
logging.debug("Bridge has been manually removed:%s" %res)
|
||||
if res:
|
||||
result = "FAILURE:%s" %res
|
||||
else:
|
||||
pr("create gre tunnel failed")
|
||||
result = "COMMAND_FAILED_CREATE_TUNNEL_FAILED"
|
||||
|
||||
# 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"])
|
||||
result = "SUCCESS:%s" %bridge
|
||||
|
||||
logging.debug("Destroy_ovs_bridge completed with result:%s" %result)
|
||||
return result
|
||||
######################## End GRE creation utils ##########################
|
||||
|
||||
|
||||
@echo
|
||||
def create_tunnel(session, args):
|
||||
bridge = args.pop("bridge")
|
||||
remote_ip = args.pop("remote_ip")
|
||||
gre_key = args.pop("key")
|
||||
src_host = args.pop("from")
|
||||
dst_host = args.pop("to")
|
||||
|
||||
logging.debug("Entering create_tunnel")
|
||||
|
||||
res = lib.check_switch()
|
||||
if res != "SUCCESS":
|
||||
logging.debug("Openvswitch running: NO")
|
||||
return "FAILURE:%s" %res
|
||||
|
||||
# We need to keep the name below 14 characters
|
||||
# src and target are enough - consider a fixed length hash
|
||||
name = "t%s-%s-%s" % (gre_key, src_host, dst_host)
|
||||
|
||||
# Verify the xapi bridge to be created
|
||||
# NOTE: Timeout should not be necessary anymore
|
||||
wait = [lib.VSCTL_PATH, "--timeout=30", "wait-until", "bridge", bridge, "--",
|
||||
"get", "bridge", bridge, "name"]
|
||||
res = lib.do_cmd(wait)
|
||||
if bridge not in res:
|
||||
logging.debug("WARNING:Can't find bridge %s for creating " +
|
||||
"tunnel!" % bridge)
|
||||
return "FAILURE:NO_BRIDGE"
|
||||
logging.debug("bridge %s for creating tunnel - VERIFIED" % bridge)
|
||||
tunnel_setup = False
|
||||
drop_flow_setup = False
|
||||
try:
|
||||
# Create a port and configure the tunnel interface for it
|
||||
add_tunnel = [lib.VSCTL_PATH, "add-port", bridge, name, "--", "set", "interface",
|
||||
name, "type=gre", "options:key=%s" % gre_key,
|
||||
"options:remote_ip=%s" % remote_ip]
|
||||
lib.do_cmd(add_tunnel)
|
||||
tunnel_setup = True
|
||||
# verify port
|
||||
verify_port = [lib.VSCTL_PATH, "get", "port", name, "interfaces"]
|
||||
res = lib.do_cmd(verify_port)
|
||||
# Expecting python-style list as output
|
||||
iface_list = []
|
||||
if len(res) > 2:
|
||||
iface_list = res.strip()[1:-1].split(',')
|
||||
if len(iface_list) != 1:
|
||||
logging.debug("WARNING: Unexpected output while verifying " +
|
||||
"port %s on bridge %s" %(name, bridge))
|
||||
return "FAILURE:VERIFY_PORT_FAILED"
|
||||
|
||||
# verify interface
|
||||
iface_uuid = iface_list[0]
|
||||
verify_interface_key = [lib.VSCTL_PATH, "get", "interface",
|
||||
iface_uuid, "options:key"]
|
||||
verify_interface_ip = [lib.VSCTL_PATH, "get", "interface",
|
||||
iface_uuid, "options:remote_ip"]
|
||||
|
||||
key_validation = lib.do_cmd(verify_interface_key)
|
||||
ip_validation = lib.do_cmd(verify_interface_ip)
|
||||
|
||||
if not gre_key in key_validation or not remote_ip in ip_validation:
|
||||
logging.debug("WARNING: Unexpected output while verifying " +
|
||||
"interface %s on bridge %s" %(name, bridge))
|
||||
return "FAILURE:VERIFY_INTERFACE_FAILED"
|
||||
logging.debug("Tunnel interface validated:%s" %verify_interface_ip)
|
||||
cmd_tun_ofport = [lib.VSCTL_PATH, "get", "interface",
|
||||
iface_uuid, "ofport"]
|
||||
tun_ofport = lib.do_cmd(cmd_tun_ofport)
|
||||
# Ensure no trailing LF
|
||||
if tun_ofport.endswith('\n'):
|
||||
tun_ofport = tun_ofport[:-1]
|
||||
# add flow entryies for dropping broadcast coming in from gre tunnel
|
||||
lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
|
||||
dl_dst='ff:ff:ff:ff:ff:ff', actions='drop')
|
||||
lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
|
||||
nw_dst='224.0.0.0/24', actions='drop')
|
||||
drop_flow_setup = True
|
||||
logging.debug("Broadcast drop rules added")
|
||||
return "SUCCESS:%s" % name
|
||||
except:
|
||||
logging.debug("An unexpected error occured. Rolling back")
|
||||
if tunnel_setup:
|
||||
logging.debug("Deleting GRE interface")
|
||||
# Destroy GRE port and interface
|
||||
lib.del_port(bridge, name)
|
||||
if drop_flow_setup:
|
||||
# Delete flows
|
||||
logging.debug("Deleting flow entries from GRE interface")
|
||||
lib.del_flows(bridge, in_port=tun_ofport)
|
||||
raise
|
||||
|
||||
def del_all_flows(bridge):
|
||||
delFlow = [ofctlPath, "del-flows %s" % bridge]
|
||||
do_cmd(delFlow)
|
||||
|
||||
normalFlow = "priority=0 idle_timeout=0 hard_timeout=0 actions=normal"
|
||||
add_flow(bridge, normalFlow)
|
||||
|
||||
def del_flows(bridge, ofport):
|
||||
delFlow = [ofctlPath, 'del-flows %s "in_port=%s"' % (bridge, ofport)]
|
||||
do_cmd(delFlow)
|
||||
|
||||
def del_port(bridge, port):
|
||||
delPort = [vsctlPath, "del-port %s %s" % (bridge, port)]
|
||||
do_cmd(delPort)
|
||||
|
||||
@echo
|
||||
def destroy_tunnel(session, args):
|
||||
bridge = args.pop("bridge")
|
||||
inPort = args.pop("in_port")
|
||||
|
||||
# delete all gre ports on bridge
|
||||
if inPort == "[]":
|
||||
listPorts = [vsctlPath, "list-ports %s" % bridge]
|
||||
res = do_cmd(listPorts, True)
|
||||
for p in res:
|
||||
if bridge in p:
|
||||
del_port(bridge, p)
|
||||
del_all_flows(bridge)
|
||||
else:
|
||||
ofport = get_field_of_interface(inPort, "ofport")
|
||||
del_flows(bridge, ofport)
|
||||
del_port(bridge, inPort)
|
||||
|
||||
iface_name = args.pop("in_port")
|
||||
logging.debug("Destroying tunnel at port %s for bridge %s"
|
||||
% (iface_name, bridge))
|
||||
ofport = get_field_of_interface(iface_name, "ofport")
|
||||
lib.del_flows(bridge, in_port=ofport)
|
||||
lib.del_port(bridge, iface_name)
|
||||
return "SUCCESS"
|
||||
|
||||
def get_field_of_interface(nameOruuid, field):
|
||||
listIface = [vsctlPath, "list interface", nameOruuid]
|
||||
res = do_cmd(listIface, True)
|
||||
|
||||
for i in res:
|
||||
if field in i:
|
||||
(x, r) = i.split(":")
|
||||
return r.lstrip().rstrip()
|
||||
return None
|
||||
|
||||
|
||||
def add_flow(bridge, flow):
|
||||
param = bridge + ' "%s"' % flow
|
||||
addflow = ["ovs-ofctl add-flow", param]
|
||||
do_cmd (addflow)
|
||||
def get_field_of_interface(iface_name, field):
|
||||
get_iface_cmd = [lib.VSCTL_PATH, "get","interface", iface_name, field]
|
||||
res = lib.do_cmd(get_iface_cmd)
|
||||
return res
|
||||
|
||||
if __name__ == "__main__":
|
||||
open_log()
|
||||
XenAPIPlugin.dispatch({"create_tunnel":create_tunnel, "destroy_tunnel":destroy_tunnel})
|
||||
close_log()
|
||||
|
||||
XenAPIPlugin.dispatch({"create_tunnel":create_tunnel,
|
||||
"destroy_tunnel":destroy_tunnel,
|
||||
"setup_ovs_bridge": setup_ovs_bridge,
|
||||
"destroy_ovs_bridge": destroy_ovs_bridge})
|
||||
|
|
|
|||
|
|
@ -441,7 +441,7 @@ def can_bridge_firewall(session, args):
|
|||
os.makedirs('/var/run/cloud')
|
||||
if not os.path.exists('/var/cache/cloud'):
|
||||
os.makedirs('/var/cache/cloud')
|
||||
get_ipset_keyword()
|
||||
#get_ipset_keyword()
|
||||
|
||||
cleanup_rules_for_dead_vms(session)
|
||||
cleanup_rules(session, args)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@
|
|||
# If [source path] does not start with '/' or '~', then it is relative path to the location of the patch file.
|
||||
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
|
||||
cloudstack_plugins.conf=..,0644,/etc/xensource
|
||||
cloudstack_pluginlib.py=..,0755,/etc/xapi.d/plugins
|
||||
ovsgre=..,0755,/etc/xapi.d/plugins
|
||||
ovstunnel=..,0755,/etc/xapi.d/plugins
|
||||
vmopsSnapshot=..,0755,/etc/xapi.d/plugins
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@
|
|||
# If [source path] does not start with '/' or '~', then it is relative path to the location of the patch file.
|
||||
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
|
||||
cloudstack_plugins.conf=..,0644,/etc/xensource
|
||||
cloudstack_pluginlib.py=..,0755,/etc/xapi.d/plugins
|
||||
ovsgre=..,0755,/etc/xapi.d/plugins
|
||||
ovstunnel=..,0755,/etc/xapi.d/plugins
|
||||
vmopsSnapshot=..,0755,/etc/xapi.d/plugins
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ import com.cloud.network.lb.dao.ElasticLbVmMapDaoImpl;
|
|||
import com.cloud.network.ovs.OvsNetworkManagerImpl;
|
||||
import com.cloud.network.ovs.OvsTunnelManagerImpl;
|
||||
import com.cloud.network.ovs.dao.GreTunnelDaoImpl;
|
||||
import com.cloud.network.ovs.dao.OvsTunnelAccountDaoImpl;
|
||||
import com.cloud.network.ovs.dao.OvsTunnelNetworkDaoImpl;
|
||||
import com.cloud.network.ovs.dao.OvsTunnelDaoImpl;
|
||||
import com.cloud.network.ovs.dao.OvsWorkDaoImpl;
|
||||
import com.cloud.network.ovs.dao.VlanMappingDaoImpl;
|
||||
|
|
@ -300,7 +300,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
|
|||
addDao("VmFlowLogDao", VmFlowLogDaoImpl.class);
|
||||
addDao("GreTunnelDao", GreTunnelDaoImpl.class);
|
||||
addDao("OvsTunnelDao", OvsTunnelDaoImpl.class);
|
||||
addDao("OvsTunnelAccountDao", OvsTunnelAccountDaoImpl.class);
|
||||
addDao("OvsTunnelAccountDao", OvsTunnelNetworkDaoImpl.class);
|
||||
addDao("StoragePoolWorkDao", StoragePoolWorkDaoImpl.class);
|
||||
addDao("HostTagsDao", HostTagsDaoImpl.class);
|
||||
addDao("NetworkDomainDao", NetworkDomainDaoImpl.class);
|
||||
|
|
|
|||
|
|
@ -127,7 +127,8 @@ public interface NetworkManager extends NetworkService {
|
|||
void prepare(VirtualMachineProfile<? extends VMInstanceVO> profile, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException, ConcurrentOperationException,
|
||||
ResourceUnavailableException;
|
||||
|
||||
void release(VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean forced);
|
||||
void release(VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean forced) throws
|
||||
ConcurrentOperationException, ResourceUnavailableException;
|
||||
|
||||
void cleanupNics(VirtualMachineProfile<? extends VMInstanceVO> vm);
|
||||
|
||||
|
|
@ -204,6 +205,8 @@ public interface NetworkManager extends NetworkService {
|
|||
String getIpOfNetworkElementInVirtualNetwork(long accountId, long dataCenterId);
|
||||
|
||||
List<NetworkVO> listNetworksForAccount(long accountId, long zoneId, Network.GuestType type);
|
||||
|
||||
List<NetworkVO> listAllNetworksInAllZonesByType(Network.GuestType type);
|
||||
|
||||
IPAddressVO markIpAsUnavailable(long addrId);
|
||||
|
||||
|
|
|
|||
|
|
@ -1946,7 +1946,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
|||
}
|
||||
|
||||
@Override
|
||||
public void release(VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean forced) {
|
||||
public void release(VirtualMachineProfile<? extends VMInstanceVO> vmProfile, boolean forced) throws
|
||||
ConcurrentOperationException, ResourceUnavailableException {
|
||||
List<NicVO> nics = _nicDao.listByVmId(vmProfile.getId());
|
||||
for (NicVO nic : nics) {
|
||||
NetworkVO network = _networksDao.findById(nic.getNetworkId());
|
||||
|
|
@ -1966,6 +1967,16 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
|||
_nicDao.update(nic.getId(), nic);
|
||||
}
|
||||
}
|
||||
// Perform release on network elements
|
||||
for (NetworkElement element : _networkElements) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Asking " + element.getName() + " to release " + nic);
|
||||
}
|
||||
//NOTE: Context appear to never be used in release method
|
||||
//implementations. Consider removing it from interface Element
|
||||
element.release(network, profile, vmProfile, null);
|
||||
}
|
||||
|
||||
} else {
|
||||
nic.setState(Nic.State.Allocated);
|
||||
updateNic(nic, network.getId(), -1);
|
||||
|
|
@ -3926,6 +3937,17 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
|||
return accountNetworks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NetworkVO> listAllNetworksInAllZonesByType(Network.GuestType type) {
|
||||
List<NetworkVO> networks = new ArrayList<NetworkVO>();
|
||||
for (NetworkVO network: _networksDao.listAll()) {
|
||||
if (!isNetworkSystem(network)) {
|
||||
networks.add(network);
|
||||
}
|
||||
}
|
||||
return networks;
|
||||
}
|
||||
|
||||
@DB
|
||||
@Override
|
||||
public IPAddressVO markIpAsUnavailable(long addrId) {
|
||||
|
|
|
|||
|
|
@ -66,7 +66,8 @@ public class OvsElement extends AdapterBase implements NetworkElement {
|
|||
DeployDestination dest, ReservationContext context)
|
||||
throws ConcurrentOperationException, ResourceUnavailableException,
|
||||
InsufficientCapacityException {
|
||||
return true;
|
||||
//Consider actually implementing the network here
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -83,12 +84,16 @@ public class OvsElement extends AdapterBase implements NetworkElement {
|
|||
return true;
|
||||
}
|
||||
|
||||
//NOTE (Salvatore Orlando):
|
||||
//The code for ovs Vlan Manager has not been touched. Only the OVS tunnel
|
||||
//manager has been restored. Ideally, the code for OVS Vlan Manager should go.
|
||||
_ovsVlanMgr.VmCheckAndCreateTunnel(vm, dest);
|
||||
String command = _ovsVlanMgr.applyDefaultFlow(vm.getVirtualMachine(), dest);
|
||||
if (command != null) {
|
||||
nic.setBroadcastUri(BroadcastDomainType.Vswitch.toUri(command));
|
||||
}
|
||||
_ovsTunnelMgr.VmCheckAndCreateTunnel(vm, dest);
|
||||
_ovsTunnelMgr.VmCheckAndCreateTunnel(vm, network, dest);
|
||||
//_ovsTunnelMgr.applyDefaultFlow(vm.getVirtualMachine(), dest);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -106,7 +111,7 @@ public class OvsElement extends AdapterBase implements NetworkElement {
|
|||
return true;
|
||||
}
|
||||
|
||||
_ovsTunnelMgr.CheckAndDestroyTunnel(vm.getVirtualMachine());
|
||||
_ovsTunnelMgr.CheckAndDestroyTunnel(vm.getVirtualMachine(), network);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +123,7 @@ public class OvsElement extends AdapterBase implements NetworkElement {
|
|||
|
||||
@Override
|
||||
public boolean isReady(PhysicalNetworkServiceProvider provider) {
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -64,14 +64,11 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru {
|
|||
@Inject
|
||||
DataCenterDao _zoneDao;
|
||||
@Inject
|
||||
ConfigurationDao _configDao;
|
||||
@Inject
|
||||
PortForwardingRulesDao _pfRulesDao;
|
||||
@Inject
|
||||
OvsNetworkManager _ovsNetworkMgr;
|
||||
@Inject
|
||||
OvsTunnelManager _tunnelMgr;
|
||||
@Inject PhysicalNetworkDao _physicalNetworkDao;
|
||||
|
||||
@Override
|
||||
public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
|
||||
|
|
@ -167,29 +164,6 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru {
|
|||
return implemented;
|
||||
}
|
||||
|
||||
public int getVlanOffset(long physicalNetworkId, int vlanTag) {
|
||||
PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
|
||||
if (pNetwork == null) {
|
||||
throw new CloudRuntimeException("Could not find the physical Network " + physicalNetworkId + ".");
|
||||
}
|
||||
|
||||
if (pNetwork.getVnet() == null) {
|
||||
throw new CloudRuntimeException("Could not find vlan range for physical Network " + physicalNetworkId + ".");
|
||||
}
|
||||
String vlanRange[] = pNetwork.getVnet().split("-");
|
||||
int lowestVlanTag = Integer.valueOf(vlanRange[0]);
|
||||
return vlanTag - lowestVlanTag;
|
||||
}
|
||||
|
||||
public int getGloballyConfiguredCidrSize() {
|
||||
try {
|
||||
String globalVlanBits = _configDao.getValue(Config.GuestVlanBits.key());
|
||||
return 8 + Integer.parseInt(globalVlanBits);
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException("Failed to read the globally configured VLAN bits size.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NicProfile allocate(Network config, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm) throws InsufficientVirtualNetworkCapcityException,
|
||||
InsufficientAddressCapacityException {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ import javax.ejb.Local;
|
|||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.DataCenter.NetworkType;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
|
|
@ -40,12 +42,14 @@ import com.cloud.network.Network.State;
|
|||
import com.cloud.network.NetworkManager;
|
||||
import com.cloud.network.NetworkProfile;
|
||||
import com.cloud.network.NetworkVO;
|
||||
import com.cloud.network.PhysicalNetworkVO;
|
||||
import com.cloud.network.Networks.AddressFormat;
|
||||
import com.cloud.network.Networks.BroadcastDomainType;
|
||||
import com.cloud.network.Networks.Mode;
|
||||
import com.cloud.network.Networks.TrafficType;
|
||||
import com.cloud.network.dao.IPAddressDao;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.PhysicalNetworkDao;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
|
|
@ -75,9 +79,13 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
|
|||
@Inject
|
||||
protected NicDao _nicDao;
|
||||
@Inject
|
||||
ConfigurationDao _configDao;
|
||||
@Inject
|
||||
protected NetworkDao _networkDao;
|
||||
@Inject
|
||||
IPAddressDao _ipAddressDao;
|
||||
@Inject
|
||||
protected PhysicalNetworkDao _physicalNetworkDao;
|
||||
Random _rand = new Random(System.currentTimeMillis());
|
||||
|
||||
private static final TrafficType[] _trafficTypes = {TrafficType.Guest};
|
||||
|
|
@ -267,6 +275,43 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
|
|||
return new Ip4Address(ip);
|
||||
}
|
||||
|
||||
public int getVlanOffset(long physicalNetworkId, int vlanTag) {
|
||||
PhysicalNetworkVO pNetwork = _physicalNetworkDao.findById(physicalNetworkId);
|
||||
if (pNetwork == null) {
|
||||
throw new CloudRuntimeException("Could not find the physical Network " + physicalNetworkId + ".");
|
||||
}
|
||||
|
||||
if (pNetwork.getVnet() == null) {
|
||||
throw new CloudRuntimeException("Could not find vlan range for physical Network " + physicalNetworkId + ".");
|
||||
}
|
||||
String vlanRange[] = pNetwork.getVnet().split("-");
|
||||
int lowestVlanTag = Integer.valueOf(vlanRange[0]);
|
||||
return vlanTag - lowestVlanTag;
|
||||
}
|
||||
|
||||
public int getGloballyConfiguredCidrSize() {
|
||||
try {
|
||||
String globalVlanBits = _configDao.getValue(Config.GuestVlanBits.key());
|
||||
return 8 + Integer.parseInt(globalVlanBits);
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException("Failed to read the globally configured VLAN bits size.");
|
||||
}
|
||||
}
|
||||
|
||||
protected void allocateVnet(Network network, NetworkVO implemented, long dcId,
|
||||
long physicalNetworkId, String reservationId) throws InsufficientVirtualNetworkCapcityException {
|
||||
if (network.getBroadcastUri() == null) {
|
||||
String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId);
|
||||
if (vnet == null) {
|
||||
throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a part of network " + network + " implement ", DataCenter.class, dcId);
|
||||
}
|
||||
implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vnet));
|
||||
EventUtils.saveEvent(UserContext.current().getCallerUserId(), network.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: "+vnet+ " Network Id: "+network.getId(), 0);
|
||||
} else {
|
||||
implemented.setBroadcastUri(network.getBroadcastUri());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException {
|
||||
assert (network.getState() == State.Implementing) : "Why are we implementing " + network;
|
||||
|
|
@ -279,16 +324,7 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
|
|||
NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated,
|
||||
network.getDataCenterId(), physicalNetworkId);
|
||||
|
||||
if (network.getBroadcastUri() == null) {
|
||||
String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), context.getReservationId());
|
||||
if (vnet == null) {
|
||||
throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a part of network " + network + " implement ", DataCenter.class, dcId);
|
||||
}
|
||||
implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vnet));
|
||||
EventUtils.saveEvent(UserContext.current().getCallerUserId(), network.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: "+vnet+ " Network Id: "+network.getId(), 0);
|
||||
} else {
|
||||
implemented.setBroadcastUri(network.getBroadcastUri());
|
||||
}
|
||||
allocateVnet(network, implemented, dcId, physicalNetworkId, context.getReservationId());
|
||||
|
||||
if (network.getGateway() != null) {
|
||||
implemented.setGateway(network.getGateway());
|
||||
|
|
|
|||
|
|
@ -14,8 +14,11 @@ package com.cloud.network.guru;
|
|||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.NetworkManager;
|
||||
|
|
@ -25,12 +28,18 @@ import com.cloud.network.ovs.OvsTunnelManager;
|
|||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.component.Inject;
|
||||
import com.cloud.vm.Nic.ReservationStrategy;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.ReservationContext;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.network.Networks.BroadcastDomainType;
|
||||
import com.cloud.network.Network.State;
|
||||
|
||||
@Local(value=NetworkGuru.class)
|
||||
public class OvsGuestNetworkGuru extends GuestNetworkGuru {
|
||||
private static final Logger s_logger = Logger.getLogger(OvsGuestNetworkGuru.class);
|
||||
|
||||
@Inject OvsNetworkManager _ovsNetworkMgr;
|
||||
@Inject NetworkManager _externalNetworkManager;
|
||||
@Inject OvsTunnelManager _ovsTunnelMgr;
|
||||
|
|
@ -52,23 +61,29 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru {
|
|||
return config;
|
||||
}
|
||||
|
||||
protected void allocateVnet(Network network, NetworkVO implemented, long dcId,
|
||||
long physicalNetworkId, String reservationId) throws InsufficientVirtualNetworkCapcityException {
|
||||
// Overriden as an empty method to avoid Vnet allocation when OVS is the network manager
|
||||
}
|
||||
|
||||
@Override
|
||||
public Network implement(Network config, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException {
|
||||
public Network implement(Network config, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException {
|
||||
assert (config.getState() == State.Implementing) : "Why are we implementing " + config;
|
||||
if (!_ovsNetworkMgr.isOvsNetworkEnabled()&& !_ovsTunnelMgr.isOvsTunnelEnabled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
s_logger.debug("### Implementing network:" + config.getId() + " in OVS Guest Network Guru");
|
||||
// The above call will NOT reserve a Vnet
|
||||
NetworkVO implemented = (NetworkVO)super.implement(config, offering, dest, context);
|
||||
|
||||
String uri = null;
|
||||
if (_ovsNetworkMgr.isOvsNetworkEnabled()) {
|
||||
uri = "vlan";
|
||||
} else if (_ovsTunnelMgr.isOvsTunnelEnabled()) {
|
||||
uri = Long.toString(config.getAccountId());
|
||||
uri = Long.toString(config.getId());
|
||||
}
|
||||
|
||||
s_logger.debug("### URI value:" + uri);
|
||||
implemented.setBroadcastUri(BroadcastDomainType.Vswitch.toUri(uri));
|
||||
s_logger.debug("### Broadcast URI is:" + implemented.getBroadcastUri().toString());
|
||||
return implemented;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ import com.cloud.host.Host;
|
|||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.Status;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.network.Network.GuestType;
|
||||
import com.cloud.network.NetworkManager;
|
||||
import com.cloud.network.NetworkVO;
|
||||
import com.cloud.network.ovs.dao.GreTunnelVO;
|
||||
import com.cloud.network.ovs.dao.OvsTunnelDao;
|
||||
import com.cloud.network.ovs.dao.OvsTunnelVO;
|
||||
|
|
@ -40,12 +43,14 @@ public class OvsTunnelListener implements Listener {
|
|||
HostDao _hostDao;
|
||||
OvsTunnelDao _tunnelDao;
|
||||
ResourceManager _resourceMgr;
|
||||
NetworkManager _networkMgr;
|
||||
|
||||
public OvsTunnelListener(OvsTunnelDao tunnelDao, HostDao hostDao) {
|
||||
this._hostDao = hostDao;
|
||||
this._tunnelDao = tunnelDao;
|
||||
ComponentLocator locator = ComponentLocator.getLocator("management-server");
|
||||
_resourceMgr = locator.getManager(ResourceManager.class);
|
||||
_networkMgr = locator.getManager(NetworkManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -74,36 +79,38 @@ public class OvsTunnelListener implements Listener {
|
|||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
List<HostVO> hosts = _resourceMgr.listAllHostsInAllZonesByType(Host.Type.Routing);
|
||||
for (HostVO h : hosts) {
|
||||
if (h.getId() == host.getId()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
OvsTunnelVO t = _tunnelDao.getByFromAndTo(host.getId(), h.getId());
|
||||
if (t == null) {
|
||||
t = new OvsTunnelVO(host.getId(), h.getId());
|
||||
try {
|
||||
_tunnelDao.persist(t);
|
||||
} catch (EntityExistsException e) {
|
||||
s_logger.debug(String.format("Already has (from=%1$s, to=%2$s)", host.getId(), h.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
t = _tunnelDao.getByFromAndTo(h.getId(), host.getId());
|
||||
if (t == null) {
|
||||
t = new OvsTunnelVO(h.getId(), host.getId());
|
||||
try {
|
||||
_tunnelDao.persist(t);
|
||||
} catch (EntityExistsException e) {
|
||||
s_logger.debug(String.format("Already has (from=%1$s, to=%2$s)", h.getId(), host.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
//try {
|
||||
//List<HostVO> hosts = _resourceMgr.listAllHostsInAllZonesByType(Host.Type.Routing);
|
||||
// NOTE: Trying to semplfy things by removing tunnel pre-allocation
|
||||
//List<NetworkVO> networks = _networkMgr.listAllNetworksInAllZonesByType(GuestType.Isolated);
|
||||
//for (HostVO h : hosts) {
|
||||
// if (h.getId() == host.getId()) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// OvsTunnelVO t = _tunnelDao.getByFromAndTo(host.getId(), h.getId());
|
||||
// if (t == null) {
|
||||
// t = new OvsTunnelVO(host.getId(), h.getId());
|
||||
// try {
|
||||
// _tunnelDao.persist(t);
|
||||
// } catch (EntityExistsException e) {
|
||||
// s_logger.debug(String.format("Already has (from=%1$s, to=%2$s)", host.getId(), h.getId()));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// t = _tunnelDao.getByFromAndTo(h.getId(), host.getId());
|
||||
// if (t == null) {
|
||||
// t = new OvsTunnelVO(h.getId(), host.getId());
|
||||
// try {
|
||||
// _tunnelDao.persist(t);
|
||||
// } catch (EntityExistsException e) {
|
||||
// s_logger.debug(String.format("Already has (from=%1$s, to=%2$s)", h.getId(), host.getId()));
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//} catch (Exception e) {
|
||||
//e.printStackTrace();
|
||||
//}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -12,19 +12,18 @@
|
|||
// Automatically generated by addcopyright.py at 04/03/2012
|
||||
package com.cloud.network.ovs;
|
||||
|
||||
import com.cloud.agent.manager.Commands;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
public interface OvsTunnelManager extends Manager {
|
||||
boolean isOvsTunnelEnabled();
|
||||
|
||||
public void VmCheckAndCreateTunnel(VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest);
|
||||
public void VmCheckAndCreateTunnel(VirtualMachineProfile<? extends VirtualMachine> vm, Network nw, DeployDestination dest);
|
||||
|
||||
public void CheckAndDestroyTunnel(VirtualMachine vm);
|
||||
public void CheckAndDestroyTunnel(VirtualMachine vm, Network nw);
|
||||
|
||||
public void applyDefaultFlow(VirtualMachine instance, DeployDestination dest);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,8 +33,9 @@ import com.cloud.configuration.dao.ConfigurationDao;
|
|||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.network.ovs.dao.OvsTunnelAccountDao;
|
||||
import com.cloud.network.ovs.dao.OvsTunnelAccountVO;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.ovs.dao.OvsTunnelNetworkDao;
|
||||
import com.cloud.network.ovs.dao.OvsTunnelNetworkVO;
|
||||
import com.cloud.network.ovs.dao.OvsTunnelDao;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.Inject;
|
||||
|
|
@ -42,11 +43,14 @@ import com.cloud.utils.concurrency.NamedThreadFactory;
|
|||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
|
||||
@Local(value={OvsTunnelManager.class})
|
||||
|
|
@ -57,14 +61,13 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager {
|
|||
boolean _isEnabled;
|
||||
ScheduledExecutorService _executorPool;
|
||||
ScheduledExecutorService _cleanupExecutor;
|
||||
OvsTunnelListener _listener;
|
||||
|
||||
@Inject ConfigurationDao _configDao;
|
||||
@Inject OvsTunnelDao _tunnelDao;
|
||||
@Inject NicDao _nicDao;
|
||||
@Inject HostDao _hostDao;
|
||||
@Inject UserVmDao _userVmDao;
|
||||
@Inject DomainRouterDao _routerDao;
|
||||
@Inject OvsTunnelAccountDao _tunnelAccountDao;
|
||||
@Inject OvsTunnelNetworkDao _tunnelNetworkDao;
|
||||
@Inject AgentManager _agentMgr;
|
||||
|
||||
@Override
|
||||
|
|
@ -76,37 +79,32 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager {
|
|||
if (_isEnabled) {
|
||||
_executorPool = Executors.newScheduledThreadPool(10, new NamedThreadFactory("OVS"));
|
||||
_cleanupExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("OVS-Cleanup"));
|
||||
_listener = new OvsTunnelListener(_tunnelDao, _hostDao);
|
||||
_agentMgr.registerForHostEvents(_listener, true, true, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected int getGreKey(long from, long to, long account) {
|
||||
OvsTunnelAccountVO ta = null;
|
||||
int key;
|
||||
protected OvsTunnelNetworkVO createTunnelRecord(long from, long to, long networkId) {
|
||||
OvsTunnelNetworkVO ta = null;
|
||||
|
||||
try {
|
||||
key = _tunnelDao.askKey(from, to);
|
||||
ta = new OvsTunnelAccountVO(from, to, key, account);
|
||||
OvsTunnelAccountVO lock = _tunnelAccountDao.acquireInLockTable(Long.valueOf(1));
|
||||
// Use the network id as a Key
|
||||
// FIXME: networkid is long, key must be integer
|
||||
// This is a horrible cast, and it must be removed and replace with something better
|
||||
// before committing into master
|
||||
ta = new OvsTunnelNetworkVO(from, to, (int)networkId, networkId);
|
||||
OvsTunnelNetworkVO lock = _tunnelNetworkDao.acquireInLockTable(Long.valueOf(1));
|
||||
if (lock == null) {
|
||||
s_logger.warn("Cannot lock table ovs_tunnel_account");
|
||||
return -1;
|
||||
return null;
|
||||
}
|
||||
_tunnelAccountDao.persist(ta);
|
||||
_tunnelAccountDao.releaseFromLockTable(lock.getId());
|
||||
_tunnelNetworkDao.persist(ta);
|
||||
_tunnelNetworkDao.releaseFromLockTable(lock.getId());
|
||||
} catch (EntityExistsException e) {
|
||||
ta = _tunnelAccountDao.getByFromToAccount(from, to, account);
|
||||
if (ta == null) {
|
||||
key = -1;
|
||||
} else {
|
||||
key = ta.getKey();
|
||||
}
|
||||
s_logger.debug("A record for the tunnel from " + from + " to " + to + " already exists");
|
||||
}
|
||||
|
||||
return key;
|
||||
return ta;
|
||||
}
|
||||
|
||||
private void handleCreateTunnelAnswer(Answer[] answers){
|
||||
|
|
@ -116,12 +114,12 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager {
|
|||
r.getFromIp(), r.getToIp(), r.getBridge(), r.getKey(), r.getInPortName());
|
||||
Long from = r.getFrom();
|
||||
Long to = r.getTo();
|
||||
long account = r.getAccount();
|
||||
OvsTunnelAccountVO ta = _tunnelAccountDao.getByFromToAccount(from, to, account);
|
||||
long networkId = r.getNetworkId();
|
||||
OvsTunnelNetworkVO ta = _tunnelNetworkDao.getByFromToNetwork(from, to, networkId);
|
||||
if (ta == null) {
|
||||
throw new CloudRuntimeException(String.format("Unable find tunnelAccount record(from=%1$s, to=%2$s, account=%3$s", from, to, account));
|
||||
throw new CloudRuntimeException(String.format("Unable find tunnelAccount record(from=%1$s, to=%2$s, account=%3$s", from, to, networkId));
|
||||
}
|
||||
|
||||
s_logger.debug("Result:" + r.getResult());
|
||||
if (!r.getResult()) {
|
||||
ta.setState("FAILED");
|
||||
s_logger.warn("Create GRE tunnel failed due to " + r.getDetails() + s);
|
||||
|
|
@ -130,24 +128,28 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager {
|
|||
ta.setPortName(r.getInPortName());
|
||||
s_logger.warn("Create GRE tunnel " + r.getDetails() + s);
|
||||
}
|
||||
_tunnelAccountDao.update(ta.getId(), ta);
|
||||
_tunnelNetworkDao.update(ta.getId(), ta);
|
||||
}
|
||||
|
||||
@DB
|
||||
protected void CheckAndCreateTunnel(VirtualMachine instance, DeployDestination dest) {
|
||||
protected void CheckAndCreateTunnel(VirtualMachine instance, Network nw, DeployDestination dest) {
|
||||
if (!_isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_logger.debug("Creating tunnels with OVS tunnel manager");
|
||||
if (instance.getType() != VirtualMachine.Type.User
|
||||
&& instance.getType() != VirtualMachine.Type.DomainRouter) {
|
||||
s_logger.debug("Will not work if you're not an instance or a virtual router");
|
||||
return;
|
||||
}
|
||||
|
||||
long hostId = dest.getHost().getId();
|
||||
long accountId = instance.getAccountId();
|
||||
List<UserVmVO>vms = _userVmDao.listByAccountId(accountId);
|
||||
List<DomainRouterVO> routers = _routerDao.findBy(accountId, instance.getDataCenterIdToDeployIn());
|
||||
// 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);
|
||||
// Find routers for the network
|
||||
List<DomainRouterVO> routers = _routerDao.findByNetwork(nw.getId());
|
||||
List<VMInstanceVO>ins = new ArrayList<VMInstanceVO>();
|
||||
if (vms != null) {
|
||||
ins.addAll(vms);
|
||||
|
|
@ -155,62 +157,61 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager {
|
|||
if (routers.size() != 0) {
|
||||
ins.addAll(routers);
|
||||
}
|
||||
List<Pair<Long, Integer>>toHosts = new ArrayList<Pair<Long, Integer>>();
|
||||
List<Pair<Long, Integer>>fromHosts = new ArrayList<Pair<Long, Integer>>();
|
||||
int key;
|
||||
s_logger.debug("### Virtual Machines:" + vms.size());
|
||||
s_logger.debug("### Virtual Routers:" + routers.size());
|
||||
List<Long> toHostIds = new ArrayList<Long>();
|
||||
List<Long> fromHostIds = new ArrayList<Long>();
|
||||
|
||||
for (VMInstanceVO v : ins) {
|
||||
Long rh = v.getHostId();
|
||||
if (rh == null || rh.longValue() == hostId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
OvsTunnelAccountVO ta = _tunnelAccountDao.getByFromToAccount(hostId, rh.longValue(), accountId);
|
||||
if (ta == null) {
|
||||
key = getGreKey(hostId, rh.longValue(), accountId);
|
||||
if (key == -1) {
|
||||
s_logger.warn(String.format("Cannot get GRE key for from=%1$s to=%2$s accountId=%3$s, tunnel create failed", hostId, rh.longValue(), accountId));
|
||||
continue;
|
||||
}
|
||||
|
||||
Pair<Long, Integer> p = new Pair<Long, Integer>(rh, Integer.valueOf(key));
|
||||
if (!toHosts.contains(p)) {
|
||||
toHosts.add(p);
|
||||
//FIXME: Still using 'TunnelAccount name' - but should actually be tunnelNetwork or something like that
|
||||
OvsTunnelNetworkVO ta = _tunnelNetworkDao.getByFromToNetwork(hostId, rh.longValue(), nw.getId());
|
||||
// Try and create the tunnel even if a previous attempt failed
|
||||
if (ta == null || ta.getState().equals("FAILED")) {
|
||||
s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + rh.longValue());
|
||||
if (ta == null) {
|
||||
this.createTunnelRecord(hostId, rh.longValue(), nw.getId());
|
||||
}
|
||||
if (!toHostIds.contains(rh)) {
|
||||
toHostIds.add(rh);
|
||||
}
|
||||
}
|
||||
|
||||
ta = _tunnelAccountDao.getByFromToAccount(rh.longValue(), hostId, accountId);
|
||||
if (ta == null) {
|
||||
key = getGreKey(rh.longValue(), hostId, accountId);
|
||||
if (key == -1) {
|
||||
s_logger.warn(String.format("Cannot get GRE key for from=%1$s to=%2$s accountId=%3$s, tunnel create failed", rh.longValue(), hostId, accountId));
|
||||
continue;
|
||||
}
|
||||
|
||||
Pair<Long, Integer> p = new Pair<Long, Integer>(rh, Integer.valueOf(key));
|
||||
if (!fromHosts.contains(p)) {
|
||||
fromHosts.add(p);
|
||||
ta = _tunnelNetworkDao.getByFromToNetwork(rh.longValue(), hostId, nw.getId());
|
||||
// Try and create the tunnel even if a previous attempt failed
|
||||
if (ta == null || ta.getState().equals("FAILED")) {
|
||||
s_logger.debug("Attempting to create tunnel from:" + rh.longValue() + " to:" + hostId);
|
||||
if (ta == null) {
|
||||
this.createTunnelRecord(rh.longValue(), hostId, nw.getId());
|
||||
}
|
||||
if (!fromHostIds.contains(rh)) {
|
||||
fromHostIds.add(rh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
String myIp = dest.getHost().getPrivateIpAddress();
|
||||
for (Pair<Long, Integer> i : toHosts) {
|
||||
HostVO rHost = _hostDao.findById(i.first());
|
||||
for (Long i : toHostIds) {
|
||||
HostVO rHost = _hostDao.findById(i);
|
||||
Commands cmds = new Commands(
|
||||
new OvsCreateTunnelCommand(rHost.getPrivateIpAddress(), i.second().toString(), Long.valueOf(hostId), i.first(), accountId, myIp));
|
||||
s_logger.debug("Ask host " + hostId + " to create gre tunnel to " + i.first());
|
||||
new OvsCreateTunnelCommand(rHost.getPrivateIpAddress(), String.valueOf(nw.getId()),
|
||||
Long.valueOf(hostId), i, nw.getId(), myIp));
|
||||
s_logger.debug("Ask host " + hostId + " to create gre tunnel to " + i);
|
||||
Answer[] answers = _agentMgr.send(hostId, cmds);
|
||||
handleCreateTunnelAnswer(answers);
|
||||
}
|
||||
|
||||
for (Pair<Long, Integer> i : fromHosts) {
|
||||
HostVO rHost = _hostDao.findById(i.first());
|
||||
for (Long i : fromHostIds) {
|
||||
HostVO rHost = _hostDao.findById(i);
|
||||
Commands cmd2s = new Commands(
|
||||
new OvsCreateTunnelCommand(myIp, i.second().toString(), i.first(), Long.valueOf(hostId), accountId, rHost.getPrivateIpAddress()));
|
||||
s_logger.debug("Ask host " + i.first() + " to create gre tunnel to " + hostId);
|
||||
Answer[] answers = _agentMgr.send(i.first(), cmd2s);
|
||||
new OvsCreateTunnelCommand(myIp, String.valueOf(nw.getId()),
|
||||
i, Long.valueOf(hostId), nw.getId(), rHost.getPrivateIpAddress()));
|
||||
s_logger.debug("Ask host " + i + " to create gre tunnel to " + hostId);
|
||||
Answer[] answers = _agentMgr.send(i, cmd2s);
|
||||
handleCreateTunnelAnswer(answers);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
@ -239,67 +240,91 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void VmCheckAndCreateTunnel(VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest) {
|
||||
CheckAndCreateTunnel(vm.getVirtualMachine(), dest);
|
||||
public void VmCheckAndCreateTunnel(VirtualMachineProfile<? extends VirtualMachine> vm, Network nw, DeployDestination dest) {
|
||||
CheckAndCreateTunnel(vm.getVirtualMachine(), nw, dest);
|
||||
}
|
||||
|
||||
private void handleDestroyTunnelAnswer(Answer ans, long from, long to, long account) {
|
||||
String toStr = (to == 0 ? "all peers" : Long.toString(to));
|
||||
private void handleDestroyTunnelAnswer(Answer ans, long from, long to, long network_id) {
|
||||
|
||||
if (ans.getResult()) {
|
||||
OvsTunnelAccountVO lock = _tunnelAccountDao.acquireInLockTable(Long.valueOf(1));
|
||||
OvsTunnelNetworkVO lock = _tunnelNetworkDao.acquireInLockTable(Long.valueOf(1));
|
||||
if (lock == null) {
|
||||
s_logger.warn(String.format("failed to lock ovs_tunnel_account, remove record of tunnel(from=%1$s, to=%2$s account=%3$s) failed", from, to, account));
|
||||
s_logger.warn(String.format("failed to lock ovs_tunnel_account, remove record of " +
|
||||
"tunnel(from=%1$s, to=%2$s account=%3$s) failed",
|
||||
from, to, network_id));
|
||||
return;
|
||||
}
|
||||
|
||||
if (to == 0) {
|
||||
_tunnelAccountDao.removeByFromAccount(from, account);
|
||||
} else {
|
||||
_tunnelAccountDao.removeByFromToAccount(from, to, account);
|
||||
}
|
||||
_tunnelAccountDao.releaseFromLockTable(lock.getId());
|
||||
_tunnelNetworkDao.removeByFromToNetwork(from, to, network_id);
|
||||
_tunnelNetworkDao.releaseFromLockTable(lock.getId());
|
||||
|
||||
s_logger.debug(String.format("Destroy tunnel(account:%1$s, from:%2$s, to:%3$s) successful", account, from, toStr));
|
||||
s_logger.debug(String.format("Destroy tunnel(account:%1$s, from:%2$s, to:%3$s) successful",
|
||||
network_id, from, to));
|
||||
} else {
|
||||
s_logger.debug(String.format("Destroy tunnel(account:%1$s, from:%2$s, to:%3$s) failed", account, from, toStr));
|
||||
s_logger.debug(String.format("Destroy tunnel(account:%1$s, from:%2$s, to:%3$s) failed",
|
||||
network_id, from, to));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void handleDestroyBridgeAnswer(Answer ans, long host_id, long network_id) {
|
||||
|
||||
if (ans.getResult()) {
|
||||
OvsTunnelNetworkVO lock = _tunnelNetworkDao.acquireInLockTable(Long.valueOf(1));
|
||||
if (lock == null) {
|
||||
s_logger.warn("failed to lock ovs_tunnel_network, remove record");
|
||||
return;
|
||||
}
|
||||
|
||||
_tunnelNetworkDao.removeByFromNetwork(host_id, network_id);
|
||||
_tunnelNetworkDao.releaseFromLockTable(lock.getId());
|
||||
|
||||
s_logger.debug(String.format("Destroy bridge for network %1$s successful", network_id));
|
||||
} else {
|
||||
s_logger.debug(String.format("Destroy bridge for network %1$s failed", network_id));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void CheckAndDestroyTunnel(VirtualMachine vm) {
|
||||
if (!_isEnabled) {
|
||||
public void CheckAndDestroyTunnel(VirtualMachine vm, Network nw) {
|
||||
s_logger.debug("### DESTROYING YOUR TUNNELS!");
|
||||
if (!_isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<UserVmVO> userVms = _userVmDao.listByAccountIdAndHostId(vm.getAccountId(), vm.getHostId());
|
||||
s_logger.debug("### User Vms:" + userVms.size());
|
||||
if (vm.getType() == VirtualMachine.Type.User) {
|
||||
if (userVms.size() > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<DomainRouterVO> routers = _routerDao.findBy(vm.getAccountId(), vm.getDataCenterIdToDeployIn());
|
||||
List<DomainRouterVO> routers = _routerDao.findByNetwork(nw.getId());
|
||||
for (DomainRouterVO router : routers) {
|
||||
if (router.getHostId() == vm.getHostId()) {
|
||||
return;
|
||||
s_logger.debug("### Not destroying because on same host as router");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (vm.getType() == VirtualMachine.Type.DomainRouter && userVms.size() != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_logger.debug("### I WILL DESTROYYY");
|
||||
try {
|
||||
/* Now we are last one on host, destroy all tunnels of my account */
|
||||
Command cmd = new OvsDestroyTunnelCommand(vm.getAccountId(), "[]");
|
||||
/* Now we are last one on host, destroy the bridge with all
|
||||
* the tunnels for this network */
|
||||
Command cmd = new OvsDestroyBridgeCommand(nw.getId());
|
||||
s_logger.debug("### Destroying bridge for network " + nw.getId() + " on host:" + vm.getHostId());
|
||||
Answer ans = _agentMgr.send(vm.getHostId(), cmd);
|
||||
handleDestroyTunnelAnswer(ans, vm.getHostId(), 0, vm.getAccountId());
|
||||
handleDestroyBridgeAnswer(ans, vm.getHostId(), nw.getId());
|
||||
|
||||
/* Then ask hosts have peer tunnel with me to destroy them */
|
||||
List<OvsTunnelAccountVO> peers = _tunnelAccountDao.listByToAccount(vm.getHostId(), vm.getAccountId());
|
||||
for (OvsTunnelAccountVO p : peers) {
|
||||
cmd = new OvsDestroyTunnelCommand(p.getAccount(), p.getPortName());
|
||||
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.getAccount());
|
||||
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);
|
||||
|
|
@ -307,4 +332,21 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyDefaultFlow(VirtualMachine instance,
|
||||
DeployDestination dest) {
|
||||
if (!_isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
VirtualMachine.Type vmType = instance.getType();
|
||||
if (vmType != VirtualMachine.Type.User
|
||||
&& vmType != VirtualMachine.Type.DomainRouter) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_logger.debug("### Applying rules for allowing broadcast traffic");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import com.cloud.network.NetworkServiceMapVO;
|
|||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.Network.Provider;
|
||||
import com.cloud.offerings.NetworkOfferingServiceMapVO;
|
||||
import com.cloud.offerings.NetworkOfferingVO;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
|
|
@ -31,7 +32,8 @@ import com.cloud.utils.db.SearchCriteria.Func;
|
|||
|
||||
@Local(value=NetworkOfferingServiceMapDao.class) @DB(txn=false)
|
||||
public class NetworkOfferingServiceMapDaoImpl extends GenericDaoBase<NetworkOfferingServiceMapVO, Long> implements NetworkOfferingServiceMapDao {
|
||||
final SearchBuilder<NetworkOfferingServiceMapVO> AllFieldsSearch;
|
||||
|
||||
final SearchBuilder<NetworkOfferingServiceMapVO> AllFieldsSearch;
|
||||
final SearchBuilder<NetworkOfferingServiceMapVO> MultipleServicesSearch;
|
||||
final GenericSearchBuilder<NetworkOfferingServiceMapVO, String> ProvidersSearch;
|
||||
final GenericSearchBuilder<NetworkOfferingServiceMapVO, String> ServicesSearch;
|
||||
|
|
@ -133,7 +135,18 @@ public class NetworkOfferingServiceMapDaoImpl extends GenericDaoBase<NetworkOffe
|
|||
public List<String> listServicesForNetworkOffering(long networkOfferingId) {
|
||||
SearchCriteria<String> sc = ServicesSearch.create();;
|
||||
sc.setParameters("networkOfferingId", networkOfferingId);
|
||||
|
||||
return customSearch(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkOfferingServiceMapVO persist(
|
||||
NetworkOfferingServiceMapVO entity) {
|
||||
SearchCriteria<NetworkOfferingServiceMapVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("networkOfferingId", entity.getNetworkOfferingId());
|
||||
sc.setParameters("service", entity.getService());
|
||||
sc.setParameters("provider", entity.getProvider());
|
||||
NetworkOfferingServiceMapVO mappingInDb = findOneBy(sc);
|
||||
return mappingInDb!=null? mappingInDb : super.persist(entity);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ import com.cloud.utils.PropertiesUtil;
|
|||
import com.cloud.utils.component.ComponentLocator;
|
||||
import com.cloud.utils.crypt.DBEncryptionUtil;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
|
|
@ -892,6 +893,9 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
|||
defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.PortForwarding, Provider.VirtualRouter);
|
||||
defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Vpn, Provider.VirtualRouter);
|
||||
|
||||
Map<Network.Service, Network.Provider> ovsIsolatedSourceNatEnabledNetworkOfferingProviders =
|
||||
new HashMap<Network.Service, Network.Provider>(defaultIsolatedSourceNatEnabledNetworkOfferingProviders);
|
||||
ovsIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Connectivity, Provider.OvsConnectivityProvider);
|
||||
Map<Network.Service, Network.Provider> netscalerServiceProviders = new HashMap<Network.Service, Network.Provider>();
|
||||
netscalerServiceProviders.put(Service.Dhcp, Provider.VirtualRouter);
|
||||
netscalerServiceProviders.put(Service.Dns, Provider.VirtualRouter);
|
||||
|
|
@ -906,18 +910,18 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
|||
txn.start();
|
||||
|
||||
// Offering #1
|
||||
NetworkOfferingVO deafultSharedSGNetworkOffering = new NetworkOfferingVO(
|
||||
NetworkOfferingVO defaultSharedSGNetworkOffering = new NetworkOfferingVO(
|
||||
NetworkOffering.DefaultSharedNetworkOfferingWithSGService,
|
||||
"Offering for Shared Security group enabled networks",
|
||||
TrafficType.Guest,
|
||||
false, true, null, null, true, Availability.Optional,
|
||||
null, Network.GuestType.Shared, true, true);
|
||||
|
||||
deafultSharedSGNetworkOffering.setState(NetworkOffering.State.Enabled);
|
||||
deafultSharedSGNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(deafultSharedSGNetworkOffering);
|
||||
|
||||
defaultSharedSGNetworkOffering.setState(NetworkOffering.State.Enabled);
|
||||
defaultSharedSGNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultSharedSGNetworkOffering);
|
||||
|
||||
for (Service service : defaultSharedSGNetworkOfferingProviders.keySet()) {
|
||||
NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(deafultSharedSGNetworkOffering.getId(), service, defaultSharedSGNetworkOfferingProviders.get(service));
|
||||
NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(defaultSharedSGNetworkOffering.getId(), service, defaultSharedSGNetworkOfferingProviders.get(service));
|
||||
_ntwkOfferingServiceMapDao.persist(offService);
|
||||
s_logger.trace("Added service for the network offering: " + offService);
|
||||
}
|
||||
|
|
@ -989,7 +993,25 @@ public class ConfigurationServerImpl implements ConfigurationServer {
|
|||
_ntwkOfferingServiceMapDao.persist(offService);
|
||||
s_logger.trace("Added service for the network offering: " + offService);
|
||||
}
|
||||
|
||||
// Offering #6 - OVS
|
||||
s_logger.debug("Adding network offering for OVS networks");
|
||||
NetworkOfferingVO ovsIsolatedSourceNatEnabledNetworkOffering = new NetworkOfferingVO(
|
||||
NetworkOffering.OvsIsolatedNetworkOfferingWithSourceNatService,
|
||||
"Offering for OVS-based Isolated networks with Source Nat service enabled",
|
||||
TrafficType.Guest,
|
||||
false, false, null, null, true, Availability.Optional,
|
||||
null, Network.GuestType.Isolated, true, false);
|
||||
|
||||
ovsIsolatedSourceNatEnabledNetworkOffering.setState(NetworkOffering.State.Enabled);
|
||||
ovsIsolatedSourceNatEnabledNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(ovsIsolatedSourceNatEnabledNetworkOffering);
|
||||
|
||||
for (Service service : ovsIsolatedSourceNatEnabledNetworkOfferingProviders.keySet()) {
|
||||
NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(ovsIsolatedSourceNatEnabledNetworkOffering.getId(), service, ovsIsolatedSourceNatEnabledNetworkOfferingProviders.get(service));
|
||||
_ntwkOfferingServiceMapDao.persist(offService);
|
||||
s_logger.debug("Added service for the OVS network offering: " + offService);
|
||||
}
|
||||
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3137,7 +3137,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
|||
if (storageId != null) {
|
||||
sc.setJoinParameters("volumeSearch", "poolId", storageId);
|
||||
}
|
||||
|
||||
s_logger.debug("THE WHERE CLAUSE IS:" + sc.getWhereClause());
|
||||
return _vmDao.search(sc, searchFilter);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -385,7 +385,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
|
|||
}
|
||||
|
||||
VirtualMachineProfile<T> profile = new VirtualMachineProfileImpl<T>(vm);
|
||||
|
||||
s_logger.debug("Cleaning up NICS");
|
||||
_networkMgr.cleanupNics(profile);
|
||||
// Clean up volumes based on the vm's instance id
|
||||
_storageMgr.cleanupVolumes(vm.getId());
|
||||
|
|
@ -949,7 +949,13 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
|
|||
}
|
||||
}
|
||||
|
||||
_networkMgr.release(profile, force);
|
||||
try {
|
||||
_networkMgr.release(profile, force);
|
||||
s_logger.debug("Successfully released network resources for the vm " + vm);
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Unable to release some network resources.", e);
|
||||
}
|
||||
|
||||
_storageMgr.release(profile);
|
||||
s_logger.debug("Successfully cleanued up resources for the vm " + vm + " in " + state + " state");
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
|
|||
return listBy(sc);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<DomainRouterVO> listBy(long accountId) {
|
||||
SearchCriteria<DomainRouterVO> sc = AllFieldsSearch.create();
|
||||
|
|
|
|||
|
|
@ -1751,18 +1751,18 @@ CREATE TABLE `cloud`.`ovs_tunnel`(
|
|||
PRIMARY KEY(`from`, `to`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `cloud`.`ovs_tunnel_account`(
|
||||
CREATE TABLE `cloud`.`ovs_tunnel_network`(
|
||||
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT,
|
||||
`from` bigint unsigned COMMENT 'from host id',
|
||||
`to` bigint unsigned COMMENT 'to host id',
|
||||
`account` bigint unsigned COMMENT 'account',
|
||||
`network_id` bigint unsigned COMMENT 'network identifier',
|
||||
`key` int unsigned COMMENT 'gre key',
|
||||
`port_name` varchar(32) COMMENT 'in port on open vswitch',
|
||||
`state` varchar(16) default 'FAILED' COMMENT 'result of tunnel creatation',
|
||||
PRIMARY KEY(`from`, `to`, `account`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
INSERT INTO `cloud`.`ovs_tunnel_account` (`from`, `to`, `account`, `key`, `port_name`, `state`) VALUES (0, 0, 0, 0, 'lock', 'SUCCESS');
|
||||
INSERT INTO `cloud`.`ovs_tunnel_network` (`from`, `to`, `network_id`, `key`, `port_name`, `state`) VALUES (0, 0, 0, 0, 'lock', 'SUCCESS');
|
||||
|
||||
CREATE TABLE `cloud`.`ovs_vlan_mapping_dirty`(
|
||||
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT,
|
||||
|
|
|
|||
Loading…
Reference in New Issue