Hyunsun Moon
Committed by Gerrit Code Review

Improved node bootstrap and debugging

Change-Id: I37d8a5236c9dc798a524891c8918380a6f85a6b5
...@@ -21,6 +21,9 @@ import org.apache.karaf.shell.commands.Command; ...@@ -21,6 +21,9 @@ import org.apache.karaf.shell.commands.Command;
21 import org.onosproject.cli.AbstractShellCommand; 21 import org.onosproject.cli.AbstractShellCommand;
22 import org.onosproject.cordvtn.api.CordVtnNode; 22 import org.onosproject.cordvtn.api.CordVtnNode;
23 import org.onosproject.cordvtn.impl.CordVtnNodeManager; 23 import org.onosproject.cordvtn.impl.CordVtnNodeManager;
24 +import org.onosproject.net.Device;
25 +import org.onosproject.net.device.DeviceService;
26 +import org.onosproject.net.driver.DriverService;
24 27
25 /** 28 /**
26 * Checks detailed node init state. 29 * Checks detailed node init state.
...@@ -36,6 +39,8 @@ public class CordVtnNodeCheckCommand extends AbstractShellCommand { ...@@ -36,6 +39,8 @@ public class CordVtnNodeCheckCommand extends AbstractShellCommand {
36 @Override 39 @Override
37 protected void execute() { 40 protected void execute() {
38 CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class); 41 CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class);
42 + DeviceService deviceService = AbstractShellCommand.get(DeviceService.class);
43 +
39 CordVtnNode node = nodeManager.getNodes() 44 CordVtnNode node = nodeManager.getNodes()
40 .stream() 45 .stream()
41 .filter(n -> n.hostname().equals(hostname)) 46 .filter(n -> n.hostname().equals(hostname))
...@@ -48,5 +53,22 @@ public class CordVtnNodeCheckCommand extends AbstractShellCommand { ...@@ -48,5 +53,22 @@ public class CordVtnNodeCheckCommand extends AbstractShellCommand {
48 } 53 }
49 54
50 print(nodeManager.checkNodeInitState(node)); 55 print(nodeManager.checkNodeInitState(node));
56 +
57 + print("%n[DEBUG]");
58 + Device device = deviceService.getDevice(node.intBrId());
59 + String driver = get(DriverService.class).getDriver(device.id()).name();
60 + print("%s available=%s driver=%s %s",
61 + device.id(),
62 + deviceService.isAvailable(device.id()),
63 + driver,
64 + device.annotations());
65 +
66 + deviceService.getPorts(node.intBrId()).forEach(port -> {
67 + Object portIsEnabled = port.isEnabled() ? "enabled" : "disabled";
68 + print("port=%s state=%s %s",
69 + port.number(),
70 + portIsEnabled,
71 + port.annotations());
72 + });
51 } 73 }
52 } 74 }
......
...@@ -178,7 +178,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro ...@@ -178,7 +178,7 @@ public class CordVtn extends AbstractProvider implements CordVtnService, HostPro
178 178
179 @Activate 179 @Activate
180 protected void activate() { 180 protected void activate() {
181 - appId = coreService.registerApplication("org.onosproject.cordvtn"); 181 + appId = coreService.registerApplication(CordVtnService.CORDVTN_APP_ID);
182 ruleInstaller = new CordVtnRuleInstaller(appId, flowRuleService, 182 ruleInstaller = new CordVtnRuleInstaller(appId, flowRuleService,
183 deviceService, 183 deviceService,
184 groupService, 184 groupService,
......
...@@ -86,6 +86,7 @@ import java.util.stream.Collectors; ...@@ -86,6 +86,7 @@ import java.util.stream.Collectors;
86 import static com.google.common.base.Preconditions.checkNotNull; 86 import static com.google.common.base.Preconditions.checkNotNull;
87 import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; 87 import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
88 import static org.onlab.util.Tools.groupedThreads; 88 import static org.onlab.util.Tools.groupedThreads;
89 +import static org.onosproject.cordvtn.impl.RemoteIpCommandUtil.*;
89 import static org.onosproject.net.Device.Type.SWITCH; 90 import static org.onosproject.net.Device.Type.SWITCH;
90 import static org.onosproject.net.behaviour.TunnelDescription.Type.VXLAN; 91 import static org.onosproject.net.behaviour.TunnelDescription.Type.VXLAN;
91 import static org.slf4j.LoggerFactory.getLogger; 92 import static org.slf4j.LoggerFactory.getLogger;
...@@ -222,7 +223,7 @@ public class CordVtnNodeManager { ...@@ -222,7 +223,7 @@ public class CordVtnNodeManager {
222 } 223 }
223 224
224 @Activate 225 @Activate
225 - protected void active() { 226 + protected void activate() {
226 appId = coreService.getAppId(CordVtnService.CORDVTN_APP_ID); 227 appId = coreService.getAppId(CordVtnService.CORDVTN_APP_ID);
227 localNodeId = clusterService.getLocalNode().id(); 228 localNodeId = clusterService.getLocalNode().id();
228 leadershipService.runForLeadership(appId.name()); 229 leadershipService.runForLeadership(appId.name());
...@@ -242,18 +243,20 @@ public class CordVtnNodeManager { ...@@ -242,18 +243,20 @@ public class CordVtnNodeManager {
242 nodeStore.addListener(nodeStoreListener); 243 nodeStore.addListener(nodeStoreListener);
243 deviceService.addListener(deviceListener); 244 deviceService.addListener(deviceListener);
244 configService.addListener(configListener); 245 configService.addListener(configListener);
246 +
247 + log.info("Started");
245 } 248 }
246 249
247 @Deactivate 250 @Deactivate
248 protected void deactivate() { 251 protected void deactivate() {
249 configService.removeListener(configListener); 252 configService.removeListener(configListener);
250 deviceService.removeListener(deviceListener); 253 deviceService.removeListener(deviceListener);
251 -
252 nodeStore.removeListener(nodeStoreListener); 254 nodeStore.removeListener(nodeStoreListener);
253 - nodeStore.clear();
254 255
255 leadershipService.withdraw(appId.name()); 256 leadershipService.withdraw(appId.name());
256 eventExecutor.shutdown(); 257 eventExecutor.shutdown();
258 +
259 + log.info("Stopped");
257 } 260 }
258 261
259 /** 262 /**
...@@ -344,29 +347,31 @@ public class CordVtnNodeManager { ...@@ -344,29 +347,31 @@ public class CordVtnNodeManager {
344 return null; 347 return null;
345 } 348 }
346 349
347 - Session session = RemoteIpCommandUtil.connect(node.sshInfo()); 350 + Session session = connect(node.sshInfo());
348 if (session == null) { 351 if (session == null) {
349 log.debug("Failed to SSH to {}", node.hostname()); 352 log.debug("Failed to SSH to {}", node.hostname());
350 return null; 353 return null;
351 } 354 }
352 355
353 - Set<IpAddress> intBrIps = RemoteIpCommandUtil.getCurrentIps(session, DEFAULT_BRIDGE); 356 + Set<IpAddress> intBrIps = getCurrentIps(session, DEFAULT_BRIDGE);
354 String result = String.format( 357 String result = String.format(
355 - "br-int created and connected : %s (%s)%n" + 358 + "Current state : %s%n" +
356 - "VXLAN interface created : %s%n" + 359 + "br-int created and connected to ONOS : %s (%s)%n" +
357 - "Data plane interface added : %s (%s)%n" + 360 + "VXLAN interface added to br-int : %s%n" +
358 - "IP flushed from %s : %s%n" + 361 + "Data plane interface is added to br-int and enabled : %s (%s)%n" +
362 + "IP flushed from data plane interface : %s (%s)%n" +
359 "Data plane IP added to br-int : %s (%s)%n" + 363 "Data plane IP added to br-int : %s (%s)%n" +
360 "Local management IP added to br-int : %s (%s)", 364 "Local management IP added to br-int : %s (%s)",
365 + node.state(),
361 isBrIntCreated(node) ? OK : NO, node.intBrId(), 366 isBrIntCreated(node) ? OK : NO, node.intBrId(),
362 isTunnelIntfCreated(node) ? OK : NO, 367 isTunnelIntfCreated(node) ? OK : NO,
363 isDataPlaneIntfAdded(node) ? OK : NO, node.dpIntf(), 368 isDataPlaneIntfAdded(node) ? OK : NO, node.dpIntf(),
364 - node.dpIntf(), 369 + isInterfaceUp(session, node.dpIntf()) &&
365 - RemoteIpCommandUtil.getCurrentIps(session, node.dpIntf()).isEmpty() ? OK : NO, 370 + getCurrentIps(session, node.dpIntf()).isEmpty() ? OK : NO, node.dpIntf(),
366 intBrIps.contains(node.dpIp().ip()) ? OK : NO, node.dpIp().cidr(), 371 intBrIps.contains(node.dpIp().ip()) ? OK : NO, node.dpIp().cidr(),
367 intBrIps.contains(node.localMgmtIp().ip()) ? OK : NO, node.localMgmtIp().cidr()); 372 intBrIps.contains(node.localMgmtIp().ip()) ? OK : NO, node.localMgmtIp().cidr());
368 373
369 - RemoteIpCommandUtil.disconnect(session); 374 + disconnect(session);
370 375
371 return result; 376 return result;
372 } 377 }
...@@ -630,6 +635,18 @@ public class CordVtnNodeManager { ...@@ -630,6 +635,18 @@ public class CordVtnNodeManager {
630 return; 635 return;
631 } 636 }
632 637
638 + Session session = connect(node.sshInfo());
639 + if (session == null) {
640 + log.debug("Failed to SSH to {}", node.hostname());
641 + return;
642 + }
643 +
644 + if (!isInterfaceUp(session, node.dpIntf())) {
645 + log.warn("Interface {} is not available", node.dpIntf());
646 + return;
647 + }
648 + disconnect(session);
649 +
633 try { 650 try {
634 Device device = deviceService.getDevice(node.ovsdbId()); 651 Device device = deviceService.getDevice(node.ovsdbId());
635 if (device.is(BridgeConfig.class)) { 652 if (device.is(BridgeConfig.class)) {
...@@ -650,24 +667,24 @@ public class CordVtnNodeManager { ...@@ -650,24 +667,24 @@ public class CordVtnNodeManager {
650 * @param node cordvtn node 667 * @param node cordvtn node
651 */ 668 */
652 private void setIpAddress(CordVtnNode node) { 669 private void setIpAddress(CordVtnNode node) {
653 - Session session = RemoteIpCommandUtil.connect(node.sshInfo()); 670 + Session session = connect(node.sshInfo());
654 if (session == null) { 671 if (session == null) {
655 log.debug("Failed to SSH to {}", node.hostname()); 672 log.debug("Failed to SSH to {}", node.hostname());
656 return; 673 return;
657 } 674 }
658 675
659 - RemoteIpCommandUtil.getCurrentIps(session, DEFAULT_BRIDGE).stream() 676 + getCurrentIps(session, DEFAULT_BRIDGE).stream()
660 .filter(ip -> !ip.equals(node.localMgmtIp().ip())) 677 .filter(ip -> !ip.equals(node.localMgmtIp().ip()))
661 .filter(ip -> !ip.equals(node.dpIp().ip())) 678 .filter(ip -> !ip.equals(node.dpIp().ip()))
662 - .forEach(ip -> RemoteIpCommandUtil.deleteIp(session, ip, DEFAULT_BRIDGE)); 679 + .forEach(ip -> deleteIp(session, ip, DEFAULT_BRIDGE));
663 680
664 - boolean result = RemoteIpCommandUtil.flushIp(session, node.dpIntf()) && 681 + boolean result = flushIp(session, node.dpIntf()) &&
665 - RemoteIpCommandUtil.setInterfaceUp(session, node.dpIntf()) && 682 + setInterfaceUp(session, node.dpIntf()) &&
666 - RemoteIpCommandUtil.addIp(session, node.dpIp(), DEFAULT_BRIDGE) && 683 + addIp(session, node.dpIp(), DEFAULT_BRIDGE) &&
667 - RemoteIpCommandUtil.addIp(session, node.localMgmtIp(), DEFAULT_BRIDGE) && 684 + addIp(session, node.localMgmtIp(), DEFAULT_BRIDGE) &&
668 - RemoteIpCommandUtil.setInterfaceUp(session, DEFAULT_BRIDGE); 685 + setInterfaceUp(session, DEFAULT_BRIDGE);
669 686
670 - RemoteIpCommandUtil.disconnect(session); 687 + disconnect(session);
671 688
672 if (result) { 689 if (result) {
673 setNodeState(node, NodeState.COMPLETE); 690 setNodeState(node, NodeState.COMPLETE);
...@@ -720,20 +737,20 @@ public class CordVtnNodeManager { ...@@ -720,20 +737,20 @@ public class CordVtnNodeManager {
720 * @return true if the IP is set, false otherwise 737 * @return true if the IP is set, false otherwise
721 */ 738 */
722 private boolean isIpAddressSet(CordVtnNode node) { 739 private boolean isIpAddressSet(CordVtnNode node) {
723 - Session session = RemoteIpCommandUtil.connect(node.sshInfo()); 740 + Session session = connect(node.sshInfo());
724 if (session == null) { 741 if (session == null) {
725 log.debug("Failed to SSH to {}", node.hostname()); 742 log.debug("Failed to SSH to {}", node.hostname());
726 return false; 743 return false;
727 } 744 }
728 745
729 - Set<IpAddress> intBrIps = RemoteIpCommandUtil.getCurrentIps(session, DEFAULT_BRIDGE); 746 + Set<IpAddress> intBrIps = getCurrentIps(session, DEFAULT_BRIDGE);
730 - boolean result = RemoteIpCommandUtil.getCurrentIps(session, node.dpIntf()).isEmpty() && 747 + boolean result = getCurrentIps(session, node.dpIntf()).isEmpty() &&
731 - RemoteIpCommandUtil.isInterfaceUp(session, node.dpIntf()) && 748 + isInterfaceUp(session, node.dpIntf()) &&
732 intBrIps.contains(node.dpIp().ip()) && 749 intBrIps.contains(node.dpIp().ip()) &&
733 intBrIps.contains(node.localMgmtIp().ip()) && 750 intBrIps.contains(node.localMgmtIp().ip()) &&
734 - RemoteIpCommandUtil.isInterfaceUp(session, DEFAULT_BRIDGE); 751 + isInterfaceUp(session, DEFAULT_BRIDGE);
735 752
736 - RemoteIpCommandUtil.disconnect(session); 753 + disconnect(session);
737 return result; 754 return result;
738 } 755 }
739 756
...@@ -951,13 +968,13 @@ public class CordVtnNodeManager { ...@@ -951,13 +968,13 @@ public class CordVtnNodeManager {
951 oldNode = event.oldValue().value(); 968 oldNode = event.oldValue().value();
952 newNode = event.newValue().value(); 969 newNode = event.newValue().value();
953 970
971 + log.info("Reloaded {}", newNode.hostname());
954 if (!newNode.equals(oldNode)) { 972 if (!newNode.equals(oldNode)) {
955 - log.info("{} has been updated", newNode.hostname());
956 log.debug("New node: {}", newNode); 973 log.debug("New node: {}", newNode);
957 } 974 }
958 - // perform init procedure based on current state on any updates, 975 + // performs init procedure even if the node is not changed
959 - // insert, or even if the node is the same for robustness since 976 + // for robustness since it's no harm to run init procedure
960 - // it's no harm to run the init procedure multiple times 977 + // multiple times
961 eventExecutor.execute(() -> initNode(newNode)); 978 eventExecutor.execute(() -> initNode(newNode));
962 break; 979 break;
963 case INSERT: 980 case INSERT:
...@@ -967,7 +984,7 @@ public class CordVtnNodeManager { ...@@ -967,7 +984,7 @@ public class CordVtnNodeManager {
967 break; 984 break;
968 case REMOVE: 985 case REMOVE:
969 oldNode = event.oldValue().value(); 986 oldNode = event.oldValue().value();
970 - log.info("{} is removed", oldNode.hostname()); 987 + log.info("Removed {}", oldNode.hostname());
971 break; 988 break;
972 default: 989 default:
973 break; 990 break;
......