diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 62dd6cfaa51..d860962cf16 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -190,5 +190,7 @@ public class ApiConstants { public static final String IS_SYSTEM = "issystem"; public static final String AVAILABILITY = "availability"; public static final String NETWORKRATE = "networkrate"; + public static final String HOST_CPU_CAPACITY = "hostcpucapacity"; + public static final String HOST_MEM_CAPACITY = "hostmemcapacity"; } diff --git a/api/src/com/cloud/api/commands/AddHostCmd.java b/api/src/com/cloud/api/commands/AddHostCmd.java index e73eb037864..95802676c16 100644 --- a/api/src/com/cloud/api/commands/AddHostCmd.java +++ b/api/src/com/cloud/api/commands/AddHostCmd.java @@ -65,6 +65,14 @@ public class AddHostCmd extends BaseCmd { @Parameter(name=ApiConstants.HYPERVISOR, type=CommandType.STRING, required=true, description="hypervisor type of the host") private String hypervisor; + + @Parameter(name=ApiConstants.HOST_CPU_CAPACITY, type=CommandType.LONG, description="CPU capacity of host") + private Long cpuCapacity; + + @Parameter(name=ApiConstants.HOST_MEM_CAPACITY, type=CommandType.LONG, description="memory capacity of host") + private Long memCapacity; + + ///////////////////////////////////////////////////// @@ -103,6 +111,14 @@ public class AddHostCmd extends BaseCmd { return hypervisor; } + public Long getCpuCapacity() { + return cpuCapacity; + } + + public Long getMemCapacity() { + return memCapacity; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/com/cloud/hypervisor/Hypervisor.java b/api/src/com/cloud/hypervisor/Hypervisor.java index 8e3805ea93b..a759050c36a 100644 --- a/api/src/com/cloud/hypervisor/Hypervisor.java +++ b/api/src/com/cloud/hypervisor/Hypervisor.java @@ -27,6 +27,8 @@ public class Hypervisor { VMware, VirtualBox, Parralels, + BareMetal, + Any; /*If you don't care about the hypervisor type*/ public static HypervisorType getType(String hypervisor) { @@ -46,9 +48,11 @@ public class Hypervisor { return HypervisorType.VirtualBox; } else if (hypervisor.equalsIgnoreCase("Parralels")) { return HypervisorType.Parralels; + }else if (hypervisor.equalsIgnoreCase("BareMetal")) { + return HypervisorType.BareMetal; } else if (hypervisor.equalsIgnoreCase("Any")) { return HypervisorType.Any; - } else { + } else { return HypervisorType.None; } } diff --git a/scripts/util/ipmi.py b/scripts/util/ipmi.py new file mode 100644 index 00000000000..9fc4674a155 --- /dev/null +++ b/scripts/util/ipmi.py @@ -0,0 +1,109 @@ +#!/usr/bin/python + +import sys, os, subprocess, errno, re +from os.path import exists + +TOOl_PATH = "/usr/bin/ipmitool" + +try: + from subprocess import check_call + from subprocess import CalledProcessError +except ImportError: + def check_call(*popenargs, **kwargs): + import subprocess + retcode = subprocess.call(*popenargs, **kwargs) + cmd = kwargs.get("args") + if cmd is None: cmd = popenargs[0] + if retcode: raise CalledProcessError(retcode, cmd) + return retcode + + class CalledProcessError(Exception): + def __init__(self, returncode, cmd): + self.returncode = returncode ; self.cmd = cmd + def __str__(self): return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode) + +class Command: + def __init__(self,name,parent=None): + self.__name = name + self.__parent = parent + def __getattr__(self,name): + if name == "_print": name = "print" + return Command(name,self) + def __call__(self,*args): + class CommandOutput: + def __init__(self,ret,stdout,stderr): + self.stdout = stdout + self.stderr = stderr + self.ret = ret + + cmd = self.__get_recursive_name() + list(args) + #print " ",cmd + popen = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE) + m = popen.communicate() + ret = popen.wait() + return CommandOutput(ret,*m) + def __get_recursive_name(self,sep=None): + m = self + l = [] + while m is not None: + l.append(m.__name) + m = m.__parent + l.reverse() + if sep: return sep.join(l) + else: return l + def __str__(self): + return ''%self.__get_recursive_name(sep=" ") + + def __repr__(self): return self.__str__() + + +ipmitool = Command("ipmitool") + +def check_tool(): + if exists(TOOl_PATH) == False: + print "Can not find ipmitool" + return False + +def ping(args): + hostname = args.get("hostname") + usrname = args.get("usrname") + password = args.get("password") + + if hostname == None: + print "No hostname" + return 1 + + o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "power", "status") + if o.ret: + print o.stderr + return 1 + else: + return 0 + +call_table = {"ping":ping} +def dispatch(args): + cmd = args[1] + params = args[2:] + func_params = {} + + if call_table.has_key(cmd) == False: + print "No function %s" % cmd + return 1 + + for p in params: + pairs = p.split("=") + if len(pairs) != 2: + print "Invalid parameter %s" % p + return 1 + func_params[pairs[0]] = pairs[1] + + func = call_table[cmd] + return func(func_params) + +if __name__ == "__main__": + if check_tool() == False: + sys.exit(1) + if len(sys.argv) < 2: + print "Not enough arguments, at least one" + sys.exit(1) + sys.exit(dispatch(sys.argv)) diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index 0a18d6e44c0..41caf97c5bf 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -749,12 +749,30 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, String url = cmd.getUrl(); String username = cmd.getUsername(); String password = cmd.getPassword(); + Long memCapacity = cmd.getMemCapacity(); + Long cpuCapacity = cmd.getCpuCapacity(); + MapbareMetalParams = new HashMap(); + // this is for standalone option if (clusterName == null && clusterId == null) { clusterName = "Standalone-" + url; } - return discoverHosts(dcId, podId, clusterId, clusterName, url, - username, password, cmd.getHypervisor()); + + if (cmd.getHypervisor().equalsIgnoreCase(Hypervisor.HypervisorType.BareMetal.toString())) { + if (memCapacity == null) { + memCapacity = Long.valueOf(0); + } + if (cpuCapacity == null) { + cpuCapacity = Long.valueOf(0); + } + + bareMetalParams.put("cpuCapacity", cpuCapacity.toString()); + bareMetalParams.put("memCapacity", memCapacity.toString()); + } + + + return discoverHostsFull(dcId, podId, clusterId, clusterName, url, + username, password, cmd.getHypervisor(), bareMetalParams); } @Override @@ -772,6 +790,14 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, String clusterName, String url, String username, String password, String hypervisorType) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException { + return discoverHostsFull(dcId, podId, clusterId, clusterName, url, username, password, hypervisorType, null); + } + + + private List discoverHostsFull(Long dcId, Long podId, Long clusterId, + String clusterName, String url, String username, String password, + String hypervisorType, Mapparams) throws IllegalArgumentException, + DiscoveryException, InvalidParameterValueException { URI uri = null; // Check if the zone exists in the system @@ -865,6 +891,8 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, boolean isHypervisorTypeSupported = false; while (en.hasMoreElements()) { Discoverer discoverer = en.nextElement(); + discoverer.putParam(params); + if (!discoverer.matchHypervisor(hypervisorType)) { continue; } diff --git a/server/src/com/cloud/resource/Discoverer.java b/server/src/com/cloud/resource/Discoverer.java index eba1aaf7c61..8d92a47d44e 100644 --- a/server/src/com/cloud/resource/Discoverer.java +++ b/server/src/com/cloud/resource/Discoverer.java @@ -45,4 +45,5 @@ public interface Discoverer extends Adapter { boolean matchHypervisor(String hypervisor); Hypervisor.HypervisorType getHypervisorType(); + public void putParam(Map params); } diff --git a/server/src/com/cloud/resource/DiscovererBase.java b/server/src/com/cloud/resource/DiscovererBase.java index 77678c53f91..5681635cf83 100644 --- a/server/src/com/cloud/resource/DiscovererBase.java +++ b/server/src/com/cloud/resource/DiscovererBase.java @@ -44,6 +44,11 @@ public abstract class DiscovererBase implements Discoverer { return null; } + + @Override + public void putParam(Map params) { + _params.putAll(params); + } @Override public String getName() {