alshabib

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

1 package org.onlab.onos.mastership; 1 package org.onlab.onos.mastership;
2 2
3 -import org.onlab.onos.cluster.NodeId;
4 import org.onlab.onos.cluster.RoleInfo; 3 import org.onlab.onos.cluster.RoleInfo;
5 import org.onlab.onos.event.AbstractEvent; 4 import org.onlab.onos.event.AbstractEvent;
6 import org.onlab.onos.net.DeviceId; 5 import org.onlab.onos.net.DeviceId;
...@@ -56,19 +55,6 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI ...@@ -56,19 +55,6 @@ public class MastershipEvent extends AbstractEvent<MastershipEvent.Type, DeviceI
56 } 55 }
57 56
58 /** 57 /**
59 - * Returns the NodeID of the node associated with the event.
60 - * For MASTER_CHANGED this is the newly elected master, and for
61 - * BACKUPS_CHANGED, this is the node that was newly added, removed, or
62 - * whose position was changed in the list.
63 - *
64 - * @return node ID as a subject
65 - */
66 - //XXX to-be removed - or keep for convenience?
67 - public NodeId node() {
68 - return roleInfo.master();
69 - }
70 -
71 - /**
72 * Returns the current role state for the subject. 58 * Returns the current role state for the subject.
73 * 59 *
74 * @return RoleInfo associated with Device ID subject 60 * @return RoleInfo associated with Device ID subject
......
1 package org.onlab.onos.store.cluster.messaging; 1 package org.onlab.onos.store.cluster.messaging;
2 2
3 +import java.util.concurrent.Future;
3 import java.util.concurrent.TimeUnit; 4 import java.util.concurrent.TimeUnit;
4 import java.util.concurrent.TimeoutException; 5 import java.util.concurrent.TimeoutException;
5 6
6 import org.onlab.onos.cluster.NodeId; 7 import org.onlab.onos.cluster.NodeId;
7 8
8 -public interface ClusterMessageResponse { 9 +public interface ClusterMessageResponse extends Future<byte[]> {
10 +
9 public NodeId sender(); 11 public NodeId sender();
10 - public byte[] get(long timeout, TimeUnit timeunit) throws TimeoutException; 12 +
11 - public byte[] get(long timeout) throws InterruptedException; 13 + // TODO InterruptedException, ExecutionException removed from original
14 + // Future declaration. Revisit if we ever need those.
15 + @Override
16 + public byte[] get(long timeout, TimeUnit unit) throws TimeoutException;
17 +
12 } 18 }
......
...@@ -227,10 +227,14 @@ implements MastershipService, MastershipAdminService { ...@@ -227,10 +227,14 @@ implements MastershipService, MastershipAdminService {
227 if (clusterService.getNodes().size() > (clusterSize.intValue() / 2)) { 227 if (clusterService.getNodes().size() > (clusterSize.intValue() / 2)) {
228 return true; 228 return true;
229 } 229 }
230 - //else { 230 +// else {
231 //FIXME: break tie for equal-sized clusters, by number of 231 //FIXME: break tie for equal-sized clusters, by number of
232 // connected switches, then masters, then nodeId hash 232 // connected switches, then masters, then nodeId hash
233 - // } 233 + // problem is, how do we get at channel info cleanly here?
234 + // Also, what's the time hit for a distributed store look-up
235 + // versus channel re-negotiation? bet on the latter being worse.
236 +
237 +// }
234 return false; 238 return false;
235 } 239 }
236 240
......
...@@ -4,9 +4,9 @@ import static com.google.common.base.Preconditions.checkArgument; ...@@ -4,9 +4,9 @@ import static com.google.common.base.Preconditions.checkArgument;
4 4
5 import java.io.IOException; 5 import java.io.IOException;
6 import java.util.Set; 6 import java.util.Set;
7 +import java.util.concurrent.ExecutionException;
7 import java.util.concurrent.TimeUnit; 8 import java.util.concurrent.TimeUnit;
8 import java.util.concurrent.TimeoutException; 9 import java.util.concurrent.TimeoutException;
9 -
10 import org.apache.felix.scr.annotations.Activate; 10 import org.apache.felix.scr.annotations.Activate;
11 import org.apache.felix.scr.annotations.Component; 11 import org.apache.felix.scr.annotations.Component;
12 import org.apache.felix.scr.annotations.Deactivate; 12 import org.apache.felix.scr.annotations.Deactivate;
...@@ -181,10 +181,13 @@ public class ClusterCommunicationManager ...@@ -181,10 +181,13 @@ public class ClusterCommunicationManager
181 } 181 }
182 } 182 }
183 183
184 - private static final class InternalClusterMessageResponse implements ClusterMessageResponse { 184 + private static final class InternalClusterMessageResponse
185 + implements ClusterMessageResponse {
185 186
186 private final NodeId sender; 187 private final NodeId sender;
187 private final Response responseFuture; 188 private final Response responseFuture;
189 + private volatile boolean isCancelled = false;
190 + private volatile boolean isDone = false;
188 191
189 public InternalClusterMessageResponse(NodeId sender, Response responseFuture) { 192 public InternalClusterMessageResponse(NodeId sender, Response responseFuture) {
190 this.sender = sender; 193 this.sender = sender;
...@@ -198,12 +201,39 @@ public class ClusterCommunicationManager ...@@ -198,12 +201,39 @@ public class ClusterCommunicationManager
198 @Override 201 @Override
199 public byte[] get(long timeout, TimeUnit timeunit) 202 public byte[] get(long timeout, TimeUnit timeunit)
200 throws TimeoutException { 203 throws TimeoutException {
201 - return responseFuture.get(timeout, timeunit); 204 + final byte[] result = responseFuture.get(timeout, timeunit);
205 + isDone = true;
206 + return result;
207 + }
208 +
209 + @Override
210 + public boolean cancel(boolean mayInterruptIfRunning) {
211 + if (isDone()) {
212 + return false;
213 + }
214 + // doing nothing for now
215 + // when onlab.netty Response support cancel, call them.
216 + isCancelled = true;
217 + return true;
218 + }
219 +
220 + @Override
221 + public boolean isCancelled() {
222 + return isCancelled;
223 + }
224 +
225 + @Override
226 + public boolean isDone() {
227 + return this.isDone || isCancelled();
202 } 228 }
203 229
204 @Override 230 @Override
205 - public byte[] get(long timeout) throws InterruptedException { 231 + public byte[] get() throws InterruptedException, ExecutionException {
206 - return responseFuture.get(); 232 + // TODO: consider forbidding this call and force the use of timed get
233 + // to enforce handling of remote peer failure scenario
234 + final byte[] result = responseFuture.get();
235 + isDone = true;
236 + return result;
207 } 237 }
208 } 238 }
209 } 239 }
......
...@@ -86,7 +86,7 @@ public class ReplicaInfoManager implements ReplicaInfoService { ...@@ -86,7 +86,7 @@ public class ReplicaInfoManager implements ReplicaInfoService {
86 final List<NodeId> standbyList = Collections.<NodeId>emptyList(); 86 final List<NodeId> standbyList = Collections.<NodeId>emptyList();
87 eventDispatcher.post(new ReplicaInfoEvent(MASTER_CHANGED, 87 eventDispatcher.post(new ReplicaInfoEvent(MASTER_CHANGED,
88 event.subject(), 88 event.subject(),
89 - new ReplicaInfo(event.node(), standbyList))); 89 + new ReplicaInfo(event.roleInfo().master(), standbyList)));
90 } 90 }
91 } 91 }
92 92
......
...@@ -4,6 +4,7 @@ import static org.onlab.onos.store.statistic.impl.StatisticStoreMessageSubjects. ...@@ -4,6 +4,7 @@ import static org.onlab.onos.store.statistic.impl.StatisticStoreMessageSubjects.
4 import static org.slf4j.LoggerFactory.getLogger; 4 import static org.slf4j.LoggerFactory.getLogger;
5 5
6 import com.google.common.collect.ImmutableSet; 6 import com.google.common.collect.ImmutableSet;
7 +
7 import org.apache.felix.scr.annotations.Activate; 8 import org.apache.felix.scr.annotations.Activate;
8 import org.apache.felix.scr.annotations.Component; 9 import org.apache.felix.scr.annotations.Component;
9 import org.apache.felix.scr.annotations.Deactivate; 10 import org.apache.felix.scr.annotations.Deactivate;
...@@ -26,9 +27,9 @@ import org.onlab.onos.store.flow.ReplicaInfo; ...@@ -26,9 +27,9 @@ import org.onlab.onos.store.flow.ReplicaInfo;
26 import org.onlab.onos.store.flow.ReplicaInfoService; 27 import org.onlab.onos.store.flow.ReplicaInfoService;
27 import org.onlab.onos.store.serializers.KryoNamespaces; 28 import org.onlab.onos.store.serializers.KryoNamespaces;
28 import org.onlab.onos.store.serializers.KryoSerializer; 29 import org.onlab.onos.store.serializers.KryoSerializer;
30 +import org.onlab.util.KryoNamespace;
29 import org.slf4j.Logger; 31 import org.slf4j.Logger;
30 32
31 -
32 import java.io.IOException; 33 import java.io.IOException;
33 import java.util.HashSet; 34 import java.util.HashSet;
34 import java.util.Map; 35 import java.util.Map;
...@@ -70,7 +71,9 @@ public class DistributedStatisticStore implements StatisticStore { ...@@ -70,7 +71,9 @@ public class DistributedStatisticStore implements StatisticStore {
70 protected static final KryoSerializer SERIALIZER = new KryoSerializer() { 71 protected static final KryoSerializer SERIALIZER = new KryoSerializer() {
71 @Override 72 @Override
72 protected void setupKryoPool() { 73 protected void setupKryoPool() {
73 - serializerPool = KryoNamespaces.API.newBuilder() 74 + serializerPool = KryoNamespace.newBuilder()
75 + .register(KryoNamespaces.API)
76 + // register this store specific classes here
74 .build() 77 .build()
75 .populate(1); 78 .populate(1);
76 } 79 }
......
...@@ -91,23 +91,14 @@ implements MastershipStore { ...@@ -91,23 +91,14 @@ implements MastershipStore {
91 91
92 @Override 92 @Override
93 public MastershipRole getRole(NodeId nodeId, DeviceId deviceId) { 93 public MastershipRole getRole(NodeId nodeId, DeviceId deviceId) {
94 - NodeId current = getNode(MASTER, deviceId); 94 + final RoleValue roleInfo = getRoleValue(deviceId);
95 - if (current == null) { 95 + if (roleInfo.contains(MASTER, nodeId)) {
96 - if (isRole(STANDBY, nodeId, deviceId)) { 96 + return MASTER;
97 - //was previously standby, or set to standby from master 97 + }
98 - return MastershipRole.STANDBY; 98 + if (roleInfo.contains(STANDBY, nodeId)) {
99 - } else { 99 + return STANDBY;
100 - return MastershipRole.NONE;
101 - }
102 - } else {
103 - if (current.equals(nodeId)) {
104 - //*should* be in unusable, not always
105 - return MastershipRole.MASTER;
106 - } else {
107 - //may be in backups or unusable from earlier retirement
108 - return MastershipRole.STANDBY;
109 - }
110 } 100 }
101 + return NONE;
111 } 102 }
112 103
113 @Override 104 @Override
...@@ -124,10 +115,11 @@ implements MastershipStore { ...@@ -124,10 +115,11 @@ implements MastershipStore {
124 roleMap.put(deviceId, rv); 115 roleMap.put(deviceId, rv);
125 return null; 116 return null;
126 case STANDBY: 117 case STANDBY:
118 + case NONE:
127 NodeId current = rv.get(MASTER); 119 NodeId current = rv.get(MASTER);
128 if (current != null) { 120 if (current != null) {
129 //backup and replace current master 121 //backup and replace current master
130 - rv.reassign(nodeId, NONE, STANDBY); 122 + rv.reassign(current, NONE, STANDBY);
131 rv.replace(current, nodeId, MASTER); 123 rv.replace(current, nodeId, MASTER);
132 } else { 124 } else {
133 //no master before so just add. 125 //no master before so just add.
...@@ -137,12 +129,6 @@ implements MastershipStore { ...@@ -137,12 +129,6 @@ implements MastershipStore {
137 roleMap.put(deviceId, rv); 129 roleMap.put(deviceId, rv);
138 updateTerm(deviceId); 130 updateTerm(deviceId);
139 return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo()); 131 return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
140 - case NONE:
141 - rv.add(MASTER, nodeId);
142 - rv.reassign(nodeId, STANDBY, NONE);
143 - roleMap.put(deviceId, rv);
144 - updateTerm(deviceId);
145 - return new MastershipEvent(MASTER_CHANGED, deviceId, rv.roleInfo());
146 default: 132 default:
147 log.warn("unknown Mastership Role {}", role); 133 log.warn("unknown Mastership Role {}", role);
148 return null; 134 return null;
...@@ -193,21 +179,28 @@ implements MastershipStore { ...@@ -193,21 +179,28 @@ implements MastershipStore {
193 switch (role) { 179 switch (role) {
194 case MASTER: 180 case MASTER:
195 rv.reassign(local, STANDBY, NONE); 181 rv.reassign(local, STANDBY, NONE);
182 + terms.putIfAbsent(deviceId, INIT);
196 roleMap.put(deviceId, rv); 183 roleMap.put(deviceId, rv);
197 break; 184 break;
198 case STANDBY: 185 case STANDBY:
199 rv.reassign(local, NONE, STANDBY); 186 rv.reassign(local, NONE, STANDBY);
200 roleMap.put(deviceId, rv); 187 roleMap.put(deviceId, rv);
201 terms.putIfAbsent(deviceId, INIT); 188 terms.putIfAbsent(deviceId, INIT);
202 -
203 break; 189 break;
204 case NONE: 190 case NONE:
205 - //claim mastership 191 + //either we're the first standby, or first to device.
206 - rv.add(MASTER, local); 192 + //for latter, claim mastership.
207 - rv.reassign(local, STANDBY, NONE); 193 + if (rv.get(MASTER) == null) {
194 + rv.add(MASTER, local);
195 + rv.reassign(local, STANDBY, NONE);
196 + updateTerm(deviceId);
197 + role = MastershipRole.MASTER;
198 + } else {
199 + rv.add(STANDBY, local);
200 + rv.reassign(local, NONE, STANDBY);
201 + role = MastershipRole.STANDBY;
202 + }
208 roleMap.put(deviceId, rv); 203 roleMap.put(deviceId, rv);
209 - updateTerm(deviceId);
210 - role = MastershipRole.MASTER;
211 break; 204 break;
212 default: 205 default:
213 log.warn("unknown Mastership Role {}", role); 206 log.warn("unknown Mastership Role {}", role);
...@@ -315,7 +308,10 @@ implements MastershipStore { ...@@ -315,7 +308,10 @@ implements MastershipStore {
315 RoleValue value = roleMap.get(deviceId); 308 RoleValue value = roleMap.get(deviceId);
316 if (value == null) { 309 if (value == null) {
317 value = new RoleValue(); 310 value = new RoleValue();
318 - roleMap.put(deviceId, value); 311 + RoleValue concurrentlyAdded = roleMap.putIfAbsent(deviceId, value);
312 + if (concurrentlyAdded != null) {
313 + return concurrentlyAdded;
314 + }
319 } 315 }
320 return value; 316 return value;
321 } 317 }
...@@ -329,16 +325,6 @@ implements MastershipStore { ...@@ -329,16 +325,6 @@ implements MastershipStore {
329 return null; 325 return null;
330 } 326 }
331 327
332 - //check if node is a certain role given a device
333 - private boolean isRole(
334 - MastershipRole role, NodeId nodeId, DeviceId deviceId) {
335 - RoleValue value = roleMap.get(deviceId);
336 - if (value != null) {
337 - return value.contains(role, nodeId);
338 - }
339 - return false;
340 - }
341 -
342 //adds or updates term information. 328 //adds or updates term information.
343 private void updateTerm(DeviceId deviceId) { 329 private void updateTerm(DeviceId deviceId) {
344 terms.lock(deviceId); 330 terms.lock(deviceId);
......
...@@ -97,6 +97,7 @@ public class DistributedMastershipStoreTest { ...@@ -97,6 +97,7 @@ public class DistributedMastershipStoreTest {
97 assertEquals("wrong role:", NONE, dms.getRole(N1, DID1)); 97 assertEquals("wrong role:", NONE, dms.getRole(N1, DID1));
98 testStore.put(DID1, N1, true, false, true); 98 testStore.put(DID1, N1, true, false, true);
99 assertEquals("wrong role:", MASTER, dms.getRole(N1, DID1)); 99 assertEquals("wrong role:", MASTER, dms.getRole(N1, DID1));
100 + testStore.put(DID1, N2, false, true, false);
100 assertEquals("wrong role:", STANDBY, dms.getRole(N2, DID1)); 101 assertEquals("wrong role:", STANDBY, dms.getRole(N2, DID1));
101 } 102 }
102 103
...@@ -155,6 +156,7 @@ public class DistributedMastershipStoreTest { ...@@ -155,6 +156,7 @@ public class DistributedMastershipStoreTest {
155 156
156 //switch over to N2 157 //switch over to N2
157 assertEquals("wrong event:", Type.MASTER_CHANGED, dms.setMaster(N2, DID1).type()); 158 assertEquals("wrong event:", Type.MASTER_CHANGED, dms.setMaster(N2, DID1).type());
159 + System.out.println(dms.getTermFor(DID1).master() + ":" + dms.getTermFor(DID1).termNumber());
158 assertEquals("wrong term", MastershipTerm.of(N2, 1), dms.getTermFor(DID1)); 160 assertEquals("wrong term", MastershipTerm.of(N2, 1), dms.getTermFor(DID1));
159 161
160 //orphan switch - should be rare case 162 //orphan switch - should be rare case
...@@ -182,14 +184,9 @@ public class DistributedMastershipStoreTest { ...@@ -182,14 +184,9 @@ public class DistributedMastershipStoreTest {
182 assertEquals("wrong event:", Type.MASTER_CHANGED, dms.relinquishRole(N1, DID1).type()); 184 assertEquals("wrong event:", Type.MASTER_CHANGED, dms.relinquishRole(N1, DID1).type());
183 assertEquals("wrong master", N2, dms.getMaster(DID1)); 185 assertEquals("wrong master", N2, dms.getMaster(DID1));
184 186
185 - //STANDBY - nothing here, either
186 - assertNull("wrong event:", dms.relinquishRole(N1, DID1));
187 - assertEquals("wrong role for node:", STANDBY, dms.getRole(N1, DID1));
188 -
189 //all nodes "give up" on device, which goes back to NONE. 187 //all nodes "give up" on device, which goes back to NONE.
190 assertNull("wrong event:", dms.relinquishRole(N2, DID1)); 188 assertNull("wrong event:", dms.relinquishRole(N2, DID1));
191 assertEquals("wrong role for node:", NONE, dms.getRole(N2, DID1)); 189 assertEquals("wrong role for node:", NONE, dms.getRole(N2, DID1));
192 - assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID1));
193 190
194 assertEquals("wrong number of retired nodes", 2, 191 assertEquals("wrong number of retired nodes", 2,
195 dms.roleMap.get(DID1).nodesOfRole(NONE).size()); 192 dms.roleMap.get(DID1).nodesOfRole(NONE).size());
...@@ -201,6 +198,10 @@ public class DistributedMastershipStoreTest { ...@@ -201,6 +198,10 @@ public class DistributedMastershipStoreTest {
201 assertEquals("wrong number of backup nodes", 1, 198 assertEquals("wrong number of backup nodes", 1,
202 dms.roleMap.get(DID1).nodesOfRole(STANDBY).size()); 199 dms.roleMap.get(DID1).nodesOfRole(STANDBY).size());
203 200
201 + //If STANDBY, should drop to NONE
202 + assertNull("wrong event:", dms.relinquishRole(N1, DID1));
203 + assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID1));
204 +
204 //NONE - nothing happens 205 //NONE - nothing happens
205 assertNull("wrong event:", dms.relinquishRole(N1, DID2)); 206 assertNull("wrong event:", dms.relinquishRole(N1, DID2));
206 assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2)); 207 assertEquals("wrong role for node:", NONE, dms.getRole(N1, DID2));
...@@ -218,7 +219,7 @@ public class DistributedMastershipStoreTest { ...@@ -218,7 +219,7 @@ public class DistributedMastershipStoreTest {
218 public void notify(MastershipEvent event) { 219 public void notify(MastershipEvent event) {
219 assertEquals("wrong event:", Type.MASTER_CHANGED, event.type()); 220 assertEquals("wrong event:", Type.MASTER_CHANGED, event.type());
220 assertEquals("wrong subject", DID1, event.subject()); 221 assertEquals("wrong subject", DID1, event.subject());
221 - assertEquals("wrong subject", N1, event.node()); 222 + assertEquals("wrong subject", N1, event.roleInfo().master());
222 addLatch.countDown(); 223 addLatch.countDown();
223 } 224 }
224 }; 225 };
......
...@@ -207,7 +207,7 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -207,7 +207,7 @@ public class OpenFlowControllerImpl implements OpenFlowController {
207 + "value for dpid: {}", dpid); 207 + "value for dpid: {}", dpid);
208 return false; 208 return false;
209 } else { 209 } else {
210 - log.error("Added switch {}", dpid); 210 + log.info("Added switch {}", dpid);
211 connectedSwitches.put(dpid, sw); 211 connectedSwitches.put(dpid, sw);
212 for (OpenFlowSwitchListener l : ofSwitchListener) { 212 for (OpenFlowSwitchListener l : ofSwitchListener) {
213 l.switchAdded(dpid); 213 l.switchAdded(dpid);
......
...@@ -610,7 +610,8 @@ ...@@ -610,7 +610,8 @@
610 </plugin> 610 </plugin>
611 611
612 </plugins> 612 </plugins>
613 -
614 </reporting> 613 </reporting>
615 - 614 + <prerequisites>
615 + <maven>3.0.0</maven>
616 + </prerequisites>
616 </project> 617 </project>
......
...@@ -16,58 +16,95 @@ from functools import partial ...@@ -16,58 +16,95 @@ from functools import partial
16 import time 16 import time
17 from sys import argv 17 from sys import argv
18 from time import sleep 18 from time import sleep
19 +from sets import Set
19 20
20 class ONOS( Controller ): 21 class ONOS( Controller ):
21 - #def __init__( self, name, command='/opt/onos/bin/onos-service', **kwargs ): 22 + "TODO"
22 - # Controller.__init__( self, name, command=command, inNamespace=True, **kwargs ) 23 +
23 - #def __init__( self, name, inNamespace=False, command='controller', 24 + onosDir = '/opt/onos/'
24 - # cargs='-v ptcp:%d', cdir=None, ip="127.0.0.1", 25 +
25 - # port=6633, protocol='tcp', **params ): 26 + def __init__( self, name, onosDir=onosDir,
26 - #self.command = command 27 + reactive=True, features=[ 'onos-app-tvue' ],
27 - #self.cargs = cargs 28 + **kwargs ):
28 - #self.cdir = cdir 29 + '''TODO'''
29 - #self.ip = ip 30 +
30 - #self.port = port 31 + Controller.__init__( self, name, **kwargs )
31 - #self.protocol = protocol 32 + # the following have been done for us:
32 - #Node.__init__( self, name, inNamespace=inNamespace, 33 + #self.ip = ip ('127.0.0.1')
33 - # ip=ip, **params ) 34 + #self.port = port (6633)
34 - #self.checkListening() 35 + #self.protocol = protocol ('tcp')
35 - 36 + #self.checkListening()
36 - ONOS_DIR = '/opt/onos/' 37 +
37 - KARAF_DIR = ONOS_DIR + 'apache-karaf-3.0.1/' 38 + self.onosDir = onosDir
38 - reactive = True 39 + self.karafDir = onosDir + 'apache-karaf-3.0.1/'
40 + self.instanceDir = self.karafDir
41 +
42 + # add default modules
43 + # TODO: consider an ordered set
44 + self.features = Set([ 'webconsole',
45 + 'onos-api',
46 + 'onos-cli',
47 + 'onos-openflow' ])
48 + self.features.update( features )
49 + # add reactive forwarding modules
50 + if reactive:
51 + self.features.update( ['onos-app-fwd',
52 + 'onos-app-proxyarp',
53 + 'onos-app-mobility' ] )
54 + # add the distributed core if we are in a namespace with no trivial core
55 + if self.inNamespace and 'onos-core-trivial' not in self.features:
56 + self.features.add( 'onos-core' )
57 + # if there is no core, add the trivial one
58 + if 'onos-core' not in self.features:
59 + self.features.add( 'onos-core-trivial' )
60 + print self.features
39 61
40 def start( self ): 62 def start( self ):
41 - # switch to the non-root user because karaf gets upset otherwise
42 - # TODO we should look into why....
43 - self.sendCmd( 'sudo su - %s' % self.findUser() )
44 - self.waiting = False
45 -
46 if self.inNamespace: 63 if self.inNamespace:
47 - self.cmd( self.KARAF_DIR + 'bin/instance create %s' % self.name ) 64 + instanceOpts = ( '-furl mvn:org.onlab.onos/onos-features/1.0.0-SNAPSHOT/xml/features '
48 - src = self.KARAF_DIR + 'etc/org.apache.karaf.features.cfg' 65 + '-s 8101' )
49 - dst = self.KARAF_DIR + 'instances/%s/etc/org.apache.karaf.features.cfg' % self.name 66 + self.userCmd( self.karafDir + 'bin/instance create %s %s' % ( instanceOpts, self.name ) )
50 - self.cmd( 'cp %s %s' % (src, dst) ) 67 + self.instanceDir = self.karafDir + 'instances/%s/' % self.name
51 - self.updateProperties( dst )
52 - self.cmd( self.KARAF_DIR + 'bin/instance start %s' % self.name )
53 else: 68 else:
54 # we are running in the root namespace, so let's use the root instance 69 # we are running in the root namespace, so let's use the root instance
55 - self.cmd( 'rm -rf '+ self.KARAF_DIR + 'data/' ) 70 + # clean up the data directory
56 - filename = self.KARAF_DIR + 'etc/org.apache.karaf.features.cfg' 71 + #self.userCmd( 'rm -rf '+ self.karafDir + 'data/' )
57 - self.updateProperties( filename ) 72 + pass
58 - self.cmd( self.KARAF_DIR + 'bin/start' ) 73 +
74 + self.userCmd( 'rm -rf '+ self.instanceDir + 'data/' )
75 +
76 + # Update etc/org.apache.karaf.features.cfg
77 + self.updateFeatures()
59 78
79 + # TODO 2. Update etc/hazelcast.xml : interface lines
80 + #cp etc/hazelcast.xml instances/c1/etc/
81 + self.updateHazelcast()
82 +
83 + # TODO 3. Update etc/system.properties : onos.ip
84 + # TODO 4. Update config/cluster.json : with all nodes
85 +
86 + # start onos
87 + self.userCmd( self.instanceDir + 'bin/start' )
60 #TODO we should wait for startup... 88 #TODO we should wait for startup...
61 89
62 def stop( self ): 90 def stop( self ):
63 - if self.inNamespace: 91 + self.userCmd( self.instanceDir + 'bin/stop' )
64 - self.cmd( '/opt/onos/apache-karaf-3.0.1/bin/instance stop %s' % self.name ) 92 + #if self.inNamespace:
65 - self.cmd( '/opt/onos/apache-karaf-3.0.1/bin/instance destroy %s' % self.name ) 93 + # self.userCmd( self.karafDir + 'bin/instance destroy %s' % self.name )
66 - else:
67 - self.cmd( self.ONOS_DIR + 'apache-karaf-3.0.1/bin/stop' )
68 self.terminate() 94 self.terminate()
69 95
70 - def updateProperties( self, filename ): 96 + def updateHazelcast( self ):
97 + readfile = self.karafDir + 'etc/hazelcast.xml'
98 + writefile = self.instanceDir + 'etc/hazelcast.xml'
99 + with open( readfile, 'r' ) as r:
100 + with open( writefile, 'w' ) as w:
101 + for line in r.readlines():
102 + if '<interface>' in line:
103 + line = '<interface>' + '192.168.123.*' + '</interface>\n'
104 + w.write( line )
105 +
106 + def updateFeatures( self ):
107 + filename = self.instanceDir + 'etc/org.apache.karaf.features.cfg'
71 with open( filename, 'r+' ) as f: 108 with open( filename, 'r+' ) as f:
72 lines = f.readlines() 109 lines = f.readlines()
73 f.seek(0) 110 f.seek(0)
...@@ -75,17 +112,25 @@ class ONOS( Controller ): ...@@ -75,17 +112,25 @@ class ONOS( Controller ):
75 for line in lines: 112 for line in lines:
76 #print '?', line, 113 #print '?', line,
77 if 'featuresBoot=' in line: 114 if 'featuresBoot=' in line:
78 - line = line.rstrip() 115 + # parse the features from the line
79 - #print ord(line[-1]), ord(line[-2]), ord(line[-3]) 116 + features = line.rstrip().split('=')[1].split(',')
80 - if self.reactive: 117 + # add the features to our features set
81 - line += ',onos-app-fwd' 118 + self.features.update( features )
82 - line += '\n' 119 + # generate the new features line
120 + line = 'featuresBoot=' + ','.join( self.features ) + '\n'
83 #print '!', line, 121 #print '!', line,
84 f.write( line ) 122 f.write( line )
85 123
124 +
86 @classmethod 125 @classmethod
87 def isAvailable( self ): 126 def isAvailable( self ):
88 - return quietRun( 'ls /opt/onos' ) 127 + return quietRun( 'ls %s' % self.onosDir )
128 +
129 + def userCmd( self, cmd ):
130 + # switch to the non-root user because karaf gets upset otherwise
131 + # because the .m2repo is not stored with root
132 + cmd = 'sudo -u %s %s' % ( self.findUser(), cmd )
133 + return self.cmd( cmd )
89 134
90 @staticmethod 135 @staticmethod
91 def findUser(): 136 def findUser():
...@@ -111,7 +156,7 @@ class ControlNetwork( Topo ): ...@@ -111,7 +156,7 @@ class ControlNetwork( Topo ):
111 # Connect everything to a single switch 156 # Connect everything to a single switch
112 cs0 = self.addSwitch( 'cs0' ) 157 cs0 = self.addSwitch( 'cs0' )
113 # Add hosts which will serve as data network controllers 158 # Add hosts which will serve as data network controllers
114 - for i in range( 0, n ): 159 + for i in range( 1, n+1 ):
115 c = self.addHost( 'c%s' % i, cls=dataController, 160 c = self.addHost( 'c%s' % i, cls=dataController,
116 inNamespace=True ) 161 inNamespace=True )
117 self.addLink( c, cs0 ) 162 self.addLink( c, cs0 )
...@@ -122,7 +167,7 @@ class ControlNetwork( Topo ): ...@@ -122,7 +167,7 @@ class ControlNetwork( Topo ):
122 167
123 class ONOSCluster( Controller ): 168 class ONOSCluster( Controller ):
124 # TODO 169 # TODO
125 - n = 4 170 + n = 3
126 171
127 def start( self ): 172 def start( self ):
128 ctopo = ControlNetwork( n=self.n, dataController=ONOS ) 173 ctopo = ControlNetwork( n=self.n, dataController=ONOS )
...@@ -137,6 +182,9 @@ class ONOSCluster( Controller ): ...@@ -137,6 +182,9 @@ class ONOSCluster( Controller ):
137 host.start() 182 host.start()
138 183
139 def stop( self ): 184 def stop( self ):
185 + for host in self.cnet.hosts:
186 + if isinstance( host, Controller ):
187 + host.stop()
140 self.cnet.stop() 188 self.cnet.stop()
141 189
142 def clist( self ): 190 def clist( self ):
...@@ -158,10 +206,11 @@ switches = { 'ovso': OVSSwitchONOS } ...@@ -158,10 +206,11 @@ switches = { 'ovso': OVSSwitchONOS }
158 206
159 if __name__ == '__main__': 207 if __name__ == '__main__':
160 # Simple test for ONOS() controller class 208 # Simple test for ONOS() controller class
161 - setLogLevel( 'info' ) 209 + setLogLevel( 'info' ) #TODO info
162 size = 2 if len( argv ) != 2 else int( argv[ 1 ] ) 210 size = 2 if len( argv ) != 2 else int( argv[ 1 ] )
163 net = Mininet( topo=LinearTopo( size ), 211 net = Mininet( topo=LinearTopo( size ),
164 - controller=partial( ONOSCluster, n=4 ), 212 + #controller=ONOS,
213 + controller=partial( ONOSCluster, n=3 ), #TODO
165 switch=OVSSwitchONOS ) 214 switch=OVSSwitchONOS )
166 net.start() 215 net.start()
167 #waitConnected( net.switches ) 216 #waitConnected( net.switches )
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
26 <dependency> 26 <dependency>
27 <groupId>com.google.guava</groupId> 27 <groupId>com.google.guava</groupId>
28 <artifactId>guava</artifactId> 28 <artifactId>guava</artifactId>
29 - <version>17.0</version>
30 <scope>test</scope> 29 <scope>test</scope>
31 </dependency> 30 </dependency>
32 31
......