mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
"Add host" for kvm:
The sequence: 1. add host in UI 2. scp setup_agent.sh to agent host, and execute it. This script receives hostip,zoneid, podid and guid, then runs "cloud-setup-agent" and "cloud-setup-console-proxy". Here, we assume that network/hostname and cloud-agent are already configed and installed. 3. Write a dummy kvm resource into the database, then wait for agent connects to server, by polling the database for every 1 minutes. If it finds the agent is in UP state in database, then return, or wait for at least 10 minutes.
This commit is contained in:
parent
59912c09c9
commit
53df26daaa
@ -37,16 +37,14 @@ backupdir = "@SHAREDSTATEDIR@/@AGENTPATH@/etcbackup"
|
|||||||
|
|
||||||
#=================== the magic happens here ====================
|
#=================== the magic happens here ====================
|
||||||
|
|
||||||
stderr("Welcome to the Cloud Agent setup")
|
|
||||||
stderr("")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# parse cmd line
|
# parse cmd line
|
||||||
opts, args = getopt.getopt(sys.argv[1:], "a", ["host=", "zone=", "pod=", "no-kvm"])
|
opts, args = getopt.getopt(sys.argv[1:], "a", ["host=", "zone=", "pod=", "no-kvm", "guid="])
|
||||||
host=None
|
host=None
|
||||||
zone=None
|
zone=None
|
||||||
pod=None
|
pod=None
|
||||||
stderr(str(opts))
|
guid=None
|
||||||
autoMode=False
|
autoMode=False
|
||||||
do_check_kvm = True
|
do_check_kvm = True
|
||||||
for opt, arg in opts:
|
for opt, arg in opts:
|
||||||
@ -59,11 +57,19 @@ try:
|
|||||||
elif opt == "--pod":
|
elif opt == "--pod":
|
||||||
if arg != "":
|
if arg != "":
|
||||||
pod = arg
|
pod = arg
|
||||||
|
elif opt == "--guid":
|
||||||
|
if arg != "":
|
||||||
|
guid = arg
|
||||||
elif opt == "--no-kvm":
|
elif opt == "--no-kvm":
|
||||||
do_check_kvm = False
|
do_check_kvm = False
|
||||||
elif opt == "-a":
|
elif opt == "-a":
|
||||||
autoMode=True
|
autoMode=True
|
||||||
|
|
||||||
|
if autoMode:
|
||||||
|
cloud_utils.setLogFile("/var/log/cloud/setupAgent.log")
|
||||||
|
|
||||||
|
stderr("Welcome to the Cloud Agent setup")
|
||||||
|
stderr("")
|
||||||
# pre-flight checks for things that the administrator must fix
|
# pre-flight checks for things that the administrator must fix
|
||||||
try:
|
try:
|
||||||
for f,n in cloud_utils.preflight_checks(
|
for f,n in cloud_utils.preflight_checks(
|
||||||
@ -106,7 +112,7 @@ try:
|
|||||||
stderr(str(e))
|
stderr(str(e))
|
||||||
bail(cloud_utils.E_SETUPFAILED,"Cloud Agent setup failed")
|
bail(cloud_utils.E_SETUPFAILED,"Cloud Agent setup failed")
|
||||||
|
|
||||||
setup_agent_config(configfile, host, zone, pod)
|
setup_agent_config(configfile, host, zone, pod, guid)
|
||||||
stderr("Enabling and starting the Cloud Agent")
|
stderr("Enabling and starting the Cloud Agent")
|
||||||
stop_service(servicename)
|
stop_service(servicename)
|
||||||
enable_service(servicename)
|
enable_service(servicename)
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import com.cloud.resource.ServerResource;
|
|||||||
|
|
||||||
@Local(value={ServerResource.class})
|
@Local(value={ServerResource.class})
|
||||||
public class DummyResource implements ServerResource {
|
public class DummyResource implements ServerResource {
|
||||||
|
private boolean _isRemoteAgent = false;
|
||||||
String _name;
|
String _name;
|
||||||
Host.Type _type;
|
Host.Type _type;
|
||||||
boolean _negative;
|
boolean _negative;
|
||||||
@ -101,4 +102,12 @@ public class DummyResource implements ServerResource {
|
|||||||
public void setAgentControl(IAgentControl agentControl) {
|
public void setAgentControl(IAgentControl agentControl) {
|
||||||
_agentControl = agentControl;
|
_agentControl = agentControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean IsRemoteAgent() {
|
||||||
|
return _isRemoteAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoteAgent(boolean remote) {
|
||||||
|
_isRemoteAgent = remote;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -149,7 +149,7 @@
|
|||||||
|
|
||||||
<adapters key="com.cloud.resource.Discoverer">
|
<adapters key="com.cloud.resource.Discoverer">
|
||||||
<adapter name="SecondaryStorage" class="com.cloud.storage.secondary.SecondaryStorageDiscoverer"/>
|
<adapter name="SecondaryStorage" class="com.cloud.storage.secondary.SecondaryStorageDiscoverer"/>
|
||||||
<adapter name="XenServer" class="com.cloud.hypervisor.xen.discoverer.XcpServerDiscoverer"/>
|
<adapter name="KVM Agent" class="com.cloud.hypervisor.kvm.discoverer.KvmServerDiscoverer"/>
|
||||||
</adapters>
|
</adapters>
|
||||||
|
|
||||||
<manager name="Cluster Manager" class="com.cloud.cluster.DummyClusterManagerImpl">
|
<manager name="Cluster Manager" class="com.cloud.cluster.DummyClusterManagerImpl">
|
||||||
|
|||||||
@ -14,6 +14,7 @@ for pythonpath in (
|
|||||||
if os.path.isdir(pythonpath): sys.path.insert(0,pythonpath)
|
if os.path.isdir(pythonpath): sys.path.insert(0,pythonpath)
|
||||||
# ---- End snippet of code ----
|
# ---- End snippet of code ----
|
||||||
import cloud_utils
|
import cloud_utils
|
||||||
|
from cloud_utils import stderr
|
||||||
|
|
||||||
E_GENERIC= 1
|
E_GENERIC= 1
|
||||||
E_NOKVM = 2
|
E_NOKVM = 2
|
||||||
@ -27,13 +28,6 @@ E_CPRECONFIGFAILED = 9
|
|||||||
E_CPFAILEDTOSTART = 10
|
E_CPFAILEDTOSTART = 10
|
||||||
E_NOFQDN = 11
|
E_NOFQDN = 11
|
||||||
|
|
||||||
|
|
||||||
def stderr(msgfmt,*args):
|
|
||||||
msgfmt += "\n"
|
|
||||||
if args: sys.stderr.write(msgfmt%args)
|
|
||||||
else: sys.stderr.write(msgfmt)
|
|
||||||
sys.stderr.flush()
|
|
||||||
|
|
||||||
def bail(errno=E_GENERIC,message=None,*args):
|
def bail(errno=E_GENERIC,message=None,*args):
|
||||||
if message: stderr(message,*args)
|
if message: stderr(message,*args)
|
||||||
stderr("Cloud Console Proxy setup aborted")
|
stderr("Cloud Console Proxy setup aborted")
|
||||||
@ -133,10 +127,11 @@ CentOS = os.path.exists("/etc/centos-release") or ( os.path.exists("/etc/redhat-
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
# parse cmd line
|
# parse cmd line
|
||||||
opts, args = getopt.getopt(sys.argv[1:], "", ["host=", "zone=", "pod="])
|
opts, args = getopt.getopt(sys.argv[1:], "a", ["host=", "zone=", "pod="])
|
||||||
host=None
|
host=None
|
||||||
zone=None
|
zone=None
|
||||||
pod=None
|
pod=None
|
||||||
|
autoMode=False
|
||||||
do_check_kvm = True
|
do_check_kvm = True
|
||||||
for opt, arg in opts:
|
for opt, arg in opts:
|
||||||
if opt == "--host":
|
if opt == "--host":
|
||||||
@ -148,8 +143,13 @@ def main():
|
|||||||
elif opt == "--pod":
|
elif opt == "--pod":
|
||||||
if arg != "":
|
if arg != "":
|
||||||
pod = arg
|
pod = arg
|
||||||
|
elif opt == "-a":
|
||||||
|
autoMode=True
|
||||||
servicename = "@PACKAGE@-console-proxy"
|
servicename = "@PACKAGE@-console-proxy"
|
||||||
|
|
||||||
|
if autoMode:
|
||||||
|
cloud_utils.setLogFile("/var/log/cloud/setupConsoleProxy.log")
|
||||||
|
|
||||||
stderr("Welcome to the Cloud Console Proxy setup")
|
stderr("Welcome to the Cloud Console Proxy setup")
|
||||||
stderr("")
|
stderr("")
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,70 @@
|
|||||||
|
package com.cloud.hypervisor.kvm.resource;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
import com.cloud.agent.api.Answer;
|
||||||
|
import com.cloud.agent.api.Command;
|
||||||
|
import com.cloud.agent.api.PingCommand;
|
||||||
|
import com.cloud.agent.api.StartupCommand;
|
||||||
|
import com.cloud.agent.api.StartupRoutingCommand;
|
||||||
|
import com.cloud.host.Host.Type;
|
||||||
|
import com.cloud.hypervisor.Hypervisor;
|
||||||
|
import com.cloud.hypervisor.xen.resource.CitrixResourceBase;
|
||||||
|
import com.cloud.resource.ServerResource;
|
||||||
|
import com.cloud.resource.ServerResourceBase;
|
||||||
|
import com.cloud.vm.State;
|
||||||
|
|
||||||
|
public class KvmDummyResourceBase extends ServerResourceBase implements ServerResource {
|
||||||
|
private String _zoneId;
|
||||||
|
private String _podId;
|
||||||
|
private String _guid;
|
||||||
|
private String _agentIp;
|
||||||
|
@Override
|
||||||
|
public Type getType() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StartupCommand[] initialize() {
|
||||||
|
StartupRoutingCommand cmd = new StartupRoutingCommand(0, 0, 0, 0, null, Hypervisor.Type.KVM, new HashMap<String, String>(), new HashMap<String, State>());
|
||||||
|
cmd.setDataCenter(_zoneId);
|
||||||
|
cmd.setPod(_podId);
|
||||||
|
cmd.setGuid(_guid);
|
||||||
|
cmd.setName(_agentIp);
|
||||||
|
cmd.setPrivateIpAddress(_agentIp);
|
||||||
|
cmd.setStorageIpAddress(_agentIp);
|
||||||
|
cmd.setVersion(KvmDummyResourceBase.class.getPackage().getImplementationVersion());
|
||||||
|
return new StartupCommand[] { cmd };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PingCommand getCurrentStatus(long id) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Answer executeRequest(Command cmd) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getDefaultScriptsDir() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
|
||||||
|
_zoneId = (String)params.get("zone");
|
||||||
|
_podId = (String)params.get("pod");
|
||||||
|
_guid = (String)params.get("guid");
|
||||||
|
_agentIp = (String)params.get("agentIp");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -23,7 +23,7 @@ import com.cloud.resource.ServerResource;
|
|||||||
import com.cloud.storage.resource.StoragePoolResource;
|
import com.cloud.storage.resource.StoragePoolResource;
|
||||||
|
|
||||||
public class VmwareResource implements StoragePoolResource, ServerResource {
|
public class VmwareResource implements StoragePoolResource, ServerResource {
|
||||||
|
private boolean _isRemoteAgent = false;
|
||||||
@Override
|
@Override
|
||||||
public DownloadAnswer execute(PrimaryStorageDownloadCommand cmd) {
|
public DownloadAnswer execute(PrimaryStorageDownloadCommand cmd) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
@ -119,4 +119,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource {
|
|||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean IsRemoteAgent() {
|
||||||
|
return _isRemoteAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoteAgent(boolean remote) {
|
||||||
|
_isRemoteAgent = remote;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -223,6 +223,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
|
|||||||
protected String _guestNetworkName;
|
protected String _guestNetworkName;
|
||||||
protected int _wait;
|
protected int _wait;
|
||||||
protected IAgentControl _agentControl;
|
protected IAgentControl _agentControl;
|
||||||
|
protected boolean _isRemoteAgent = false;
|
||||||
|
|
||||||
protected final XenServerHost _host = new XenServerHost();
|
protected final XenServerHost _host = new XenServerHost();
|
||||||
|
|
||||||
@ -6072,6 +6073,13 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
|
|||||||
_agentControl = agentControl;
|
_agentControl = agentControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean IsRemoteAgent() {
|
||||||
|
return _isRemoteAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoteAgent(boolean remote) {
|
||||||
|
_isRemoteAgent = remote;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected Answer execute(PoolEjectCommand cmd) {
|
protected Answer execute(PoolEjectCommand cmd) {
|
||||||
|
|||||||
@ -71,4 +71,8 @@ public interface ServerResource extends Manager {
|
|||||||
public IAgentControl getAgentControl();
|
public IAgentControl getAgentControl();
|
||||||
|
|
||||||
public void setAgentControl(IAgentControl agentControl);
|
public void setAgentControl(IAgentControl agentControl);
|
||||||
|
|
||||||
|
public boolean IsRemoteAgent();
|
||||||
|
|
||||||
|
public void setRemoteAgent(boolean remote);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,6 +48,7 @@ public abstract class ServerResourceBase implements ServerResource {
|
|||||||
protected NetworkInterface _storageNic;
|
protected NetworkInterface _storageNic;
|
||||||
protected NetworkInterface _storageNic2;
|
protected NetworkInterface _storageNic2;
|
||||||
protected IAgentControl _agentControl;
|
protected IAgentControl _agentControl;
|
||||||
|
protected boolean _isRemoteAgent = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@ -301,4 +302,12 @@ public abstract class ServerResourceBase implements ServerResource {
|
|||||||
public boolean stop() {
|
public boolean stop() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean IsRemoteAgent() {
|
||||||
|
return _isRemoteAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoteAgent(boolean remote) {
|
||||||
|
_isRemoteAgent = remote;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,9 +45,11 @@ elif os.path.exists("/etc/redhat-release") and not os.path.exists("/etc/fedora-r
|
|||||||
elif os.path.exists("/etc/legal") and "Ubuntu" in file("/etc/legal").read(-1): distro = Ubuntu
|
elif os.path.exists("/etc/legal") and "Ubuntu" in file("/etc/legal").read(-1): distro = Ubuntu
|
||||||
else: distro = Unknown
|
else: distro = Unknown
|
||||||
|
|
||||||
|
logFileName=None
|
||||||
# ================== LIBRARY UTILITY CODE=============
|
# ================== LIBRARY UTILITY CODE=============
|
||||||
|
def setLogFile(logFile):
|
||||||
|
global logFileName
|
||||||
|
logFileName=logFile
|
||||||
def read_properties(propfile):
|
def read_properties(propfile):
|
||||||
if not hasattr(propfile,"read"): propfile = file(propfile)
|
if not hasattr(propfile,"read"): propfile = file(propfile)
|
||||||
properties = propfile.read().splitlines()
|
properties = propfile.read().splitlines()
|
||||||
@ -63,9 +65,10 @@ def read_properties(propfile):
|
|||||||
def stderr(msgfmt,*args):
|
def stderr(msgfmt,*args):
|
||||||
"""Print a message to stderr, optionally interpolating the arguments into it"""
|
"""Print a message to stderr, optionally interpolating the arguments into it"""
|
||||||
msgfmt += "\n"
|
msgfmt += "\n"
|
||||||
|
if logFileName != None:
|
||||||
|
sys.stderr = open(logFileName, 'a+')
|
||||||
if args: sys.stderr.write(msgfmt%args)
|
if args: sys.stderr.write(msgfmt%args)
|
||||||
else: sys.stderr.write(msgfmt)
|
else: sys.stderr.write(msgfmt)
|
||||||
sys.stderr.flush()
|
|
||||||
|
|
||||||
def exit(errno=E_GENERIC,message=None,*args):
|
def exit(errno=E_GENERIC,message=None,*args):
|
||||||
"""Exit with an error status code, printing a message to stderr if specified"""
|
"""Exit with an error status code, printing a message to stderr if specified"""
|
||||||
@ -907,7 +910,7 @@ def prompt_for_hostpods(zonespods):
|
|||||||
|
|
||||||
# this configures the agent
|
# this configures the agent
|
||||||
|
|
||||||
def setup_agent_config(configfile, host, zone, pod):
|
def setup_agent_config(configfile, host, zone, pod, guid):
|
||||||
stderr("Examining Agent configuration")
|
stderr("Examining Agent configuration")
|
||||||
fn = configfile
|
fn = configfile
|
||||||
text = file(fn).read(-1)
|
text = file(fn).read(-1)
|
||||||
@ -915,6 +918,9 @@ def setup_agent_config(configfile, host, zone, pod):
|
|||||||
confopts = dict([ m.split("=",1) for m in lines if "=" in m and not m.startswith("#") ])
|
confopts = dict([ m.split("=",1) for m in lines if "=" in m and not m.startswith("#") ])
|
||||||
confposes = dict([ (m.split("=",1)[0],n) for n,m in enumerate(lines) if "=" in m and not m.startswith("#") ])
|
confposes = dict([ (m.split("=",1)[0],n) for n,m in enumerate(lines) if "=" in m and not m.startswith("#") ])
|
||||||
|
|
||||||
|
if guid != None:
|
||||||
|
confopts['guid'] = guid
|
||||||
|
else:
|
||||||
if not "guid" in confopts:
|
if not "guid" in confopts:
|
||||||
stderr("Generating GUID for this Agent")
|
stderr("Generating GUID for this Agent")
|
||||||
confopts['guid'] = uuidgen().stdout.strip()
|
confopts['guid'] = uuidgen().stdout.strip()
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
# Did cloud-agent installed
|
# Did cloud-agent installed
|
||||||
set -x
|
#set -x
|
||||||
install_cloud_agent() {
|
install_cloud_agent() {
|
||||||
local dev=$1
|
local dev=$1
|
||||||
local retry=10
|
local retry=10
|
||||||
@ -126,6 +126,7 @@ cloud_agent_setup() {
|
|||||||
local host=$1
|
local host=$1
|
||||||
local zone=$2
|
local zone=$2
|
||||||
local pod=$3
|
local pod=$3
|
||||||
|
local guid=$4
|
||||||
# disable selinux
|
# disable selinux
|
||||||
selenabled=`cat /selinux/enforce`
|
selenabled=`cat /selinux/enforce`
|
||||||
if [ "$selenabled" == "1" ]
|
if [ "$selenabled" == "1" ]
|
||||||
@ -133,21 +134,22 @@ cloud_agent_setup() {
|
|||||||
sed -i 's/\(SELINUX\)\(.*\)/\1=permissive/' /etc/selinux/config
|
sed -i 's/\(SELINUX\)\(.*\)/\1=permissive/' /etc/selinux/config
|
||||||
setenforce 0
|
setenforce 0
|
||||||
fi
|
fi
|
||||||
cloud-setup-agent --host=$host --zone=$zone --pod=$pod -a
|
cloud-setup-agent --host=$host --zone=$zone --pod=$pod --guid=$guid -a > /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
cloud_consoleP_setup() {
|
cloud_consoleP_setup() {
|
||||||
local host=$1
|
local host=$1
|
||||||
local zone=$2
|
local zone=$2
|
||||||
local pod=$3
|
local pod=$3
|
||||||
cloud-setup-console-proxy --host=$host --zone=$zone --pod=$pod
|
cloud-setup-console-proxy --host=$host --zone=$zone --pod=$pod -a > /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
host=
|
host=
|
||||||
zone=
|
zone=
|
||||||
pod=
|
pod=
|
||||||
|
guid=
|
||||||
dflag=
|
dflag=
|
||||||
while getopts 'h:z:p:d' OPTION
|
while getopts 'h:z:p:u:d' OPTION
|
||||||
do
|
do
|
||||||
case $OPTION in
|
case $OPTION in
|
||||||
h)
|
h)
|
||||||
@ -159,6 +161,9 @@ do
|
|||||||
p)
|
p)
|
||||||
pod="$OPTARG"
|
pod="$OPTARG"
|
||||||
;;
|
;;
|
||||||
|
u)
|
||||||
|
guid="$OPTARG"
|
||||||
|
;;
|
||||||
d)
|
d)
|
||||||
dflag=1
|
dflag=1
|
||||||
;;
|
;;
|
||||||
@ -166,7 +171,7 @@ do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
install_cloud_agent $dflag
|
#install_cloud_agent $dflag
|
||||||
install_cloud_consoleP $dflag
|
#install_cloud_consoleP $dflag
|
||||||
cloud_agent_setup $host $zone $pod
|
cloud_agent_setup $host $zone $pod $guid
|
||||||
cloud_consoleP_setup $host $zone $pod
|
cloud_consoleP_setup $host $zone $pod
|
||||||
|
|||||||
@ -20,5 +20,6 @@
|
|||||||
<classpathentry kind="lib" path="/thirdparty/commons-codec-1.4.jar"/>
|
<classpathentry kind="lib" path="/thirdparty/commons-codec-1.4.jar"/>
|
||||||
<classpathentry kind="lib" path="/thirdparty/servlet-api.jar"/>
|
<classpathentry kind="lib" path="/thirdparty/servlet-api.jar"/>
|
||||||
<classpathentry combineaccessrules="false" kind="src" path="/api"/>
|
<classpathentry combineaccessrules="false" kind="src" path="/api"/>
|
||||||
|
<classpathentry kind="lib" path="/thirdparty/trilead-ssh2-build213.jar"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|||||||
@ -100,6 +100,7 @@ import com.cloud.host.Status.Event;
|
|||||||
import com.cloud.host.dao.DetailsDao;
|
import com.cloud.host.dao.DetailsDao;
|
||||||
import com.cloud.host.dao.HostDao;
|
import com.cloud.host.dao.HostDao;
|
||||||
import com.cloud.hypervisor.Hypervisor;
|
import com.cloud.hypervisor.Hypervisor;
|
||||||
|
import com.cloud.hypervisor.kvm.resource.KvmDummyResourceBase;
|
||||||
import com.cloud.maid.StackMaid;
|
import com.cloud.maid.StackMaid;
|
||||||
import com.cloud.maint.UpgradeManager;
|
import com.cloud.maint.UpgradeManager;
|
||||||
import com.cloud.network.IPAddressVO;
|
import com.cloud.network.IPAddressVO;
|
||||||
@ -464,6 +465,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory {
|
|||||||
long id = server.getId();
|
long id = server.getId();
|
||||||
|
|
||||||
AgentAttache attache = createAttache(id, server, resource);
|
AgentAttache attache = createAttache(id, server, resource);
|
||||||
|
if (!resource.IsRemoteAgent())
|
||||||
notifyMonitorsOfConnection(attache, startup);
|
notifyMonitorsOfConnection(attache, startup);
|
||||||
return attache;
|
return attache;
|
||||||
}
|
}
|
||||||
@ -1550,7 +1552,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory {
|
|||||||
|
|
||||||
protected AgentAttache createAttache(long id, HostVO server, ServerResource resource) {
|
protected AgentAttache createAttache(long id, HostVO server, ServerResource resource) {
|
||||||
s_logger.debug("Adding directly connect host for " + id);
|
s_logger.debug("Adding directly connect host for " + id);
|
||||||
if (resource instanceof DummySecondaryStorageResource) {
|
if (resource instanceof DummySecondaryStorageResource || resource instanceof KvmDummyResourceBase) {
|
||||||
return new DummyAttache(id, false);
|
return new DummyAttache(id, false);
|
||||||
}
|
}
|
||||||
final DirectAgentAttache attache = new DirectAgentAttache(id, resource, server.getStatus() == Status.Maintenance
|
final DirectAgentAttache attache = new DirectAgentAttache(id, resource, server.getStatus() == Status.Maintenance
|
||||||
|
|||||||
@ -1,8 +1,16 @@
|
|||||||
package com.cloud.hypervisor.kvm.discoverer;
|
package com.cloud.hypervisor.kvm.discoverer;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.ejb.Local;
|
||||||
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.agent.Listener;
|
import com.cloud.agent.Listener;
|
||||||
import com.cloud.agent.api.AgentControlAnswer;
|
import com.cloud.agent.api.AgentControlAnswer;
|
||||||
@ -10,15 +18,31 @@ import com.cloud.agent.api.AgentControlCommand;
|
|||||||
import com.cloud.agent.api.Answer;
|
import com.cloud.agent.api.Answer;
|
||||||
import com.cloud.agent.api.Command;
|
import com.cloud.agent.api.Command;
|
||||||
import com.cloud.agent.api.StartupCommand;
|
import com.cloud.agent.api.StartupCommand;
|
||||||
|
import com.cloud.configuration.dao.ConfigurationDao;
|
||||||
import com.cloud.exception.DiscoveryException;
|
import com.cloud.exception.DiscoveryException;
|
||||||
import com.cloud.host.HostVO;
|
import com.cloud.host.HostVO;
|
||||||
import com.cloud.host.Status;
|
import com.cloud.host.Status;
|
||||||
|
import com.cloud.host.dao.HostDao;
|
||||||
|
import com.cloud.hypervisor.kvm.resource.KvmDummyResourceBase;
|
||||||
|
import com.cloud.hypervisor.xen.resource.CitrixResourceBase;
|
||||||
import com.cloud.resource.Discoverer;
|
import com.cloud.resource.Discoverer;
|
||||||
import com.cloud.resource.DiscovererBase;
|
import com.cloud.resource.DiscovererBase;
|
||||||
import com.cloud.resource.ServerResource;
|
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.SCPClient;
|
||||||
|
import com.trilead.ssh2.Session;
|
||||||
|
|
||||||
|
@Local(value=Discoverer.class)
|
||||||
public class KvmServerDiscoverer extends DiscovererBase implements Discoverer,
|
public class KvmServerDiscoverer extends DiscovererBase implements Discoverer,
|
||||||
Listener {
|
Listener {
|
||||||
|
private static final Logger s_logger = Logger.getLogger(KvmServerDiscoverer.class);
|
||||||
|
private String _setupAgentPath;
|
||||||
|
private ConfigurationDao _configDao;
|
||||||
|
private String _hostIp;
|
||||||
|
private int _waitTime = 10;
|
||||||
|
@Inject HostDao _hostDao = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean processAnswer(long agentId, long seq, Answer[] answers) {
|
public boolean processAnswer(long agentId, long seq, Answer[] answers) {
|
||||||
@ -73,14 +97,101 @@ public class KvmServerDiscoverer extends DiscovererBase implements Discoverer,
|
|||||||
public Map<? extends ServerResource, Map<String, String>> find(long dcId,
|
public Map<? extends ServerResource, Map<String, String>> find(long dcId,
|
||||||
Long podId, Long clusterId, URI uri, String username,
|
Long podId, Long clusterId, URI uri, String username,
|
||||||
String password) throws DiscoveryException {
|
String password) throws DiscoveryException {
|
||||||
// TODO Auto-generated method stub
|
Map<KvmDummyResourceBase, Map<String, String>> resources = new HashMap<KvmDummyResourceBase, Map<String, String>>();
|
||||||
|
Map<String, String> details = new HashMap<String, String>();
|
||||||
|
if (!uri.getScheme().equals("http")) {
|
||||||
|
String msg = "urlString is not http 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 {
|
||||||
|
|
||||||
|
String hostname = uri.getHost();
|
||||||
|
InetAddress ia = InetAddress.getByName(hostname);
|
||||||
|
agentIp = ia.getHostAddress();
|
||||||
|
String guid = UUID.nameUUIDFromBytes(agentIp.getBytes()).toString();
|
||||||
|
sshConnection = new com.trilead.ssh2.Connection(agentIp, 22);
|
||||||
|
|
||||||
|
sshConnection.connect(null, 60000, 60000);
|
||||||
|
if (!sshConnection.authenticateWithPassword(username, password)) {
|
||||||
|
throw new Exception("Unable to authenticate");
|
||||||
|
}
|
||||||
|
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" );
|
||||||
|
|
||||||
|
KvmDummyResourceBase kvmResource = new KvmDummyResourceBase();
|
||||||
|
Map<String, Object> params = new HashMap<String, Object>();
|
||||||
|
|
||||||
|
params.put("zone", Long.toString(dcId));
|
||||||
|
params.put("pod", Long.toString(podId));
|
||||||
|
params.put("guid", guid);
|
||||||
|
params.put("agentIp", agentIp);
|
||||||
|
kvmResource.configure("kvm agent", params);
|
||||||
|
kvmResource.setRemoteAgent(true);
|
||||||
|
resources.put(kvmResource, details);
|
||||||
|
return resources;
|
||||||
|
} catch (Exception e) {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postDiscovery(List<HostVO> hosts, long msId) {
|
public void postDiscovery(List<HostVO> hosts, long msId) throws DiscoveryException {
|
||||||
// TODO Auto-generated method stub
|
/*Wait for agent coming back*/
|
||||||
|
if (hosts.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
HostVO host = hosts.get(0);
|
||||||
|
for (int i = 0 ; i < _waitTime; i++) {
|
||||||
|
|
||||||
|
if (host.getStatus() != Status.Up) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(60000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
s_logger.debug("Failed to sleep: " + e.toString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*Timeout, throw warning msg to user*/
|
||||||
|
throw new DiscoveryException("Agent " + host.getId() + ":" + host.getPublicIpAddress() + " does not come back, It may connect to server later, if not, please check the agent log");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||||
|
ComponentLocator locator = ComponentLocator.getCurrentLocator();
|
||||||
|
_configDao = locator.getDao(ConfigurationDao.class);
|
||||||
|
_setupAgentPath = Script.findScript(getPatchPath(), "setup_agent.sh");
|
||||||
|
|
||||||
|
if (_setupAgentPath == null) {
|
||||||
|
throw new ConfigurationException("Can't find setup_agent.sh");
|
||||||
|
}
|
||||||
|
_hostIp = _configDao.getValue("host");
|
||||||
|
if (_hostIp == null) {
|
||||||
|
throw new ConfigurationException("Can't get host IP");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getPatchPath() {
|
||||||
|
return "scripts/vm/hypervisor/kvm/";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -450,7 +450,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postDiscovery(List<HostVO> hosts, long msId) {
|
public void postDiscovery(List<HostVO> hosts, long msId) throws DiscoveryException{
|
||||||
//do nothing
|
//do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,5 +40,5 @@ public interface Discoverer extends Adapter {
|
|||||||
*/
|
*/
|
||||||
Map<? extends ServerResource, Map<String, String>> find(long dcId, Long podId, Long clusterId, URI uri, String username, String password) throws DiscoveryException;
|
Map<? extends ServerResource, Map<String, String>> find(long dcId, Long podId, Long clusterId, URI uri, String username, String password) throws DiscoveryException;
|
||||||
|
|
||||||
void postDiscovery(List<HostVO> hosts, long msId);
|
void postDiscovery(List<HostVO> hosts, long msId) throws DiscoveryException;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user