mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-6278
Baremetal Advanced Networking support
This commit is contained in:
parent
5fdc8b403d
commit
66fff6c574
@ -30,6 +30,7 @@ import java.util.Map;
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.network.Network;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.AddBaremetalPxeCmd;
|
||||
@ -83,7 +84,7 @@ public class BareMetalPingServiceImpl extends BareMetalPxeServiceBase implements
|
||||
BaremetalPxeDao _pxeDao;
|
||||
|
||||
@Override
|
||||
public boolean prepare(VirtualMachineProfile profile, NicProfile pxeNic, DeployDestination dest, ReservationContext context) {
|
||||
public boolean prepare(VirtualMachineProfile profile, NicProfile pxeNic, Network network, DeployDestination dest, ReservationContext context) {
|
||||
QueryBuilder<BaremetalPxeVO> sc = QueryBuilder.create(BaremetalPxeVO.class);
|
||||
sc.and(sc.entity().getDeviceType(), Op.EQ, BaremetalPxeType.PING.toString());
|
||||
sc.and(sc.entity().getPodId(), Op.EQ, dest.getPod().getId());
|
||||
|
||||
@ -20,6 +20,7 @@ package com.cloud.baremetal.networkservice;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -27,6 +28,18 @@ import java.util.Map;
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.OperationTimedoutException;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.guru.ControlNetworkGuru;
|
||||
import com.cloud.network.guru.NetworkGuru;
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.AddBaremetalKickStartPxeCmd;
|
||||
@ -62,6 +75,8 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.ReservationContext;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
@Local(value = BaremetalPxeService.class)
|
||||
public class BaremetalKickStartServiceImpl extends BareMetalPxeServiceBase implements BaremetalPxeService {
|
||||
@ -80,20 +95,31 @@ public class BaremetalKickStartServiceImpl extends BareMetalPxeServiceBase imple
|
||||
NetworkDao _nwDao;
|
||||
@Inject
|
||||
VMTemplateDao _tmpDao;
|
||||
@Inject
|
||||
DomainRouterDao _routerDao;
|
||||
@Inject
|
||||
NicDao _nicDao;
|
||||
|
||||
@Override
|
||||
public boolean prepare(VirtualMachineProfile profile, NicProfile nic, DeployDestination dest, ReservationContext context) {
|
||||
NetworkVO nwVO = _nwDao.findById(nic.getNetworkId());
|
||||
QueryBuilder<BaremetalPxeVO> sc = QueryBuilder.create(BaremetalPxeVO.class);
|
||||
sc.and(sc.entity().getDeviceType(), Op.EQ, BaremetalPxeType.KICK_START.toString());
|
||||
sc.and(sc.entity().getPhysicalNetworkId(), Op.EQ, nwVO.getPhysicalNetworkId());
|
||||
BaremetalPxeVO pxeVo = sc.find();
|
||||
if (pxeVo == null) {
|
||||
throw new CloudRuntimeException("No kickstart PXE server found in pod: " + dest.getPod().getId() + ", you need to add it before starting VM");
|
||||
private DomainRouterVO getVirtualRouter(Network network) {
|
||||
List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER);
|
||||
|
||||
if (routers.isEmpty()) {
|
||||
throw new CloudRuntimeException(String.format("cannot find any running virtual router on network[id:%s, uuid:%s]", network.getId(), network.getUuid()));
|
||||
}
|
||||
VMTemplateVO template = _tmpDao.findById(profile.getTemplateId());
|
||||
|
||||
try {
|
||||
if (routers.size() > 1) {
|
||||
throw new CloudRuntimeException(String.format("baremetal hasn't supported redundant router yet"));
|
||||
}
|
||||
|
||||
DomainRouterVO vr = routers.get(0);
|
||||
if (!Hypervisor.HypervisorType.VMware.equals(vr.getHypervisorType())) {
|
||||
throw new CloudRuntimeException(String.format("baremetal only support vmware virtual router, but get %s", vr.getHypervisorType()));
|
||||
}
|
||||
|
||||
return vr;
|
||||
}
|
||||
|
||||
private List<String> parseKickstartUrl(VirtualMachineProfile profile) {
|
||||
String tpl = profile.getTemplate().getUrl();
|
||||
assert tpl != null : "How can a null template get here!!!";
|
||||
String[] tpls = tpl.split(";");
|
||||
@ -126,6 +152,25 @@ public class BaremetalKickStartServiceImpl extends BareMetalPxeServiceBase imple
|
||||
}
|
||||
}
|
||||
|
||||
return Arrays.asList(ks, kernel, initrd);
|
||||
}
|
||||
|
||||
private boolean preparePxeInBasicZone(VirtualMachineProfile profile, NicProfile nic, DeployDestination dest, ReservationContext context) throws AgentUnavailableException, OperationTimedoutException {
|
||||
NetworkVO nwVO = _nwDao.findById(nic.getNetworkId());
|
||||
QueryBuilder<BaremetalPxeVO> sc = QueryBuilder.create(BaremetalPxeVO.class);
|
||||
sc.and(sc.entity().getDeviceType(), Op.EQ, BaremetalPxeType.KICK_START.toString());
|
||||
sc.and(sc.entity().getPhysicalNetworkId(), Op.EQ, nwVO.getPhysicalNetworkId());
|
||||
BaremetalPxeVO pxeVo = sc.find();
|
||||
if (pxeVo == null) {
|
||||
throw new CloudRuntimeException("No kickstart PXE server found in pod: " + dest.getPod().getId() + ", you need to add it before starting VM");
|
||||
}
|
||||
VMTemplateVO template = _tmpDao.findById(profile.getTemplateId());
|
||||
List<String> tuple = parseKickstartUrl(profile);
|
||||
|
||||
String ks = tuple.get(0);
|
||||
String kernel = tuple.get(1);
|
||||
String initrd = tuple.get(2);
|
||||
|
||||
PrepareKickstartPxeServerCommand cmd = new PrepareKickstartPxeServerCommand();
|
||||
cmd.setKsFile(ks);
|
||||
cmd.setInitrd(initrd);
|
||||
@ -135,11 +180,66 @@ public class BaremetalKickStartServiceImpl extends BareMetalPxeServiceBase imple
|
||||
Answer aws = _agentMgr.send(pxeVo.getHostId(), cmd);
|
||||
if (!aws.getResult()) {
|
||||
s_logger.warn("Unable to set host: " + dest.getHost().getId() + " to PXE boot because " + aws.getDetails());
|
||||
return aws.getResult();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private URI buildUrl(String mgmtIp, String subPath) {
|
||||
UriComponentsBuilder ub = UriComponentsBuilder.newInstance();
|
||||
ub.scheme("http");
|
||||
ub.scheme(mgmtIp);
|
||||
ub.port(10086);
|
||||
ub.path(subPath);
|
||||
return ub.build().toUri();
|
||||
}
|
||||
|
||||
private boolean preparePxeInAdvancedZone(VirtualMachineProfile profile, NicProfile nic, Network network, DeployDestination dest, ReservationContext context) {
|
||||
DomainRouterVO vr = getVirtualRouter(network);
|
||||
List<NicVO> nics = _nicDao.listByVmId(vr.getId());
|
||||
NicVO mgmtNic = null;
|
||||
for (NicVO nicvo : nics) {
|
||||
if (ControlNetworkGuru.class.getSimpleName().equals(nicvo.getReserver())) {
|
||||
mgmtNic = nicvo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mgmtNic == null) {
|
||||
throw new CloudRuntimeException(String.format("cannot find management nic on virutal router[id:%s]", vr.getId()));
|
||||
}
|
||||
|
||||
BaremetalVritualRouterCommands.PreparePxeCmd cmd = new BaremetalVritualRouterCommands.PreparePxeCmd();
|
||||
List<String> tuple = parseKickstartUrl(profile);
|
||||
cmd.setKickStartUrl(tuple.get(0));
|
||||
cmd.setKernelUrl(tuple.get(1));
|
||||
cmd.setInitrdUrl(tuple.get(2));
|
||||
cmd.setGuestMac(nic.getMacAddress());
|
||||
RestTemplate rst = new RestTemplate();
|
||||
BaremetalVritualRouterCommands.PreparePxeRsp rsp = rst.getForObject(buildUrl(mgmtNic.getIp4Address(), BaremetalVritualRouterCommands.PREPARE_PXE_URL), BaremetalVritualRouterCommands.PreparePxeRsp.class);
|
||||
if (!rsp.isSuccess()) {
|
||||
throw new CloudRuntimeException(String.format("failed preparing PXE in virtual router[id:%s], because %s", vr.getId(), rsp.getError()));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean prepare(VirtualMachineProfile profile, NicProfile nic, Network network, DeployDestination dest, ReservationContext context) {
|
||||
try {
|
||||
if (DataCenter.NetworkType.Basic.equals(dest.getDataCenter().getNetworkType())) {
|
||||
if (!preparePxeInBasicZone(profile, nic, dest, context)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!preparePxeInAdvancedZone(profile, nic, network, dest, context)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
IpmISetBootDevCommand bootCmd = new IpmISetBootDevCommand(BootDev.pxe);
|
||||
aws = _agentMgr.send(dest.getHost().getId(), bootCmd);
|
||||
Answer aws = _agentMgr.send(dest.getHost().getId(), bootCmd);
|
||||
if (!aws.getResult()) {
|
||||
s_logger.warn("Unable to set host: " + dest.getHost().getId() + " to PXE boot because " + aws.getDetails());
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ public class BaremetalPxeElement extends AdapterBase implements NetworkElement {
|
||||
_nicDao.update(nicVo.getId(), nicVo);
|
||||
|
||||
/*This vm is just being created */
|
||||
if (!_pxeMgr.prepare(vm, nic, dest, context)) {
|
||||
if (!_pxeMgr.prepare(vm, nic, network, dest, context)) {
|
||||
throw new CloudRuntimeException("Cannot prepare pxe server");
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ public interface BaremetalPxeManager extends Manager, PluggableService {
|
||||
PING, KICK_START,
|
||||
}
|
||||
|
||||
boolean prepare(VirtualMachineProfile profile, NicProfile nic, DeployDestination dest, ReservationContext context);
|
||||
boolean prepare(VirtualMachineProfile profile, NicProfile nic, Network network, DeployDestination dest, ReservationContext context);
|
||||
|
||||
boolean prepareCreateTemplate(Long pxeServerId, UserVm vm, String templateUrl);
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.network.Network;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.AddBaremetalKickStartPxeCmd;
|
||||
@ -132,10 +133,10 @@ public class BaremetalPxeManagerImpl extends ManagerBase implements BaremetalPxe
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean prepare(VirtualMachineProfile profile, NicProfile nic, DeployDestination dest, ReservationContext context) {
|
||||
public boolean prepare(VirtualMachineProfile profile, NicProfile nic, Network network, DeployDestination dest, ReservationContext context) {
|
||||
//TODO: select type from template
|
||||
BaremetalPxeType type = BaremetalPxeType.KICK_START;
|
||||
return getServiceByType(type.toString()).prepare(profile, nic, dest, context);
|
||||
return getServiceByType(type.toString()).prepare(profile, nic, network, dest, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -24,6 +24,7 @@ package com.cloud.baremetal.networkservice;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.network.Network;
|
||||
import org.apache.cloudstack.api.AddBaremetalPxeCmd;
|
||||
import org.apache.cloudstack.api.ListBaremetalPxeServersCmd;
|
||||
|
||||
@ -37,7 +38,7 @@ import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
public interface BaremetalPxeService extends Adapter {
|
||||
|
||||
public boolean prepare(VirtualMachineProfile profile, NicProfile nic, DeployDestination dest, ReservationContext context);
|
||||
public boolean prepare(VirtualMachineProfile profile, NicProfile nic, Network network, DeployDestination dest, ReservationContext context);
|
||||
|
||||
public boolean prepareCreateTemplate(Long pxeServerId, UserVm vm, String templateUrl);
|
||||
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
package com.cloud.baremetal.networkservice;
|
||||
|
||||
/**
|
||||
* Created by frank on 7/23/14.
|
||||
*/
|
||||
public class BaremetalVritualRouterCommands {
|
||||
public static String PREPARE_PXE_URL = "/baremetal/pxe/prepare";
|
||||
|
||||
public abstract static class AgentCommand {
|
||||
}
|
||||
|
||||
public abstract static class AgentResponse {
|
||||
private boolean success;
|
||||
private String error;
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setError(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PreparePxeCmd extends AgentCommand {
|
||||
private String guestMac;
|
||||
private String kickStartUrl;
|
||||
private String initrdUrl;
|
||||
private String kernelUrl;
|
||||
|
||||
public String getGuestMac() {
|
||||
return guestMac;
|
||||
}
|
||||
|
||||
public void setGuestMac(String guestMac) {
|
||||
this.guestMac = guestMac;
|
||||
}
|
||||
|
||||
public String getKickStartUrl() {
|
||||
return kickStartUrl;
|
||||
}
|
||||
|
||||
public void setKickStartUrl(String kickStartUrl) {
|
||||
this.kickStartUrl = kickStartUrl;
|
||||
}
|
||||
|
||||
public String getInitrdUrl() {
|
||||
return initrdUrl;
|
||||
}
|
||||
|
||||
public void setInitrdUrl(String initrdUrl) {
|
||||
this.initrdUrl = initrdUrl;
|
||||
}
|
||||
|
||||
public String getKernelUrl() {
|
||||
return kernelUrl;
|
||||
}
|
||||
|
||||
public void setKernelUrl(String kernelUrl) {
|
||||
this.kernelUrl = kernelUrl;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PreparePxeRsp extends AgentResponse {
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user