Skip to content

Commit 9d2916f

Browse files
committed
it works
1 parent c94b6ac commit 9d2916f

23 files changed

Lines changed: 813 additions & 128 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
build/replace.properties
12
build/build.number
23
bin/
34
cloudstack-proprietary/

agent/src/com/cloud/agent/Agent.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,7 @@
7777
*
7878
**/
7979
public class Agent implements HandlerFactory, IAgentControl {
80-
private static final Logger s_logger = Logger.getLogger(Agent.class.getName());
81-
80+
private static final Logger s_logger = Logger.getLogger(Agent.class.getName());
8281
public enum ExitStatus {
8382
Normal(0), // Normal status = 0.
8483
Upgrade(65), // Exiting for upgrade.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.cloud.network.ovs;
2+
3+
import com.cloud.agent.api.Answer;
4+
import com.cloud.agent.api.Command;
5+
6+
public class OvsCreateGreTunnelAnswer extends Answer {
7+
String hostIp;
8+
String remoteIp;
9+
String bridge;
10+
String key;
11+
12+
public OvsCreateGreTunnelAnswer(Command cmd, boolean success, String details) {
13+
super(cmd, success, details);
14+
}
15+
16+
public OvsCreateGreTunnelAnswer(Command cmd, boolean success,
17+
String details, String hostIp, String remoteIp, String bridge,
18+
String key) {
19+
super(cmd, success, details);
20+
this.hostIp = hostIp;
21+
this.remoteIp = remoteIp;
22+
this.bridge = bridge;
23+
this.key = key;
24+
}
25+
26+
public String getHostIp() {
27+
return hostIp;
28+
}
29+
30+
public String getRemoteIp() {
31+
return remoteIp;
32+
}
33+
34+
public String getBridge() {
35+
return bridge;
36+
}
37+
38+
public String getKey() {
39+
return key;
40+
}
41+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.cloud.network.ovs;
2+
3+
import com.cloud.agent.api.Command;
4+
5+
public class OvsDeleteFlowCommand extends Command {
6+
String vmName;
7+
8+
@Override
9+
public boolean executeInSequence() {
10+
return true;
11+
}
12+
13+
public String getVmName() {
14+
return vmName;
15+
}
16+
17+
public OvsDeleteFlowCommand(String vmName) {
18+
this.vmName = vmName;
19+
}
20+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.cloud.network.ovs;
2+
3+
import com.cloud.agent.api.Answer;
4+
import com.cloud.agent.api.Command;
5+
6+
public class OvsSetTagAndFlowAnswer extends Answer {
7+
Long vmId;
8+
Long seqno;
9+
10+
public OvsSetTagAndFlowAnswer(Command cmd, boolean success, String details) {
11+
super(cmd, success, details);
12+
OvsSetTagAndFlowCommand c = (OvsSetTagAndFlowCommand)cmd;
13+
this.vmId = c.getVmId();
14+
this.seqno = Long.parseLong(c.getSeqNo());
15+
}
16+
17+
public Long getVmId() {
18+
return vmId;
19+
}
20+
21+
public Long getSeqNo() {
22+
return seqno;
23+
}
24+
}

api/src/com/cloud/network/ovs/OvsSetTagAndFlowCommand.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,18 @@
55
public class OvsSetTagAndFlowCommand extends Command {
66
String vlans;
77
String vmName;
8+
String seqno;
9+
Long vmId;
810

911
@Override
1012
public boolean executeInSequence() {
1113
return true;
1214
}
1315

16+
public String getSeqNo() {
17+
return seqno;
18+
}
19+
1420
public String getVlans() {
1521
return vlans;
1622
}
@@ -19,8 +25,14 @@ public String getVmName() {
1925
return vmName;
2026
}
2127

22-
public OvsSetTagAndFlowCommand(String vmName, String vlans) {
28+
public Long getVmId() {
29+
return vmId;
30+
}
31+
32+
public OvsSetTagAndFlowCommand(String vmName, String vlans, String seqno, Long vmId) {
2333
this.vmName = vmName;
2434
this.vlans = vlans;
35+
this.seqno = seqno;
36+
this.vmId = vmId;
2537
}
2638
}

build/replace.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ DBHOST=localhost
66
AGENTLOGDIR=logs
77
AGENTLOG=logs/agent.log
88
MSMNTDIR=/mnt
9+
DBROOTPW=
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.cloud.agent.api;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
import com.cloud.host.Host;
7+
import com.cloud.utils.Pair;
8+
import com.cloud.vm.State;
9+
10+
public class PingRoutingWithOvsCommand extends PingRoutingCommand {
11+
List<Pair<String, Long>> states;
12+
13+
protected PingRoutingWithOvsCommand() {
14+
super();
15+
}
16+
17+
public PingRoutingWithOvsCommand(Host.Type type, long id,
18+
Map<String, State> states, List<Pair<String, Long>> ovsStates) {
19+
super(type, id, states);
20+
this.states = ovsStates;
21+
}
22+
23+
public List<Pair<String, Long>> getStates() {
24+
return states;
25+
}
26+
}

core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java

Lines changed: 86 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
import com.cloud.agent.api.PingCommand;
9595
import com.cloud.agent.api.PingRoutingCommand;
9696
import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
97+
import com.cloud.agent.api.PingRoutingWithOvsCommand;
9798
import com.cloud.agent.api.PingTestCommand;
9899
import com.cloud.agent.api.PoolEjectCommand;
99100
import com.cloud.agent.api.PrepareForMigrationAnswer;
@@ -159,7 +160,10 @@
159160
import com.cloud.network.Networks.BroadcastDomainType;
160161
import com.cloud.network.Networks.IsolationType;
161162
import com.cloud.network.Networks.TrafficType;
163+
import com.cloud.network.ovs.OvsCreateGreTunnelAnswer;
162164
import com.cloud.network.ovs.OvsCreateGreTunnelCommand;
165+
import com.cloud.network.ovs.OvsDeleteFlowCommand;
166+
import com.cloud.network.ovs.OvsSetTagAndFlowAnswer;
163167
import com.cloud.network.ovs.OvsSetTagAndFlowCommand;
164168
import com.cloud.resource.ServerResource;
165169
import com.cloud.storage.Storage;
@@ -247,6 +251,7 @@ public abstract class CitrixResourceBase implements ServerResource {
247251

248252
protected StorageLayer _storage;
249253
protected boolean _canBridgeFirewall = false;
254+
protected boolean _isOvs = false;
250255
protected HashMap<StoragePoolType, StoragePoolResource> _pools = new HashMap<StoragePoolType, StoragePoolResource>(5);
251256

252257
public enum SRType {
@@ -449,6 +454,8 @@ public Answer executeRequest(Command cmd) {
449454
return execute((OvsCreateGreTunnelCommand)cmd);
450455
} else if (cmd instanceof OvsSetTagAndFlowCommand) {
451456
return execute((OvsSetTagAndFlowCommand)cmd);
457+
} else if (cmd instanceof OvsDeleteFlowCommand) {
458+
return execute((OvsDeleteFlowCommand)cmd);
452459
} else {
453460
return Answer.createUnsupportedCommandAnswer(cmd);
454461
}
@@ -3312,9 +3319,12 @@ public PingCommand getCurrentStatus(long id) {
33123319
if (newStates == null) {
33133320
newStates = new HashMap<String, State>();
33143321
}
3315-
if (!_canBridgeFirewall) {
3322+
if (!_canBridgeFirewall && !_isOvs) {
33163323
return new PingRoutingCommand(getType(), id, newStates);
3317-
} else {
3324+
} else if (_isOvs) {
3325+
List<Pair<String, Long>>ovsStates = ovsFullSyncStates();
3326+
return new PingRoutingWithOvsCommand(getType(), id, newStates, ovsStates);
3327+
}else {
33183328
HashMap<String, Pair<Long, Long>> nwGrpStates = syncNetworkGroups(conn, id);
33193329
return new PingRoutingWithNwGroupsCommand(getType(), id, newStates, nwGrpStates);
33203330
}
@@ -3820,7 +3830,61 @@ protected boolean can_bridge_firewall(Connection conn) {
38203830
return Boolean.valueOf(callHostPlugin(conn, "vmops", "can_bridge_firewall", "host_uuid", _host.uuid));
38213831
}
38223832

3823-
private Answer execute(OvsSetTagAndFlowCommand cmd) {
3833+
private Answer execute(OvsDeleteFlowCommand cmd) {
3834+
_isOvs = true;
3835+
3836+
Connection conn = getConnection();
3837+
try {
3838+
String nwName = Networks.BroadcastScheme.VSwitch.toString();
3839+
Network nw = getNetworkByName(conn, nwName);
3840+
assert nw!= null : "Why there is no vswith network ???";
3841+
String bridge = nw.getBridge(conn);
3842+
String result = callHostPlugin(conn, "vmops", "ovs_delete_flow", "bridge", bridge,
3843+
"vmName", cmd.getVmName());
3844+
3845+
if (result.equalsIgnoreCase("SUCCESS")) {
3846+
return new Answer(cmd, true, "success to delete flows for " + cmd.getVmName());
3847+
} else {
3848+
return new Answer(cmd, false, result);
3849+
}
3850+
} catch (Exception e) {
3851+
e.printStackTrace();
3852+
}
3853+
return new Answer(cmd, false, "failed to delete flow for " + cmd.getVmName());
3854+
}
3855+
3856+
private List<Pair<String, Long>> ovsFullSyncStates() {
3857+
Connection conn = getConnection();
3858+
try {
3859+
String result = callHostPlugin(conn, "vmops", "ovs_get_vm_log", "host_uuid", _host.uuid);
3860+
String [] logs = result != null ?result.split(";"): new String [0];
3861+
List<Pair<String, Long>> states = new ArrayList<Pair<String, Long>>();
3862+
for (String log: logs){
3863+
String [] info = log.split(",");
3864+
if (info.length != 4) {
3865+
s_logger.warn("Wrong element number in ovs log");
3866+
continue;
3867+
}
3868+
3869+
//','.join([bridge, vmName, vmId, seqno])
3870+
try {
3871+
states.add(new Pair<String,Long>(info[0], Long.parseLong(info[3])));
3872+
} catch (NumberFormatException nfe) {
3873+
states.add(new Pair<String,Long>(info[0], -1L));
3874+
}
3875+
}
3876+
3877+
return states;
3878+
} catch (Exception e) {
3879+
e.printStackTrace();
3880+
}
3881+
3882+
return null;
3883+
}
3884+
3885+
private OvsSetTagAndFlowAnswer execute(OvsSetTagAndFlowCommand cmd) {
3886+
_isOvs = true;
3887+
38243888
Connection conn = getConnection();
38253889
try {
38263890
String nwName = Networks.BroadcastScheme.VSwitch.toString();
@@ -3833,48 +3897,47 @@ private Answer execute(OvsSetTagAndFlowCommand cmd) {
38333897
* plugin side
38343898
*/
38353899
String result = callHostPlugin(conn, "vmops", "ovs_set_tag_and_flow", "bridge", bridge,
3836-
"vmName", cmd.getVmName(), "vlans", cmd.getVlans());
3900+
"vmName", cmd.getVmName(), "vlans", cmd.getVlans(), "seqno", cmd.getSeqNo());
38373901
s_logger.debug("set flow for " + cmd.getVmName() + " " + result);
38383902

38393903
if (result.equalsIgnoreCase("SUCCESS")) {
3840-
return new Answer(cmd, true, "Set flow for " + cmd.getVmName()
3841-
+ " success, vlans:" + cmd.getVlans());
3904+
return new OvsSetTagAndFlowAnswer(cmd, true, result);
38423905
} else {
3843-
return new Answer(cmd, false, "Set flow for " + cmd.getVmName()
3844-
+ " failed, vlans:" + cmd.getVlans());
3906+
return new OvsSetTagAndFlowAnswer(cmd, false, result);
38453907
}
38463908
} catch (Exception e) {
38473909
e.printStackTrace();
38483910
}
38493911

3850-
return new Answer(cmd, false, "Set flow for " + cmd.getVmName()
3851-
+ " failed, vlans:" + cmd.getVlans());
3912+
return new OvsSetTagAndFlowAnswer(cmd, false, "EXCEPTION");
38523913
}
38533914

3854-
private Answer execute(OvsCreateGreTunnelCommand cmd) {
3915+
3916+
private OvsCreateGreTunnelAnswer execute(OvsCreateGreTunnelCommand cmd) {
3917+
_isOvs = true;
3918+
38553919
Connection conn = getConnection();
3920+
String bridge = "unkonwn";
38563921
try {
3857-
String nwName = Networks.BroadcastScheme.VSwitch.toString();
3858-
Network nw = getNetworkByName(conn, nwName);
3859-
if (nw == null) {
3860-
nw = setupvSwitchNetwork(conn);
3861-
}
3922+
//TODO: we may store vswtich network to _host
3923+
Network nw = setupvSwitchNetwork(conn);
3924+
bridge = nw.getBridge(conn);
38623925

38633926
String result = callHostPlugin(conn, "vmops", "vlanRemapUtils",
3864-
"op", "createGRE", "bridge", nw.getBridge(conn),
3927+
"op", "createGRE", "bridge", bridge,
38653928
"remoteIP", cmd.getRemoteIp(), "greKey", cmd.getKey());
3866-
if (result.equalsIgnoreCase("SUCCESS")) {
3867-
return new Answer(cmd, true, "create gre tunnel to "
3868-
+ cmd.getRemoteIp() + " success");
3929+
if (result.equalsIgnoreCase("SUCCESS") || result.equalsIgnoreCase("TUNNEL_EXISTED")) {
3930+
return new OvsCreateGreTunnelAnswer(cmd, true, result);
38693931
} else {
3870-
return new Answer(cmd, false, "create gre tunnel to "
3871-
+ cmd.getRemoteIp() + " failed");
3932+
return new OvsCreateGreTunnelAnswer(cmd, false, result,
3933+
_host.ip, cmd.getRemoteIp(), bridge, cmd.getKey());
38723934
}
38733935
} catch (Exception e) {
38743936
e.printStackTrace();
38753937
}
38763938

3877-
return new Answer(cmd, false, "create gre tunnel to " + cmd.getRemoteIp() + " failed");
3939+
return new OvsCreateGreTunnelAnswer(cmd, false, "EXCEPTION", _host.ip,
3940+
cmd.getRemoteIp(), bridge, cmd.getKey());
38783941
}
38793942

38803943
private Answer execute(SecurityIngressRulesCmd cmd) {

0 commit comments

Comments
 (0)