Bug 8208 - bare metal provisioning

able to start, stop, reboot, destroy VM
This commit is contained in:
Frank 2011-03-01 11:40:40 -08:00
parent cd676f481d
commit 35b7c26689
13 changed files with 111 additions and 21 deletions

View File

@ -30,6 +30,7 @@ import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
import com.cloud.uservm.UserVm;
@ -95,7 +96,13 @@ public class DestroyVMCmd extends BaseAsyncCmd {
@Override
public void execute() throws ResourceUnavailableException, ConcurrentOperationException{
UserContext.current().setEventDetails("Vm Id: "+getId());
UserVm result = _userVmService.destroyVm(this);
UserVm result;
if (_userVmService.getHypervisorTypeOfUserVM(getId()) == HypervisorType.BareMetal) {
result = _bareMetalVmService.destroyVm(this);
} else {
result = _userVmService.destroyVm(this);
}
if (result != null) {
UserVmResponse response = _responseGenerator.createUserVmResponse(result);
response.setResponseName("virtualmachine");

View File

@ -30,6 +30,7 @@ import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
import com.cloud.uservm.UserVm;
@ -94,7 +95,13 @@ public class RebootVMCmd extends BaseAsyncCmd {
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException{
UserContext.current().setEventDetails("Vm Id: "+getId());
UserVm result = _userVmService.rebootVirtualMachine(this);
UserVm result;
if (_userVmService.getHypervisorTypeOfUserVM(getId()) == HypervisorType.BareMetal) {
result = _bareMetalVmService.rebootVirtualMachine(this);
} else {
result = _userVmService.rebootVirtualMachine(this);
}
if (result !=null){
UserVmResponse response = _responseGenerator.createUserVmResponse(result);
response.setResponseName(getCommandName());

View File

@ -33,6 +33,7 @@ import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
import com.cloud.uservm.UserVm;
@ -104,7 +105,13 @@ public class StartVMCmd extends BaseAsyncCmd {
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException{
try {
UserContext.current().setEventDetails("Vm Id: "+getId());
UserVm result = _userVmService.startVirtualMachine(this);
UserVm result;
if (_userVmService.getHypervisorTypeOfUserVM(getId()) == HypervisorType.BareMetal) {
result = _bareMetalVmService.startVirtualMachine(this);
} else {
result = _userVmService.startVirtualMachine(this);
}
if (result != null){
UserVmResponse response = _responseGenerator.createUserVmResponse(result);
response.setResponseName(getCommandName());

View File

@ -29,6 +29,7 @@ import com.cloud.api.response.UserVmResponse;
import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
import com.cloud.uservm.UserVm;
@ -107,7 +108,14 @@ public class StopVMCmd extends BaseAsyncCmd {
@Override
public void execute() throws ServerApiException, ConcurrentOperationException{
UserContext.current().setEventDetails("Vm Id: "+getId());
UserVm result = _userVmService.stopVirtualMachine(getId(), isForced());
UserVm result;
if (_userVmService.getHypervisorTypeOfUserVM(getId()) == HypervisorType.BareMetal) {
result = _bareMetalVmService.stopVirtualMachine(getId(), isForced());
} else {
result = _userVmService.stopVirtualMachine(getId(), isForced());
}
if (result != null) {
UserVmResponse response = _responseGenerator.createUserVmResponse(result);
response.setResponseName(getCommandName());

View File

@ -42,6 +42,7 @@ import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.Volume;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.uservm.UserVm;
@ -170,4 +171,6 @@ public interface UserVmService {
* @return List of UserVMs.
*/
List<? extends UserVm> searchForUserVMs(ListVMsCmd cmd);
HypervisorType getHypervisorTypeOfUserVM(long vmid);
}

View File

@ -78,6 +78,7 @@ def ping(args):
print o.stderr
return 1
else:
print o.stdout
return 0
def boot_dev(args):
@ -117,7 +118,24 @@ def reboot(args):
else:
return 0
call_table = {"ping":ping, "boot_dev":boot_dev, "reboot":reboot}
def power(args):
hostname = args.get("hostname")
usrname = args.get("usrname")
password = args.get("password")
action = args.get("action")
if hostname == None:
print "No hostname"
return 1
o = ipmitool("-H", hostname, "-U", usrname, "-P", password, "chassis", "power", action)
if o.ret:
print o.stderr
return 1
else:
return 0
call_table = {"ping":ping, "boot_dev":boot_dev, "reboot":reboot, "power":power}
def dispatch(args):
cmd = args[1]
params = args[2:]

View File

@ -33,6 +33,9 @@ public class AddPxeServerCmd extends BaseCmd {
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required = true, description="Zone in which to add the external firewall appliance.")
private Long zoneId;
@Parameter(name=ApiConstants.POD_ID, type=CommandType.LONG, required = true, description="Zone in which to add the external firewall appliance.")
private Long podId;
@Parameter(name=ApiConstants.URL, type=CommandType.STRING, required = true, description="URL of the PXE server appliance.")
private String url;
@ -68,6 +71,10 @@ public class AddPxeServerCmd extends BaseCmd {
public String getType() {
return type;
}
public Long getPod() {
return podId;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////

View File

@ -37,18 +37,16 @@ public class LinMinPxeServerManagerImpl extends PxeServerManagerImpl implements
@Override
public Host addPxeServer(AddPxeServerCmd cmd) throws InvalidParameterValueException, CloudRuntimeException {
long zoneId = cmd.getZoneId();
Long podId = cmd.getPod();
DataCenterVO zone = _dcDao.findById(zoneId);
String zoneName;
if (zone == null) {
throw new InvalidParameterValueException("Could not find zone with ID: " + zoneId);
} else {
zoneName = zone.getName();
}
}
List<HostVO> pxeServers = _hostDao.listByTypeDataCenter(Host.Type.PxeServer, zoneId);
List<HostVO> pxeServers = _hostDao.listBy(Host.Type.PxeServer, null, podId, zoneId);
if (pxeServers.size() != 0) {
throw new InvalidParameterValueException("Already had a PXE server in zone: " + zoneName);
throw new InvalidParameterValueException("Already had a PXE server in Pod: " + podId + " zone: " + zoneId);
}
URI uri;
@ -65,10 +63,12 @@ public class LinMinPxeServerManagerImpl extends PxeServerManagerImpl implements
String guid = getPxeServerGuid(Long.toString(zoneId), PxeServerType.LinMin.getName(), ipAddress);
Map params = new HashMap<String, String>();
params.put("zone", Long.toString(zoneId));
params.put("pod", podId.toString());
params.put("ip", ipAddress);
params.put("username", username);
params.put("password", password);
params.put("guid", guid);
params.put("pod", Long.toString(cmd.getPod()));
ServerResource resource = null;
try {

View File

@ -48,6 +48,7 @@ public class LinMinPxeServerResource implements ServerResource {
String _password;
String _ip;
String _zoneId;
String _podId;
class XmlReturn {
NodeList nList;
@ -86,6 +87,7 @@ public class LinMinPxeServerResource implements ServerResource {
_username = (String)params.get("username");
_password = (String)params.get("password");
_zoneId = (String)params.get("zone");
_podId = (String)params.get("pod");
if (_guid == null) {
throw new ConfigurationException("No Guid specified");
@ -95,6 +97,10 @@ public class LinMinPxeServerResource implements ServerResource {
throw new ConfigurationException("No Zone specified");
}
if (_podId == null) {
throw new ConfigurationException("No Pod specified");
}
if (_ip == null) {
throw new ConfigurationException("No IP specified");
}
@ -157,7 +163,7 @@ public class LinMinPxeServerResource implements ServerResource {
StartupPxeServerCommand cmd = new StartupPxeServerCommand();
cmd.setName(_name);
cmd.setDataCenter(_zoneId);
cmd.setPod("");
cmd.setPod(_podId);
cmd.setPrivateIpAddress(_ip);
cmd.setStorageIpAddress("");
cmd.setVersion("");

View File

@ -16,6 +16,7 @@ import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.baremetal.PrepareLinMinPxeServerCommand;
import com.cloud.agent.manager.Commands;
import com.cloud.api.commands.AttachVolumeCmd;
@ -271,7 +272,9 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet
if (_itMgr.allocate(vm, template, offering, null, null, networks, null, plan, cmd.getHypervisor(), owner) == null) {
return null;
}
// startVirtualMachine() will retrieve this property
vm.setDetail("pxeboot", "true");
_vmDao.saveDetails(vm);
if (s_logger.isDebugEnabled()) {
@ -374,16 +377,12 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet
throw new PermissionDeniedException("The owner of " + vm + " either does not exist or is disabled: " + vm.getAccountId());
}
if (profile.getTemplate() == null) {
PxeServerType pxeType = (PxeServerType) profile.getParameter(Param.PxeSeverType);
if (pxeType == null) {
s_logger.debug("This is a normal IPMI start, skip prepartion of PXE server");
return true;
}
s_logger.debug("This is a PXE start, prepare PXE server first");
PxeServerType pxeType = (PxeServerType) profile.getParameter(Param.PxeSeverType);
if (pxeType == null) {
throw new CloudRuntimeException("No PXE type specified");
}
PxeServerManager pxeMgr = null;
ComponentLocator locator = ComponentLocator.getLocator(ManagementService.Name);
@ -445,4 +444,14 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet
return true;
}
@Override
public void finalizeStop(VirtualMachineProfile<UserVmVO> profile, StopAnswer answer) {
super.finalizeStop(profile, answer);
}
@Override
public UserVm destroyVm(long vmId) throws ResourceUnavailableException, ConcurrentOperationException {
return super.destroyVm(vmId);
}
}

View File

@ -2683,4 +2683,14 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
return _vmDao.search(sc, searchFilter);
}
@Override
public HypervisorType getHypervisorTypeOfUserVM(long vmid) {
UserVmVO userVm = _vmDao.findById(vmid);
if (userVm == null) {
throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmid);
}
return userVm.getHypervisorType();
}
}

View File

@ -841,8 +841,10 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
}
try {
_storageMgr.release(profile);
s_logger.debug("Successfully released storage resources for the vm " + vm);
if (vm.getHypervisorType() != HypervisorType.BareMetal) {
_storageMgr.release(profile);
s_logger.debug("Successfully released storage resources for the vm " + vm);
}
} catch (Exception e) {
s_logger.warn("Unable to release storage resources.", e);
}

View File

@ -154,6 +154,12 @@ public class Script implements Callable<String> {
return execute(new OutputInterpreter.OutputLogger(_logger));
}
@Override
public String toString() {
String[] command = _command.toArray(new String[_command.size()]);
return buildCommandLine(command);
}
public String execute(OutputInterpreter interpreter) {
String[] command = _command.toArray(new String[_command.size()]);