diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index a91dfba0741..3d0ed144903 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -468,6 +468,9 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { AgentAttache attache = createAttache(id, server, resource); if (!resource.IsRemoteAgent()) notifyMonitorsOfConnection(attache, startup); + else { + _hostDao.updateStatus(server, Event.AgentConnected, _nodeId); + } return attache; } diff --git a/server/src/com/cloud/agent/manager/DirectAgentAttache.java b/server/src/com/cloud/agent/manager/DirectAgentAttache.java index e651c76813e..cafa42b9306 100644 --- a/server/src/com/cloud/agent/manager/DirectAgentAttache.java +++ b/server/src/com/cloud/agent/manager/DirectAgentAttache.java @@ -124,7 +124,11 @@ public class DirectAgentAttache extends AgentAttache { public synchronized void run() { try { ServerResource resource = _resource; - + + if (resource.IsRemoteAgent()) { + return; + } + if (resource != null) { PingCommand cmd = resource.getCurrentStatus(_id); if (cmd == null) { diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java index 2f043069012..b1d8bb088cf 100644 --- a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java @@ -1,5 +1,7 @@ package com.cloud.hypervisor.kvm.discoverer; +import java.io.IOException; +import java.io.InputStream; import java.net.InetAddress; import java.net.URI; import java.util.HashMap; @@ -31,6 +33,7 @@ import com.cloud.resource.ServerResource; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; import com.cloud.utils.script.Script; +import com.trilead.ssh2.ChannelCondition; import com.trilead.ssh2.SCPClient; import com.trilead.ssh2.Session; @@ -92,6 +95,85 @@ public class KvmServerDiscoverer extends DiscovererBase implements Discoverer, // TODO Auto-generated method stub return false; } + + private static boolean sshExecuteCmd(com.trilead.ssh2.Connection sshConnection, String cmd) { + s_logger.debug("Executing cmd: " + cmd); + Session sshSession = null; + try { + sshSession = sshConnection.openSession(); + // There is a bug in Trilead library, wait a second before + // starting a shell and executing commands, from http://spci.st.ewi.tudelft.nl/chiron/xref/nl/tudelft/swerl/util/SSHConnection.html + Thread.sleep(1000); + + if (sshSession == null) { + return false; + } + + sshSession.execCommand(cmd); + + InputStream stdout = sshSession.getStdout(); + InputStream stderr = sshSession.getStderr(); + + + byte[] buffer = new byte[8192]; + while (true) { + if (stdout == null || stderr == null) { + return false; + } + + if ((stdout.available() == 0) && (stderr.available() == 0)) { + int conditions = sshSession.waitForCondition( + ChannelCondition.STDOUT_DATA + | ChannelCondition.STDERR_DATA + | ChannelCondition.EOF, 120000); + + if ((conditions & ChannelCondition.TIMEOUT) != 0) { + s_logger.info("Timeout while waiting for data from peer."); + break; + } + + if ((conditions & ChannelCondition.EOF) != 0) { + if ((conditions & (ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA)) == 0) { + break; + } + } + } + + while (stdout.available() > 0) { + stdout.read(buffer); + } + + while (stderr.available() > 0) { + stderr.read(buffer); + } + } + + Thread.sleep(1000); + if (sshSession.getExitStatus() != 0) { + return false; + } + + return true; + } catch (IOException e) { + s_logger.debug("Executing cmd: " + cmd + " failed, due to: " + e.toString()); + return false; + } catch (InterruptedException e) { + return false; + } catch (Exception e) { + return false; + } finally { + if (sshSession != null) + sshSession.close(); + } + } + + private static boolean sshExecuteCmd(com.trilead.ssh2.Connection sshConnection, String cmd, int nTimes) { + for (int i = 0; i < nTimes; i ++) { + if (sshExecuteCmd(sshConnection, cmd)) + return true; + } + return false; + } @Override public Map> find(long dcId, @@ -99,13 +181,12 @@ public class KvmServerDiscoverer extends DiscovererBase implements Discoverer, String password) throws DiscoveryException { Map> resources = new HashMap>(); Map details = new HashMap(); - if (!uri.getScheme().equals("kvm")) { + if (!uri.getScheme().equals("http")) { String msg = "urlString is not kvm so we're not taking care of the discovery for this: " + uri; s_logger.debug(msg); return null; } com.trilead.ssh2.Connection sshConnection = null; - Session sshSession = null; String agentIp = null; try { @@ -119,19 +200,24 @@ public class KvmServerDiscoverer extends DiscovererBase implements Discoverer, if (!sshConnection.authenticateWithPassword(username, password)) { throw new Exception("Unable to authenticate"); } + + if (!sshExecuteCmd(sshConnection, "lsmod|grep kvm >& /dev/null", 3)) { + s_logger.debug("It's not a KVM enabled machine"); + return null; + } + + s_logger.debug("copying " + _setupAgentPath + " to host"); SCPClient scp = new SCPClient(sshConnection); scp.put(_setupAgentPath, "/usr/bin", "0755"); - sshSession = sshConnection.openSession(); - /*running setup script in background, because we will restart agent network, that may cause connection lost*/ - s_logger.debug("/usr/bin/setup_agent.sh " + " -h " + _hostIp + " -z " + dcId + " -p " + podId + " -u " + guid); - sshSession.execCommand("/usr/bin/setup_agent.sh " + " -h " + _hostIp + " -z " + dcId + " -p " + podId + " -u " + guid + " 1>&2" ); + + sshExecuteCmd(sshConnection, "/usr/bin/setup_agent.sh " + " -h " + _hostIp + " -z " + dcId + " -p " + podId + " -u " + guid + " 1>&2", 3); KvmDummyResourceBase kvmResource = new KvmDummyResourceBase(); Map params = new HashMap(); params.put("zone", Long.toString(dcId)); params.put("pod", Long.toString(podId)); - params.put("guid", guid); + params.put("guid", guid + "-LibvirtComputingResource"); /*tail added by agent.java*/ params.put("agentIp", agentIp); kvmResource.configure("kvm agent", params); kvmResource.setRemoteAgent(true); @@ -141,9 +227,6 @@ public class KvmServerDiscoverer extends DiscovererBase implements Discoverer, String msg = " can't setup agent, due to " + e.toString() + " - " + e.getMessage(); s_logger.warn(msg); } finally { - if (sshSession != null) - sshSession.close(); - if (sshConnection != null) sshConnection.close(); }