CLOUDSTACK-6278

Baremetal Advanced Networking support
This commit is contained in:
Frank.Zhang 2014-07-30 14:33:57 -07:00
parent 66fff6c574
commit 44dff6c426
4 changed files with 118 additions and 76 deletions

View File

@ -22,26 +22,11 @@
// Automatically generated by addcopyright.py at 04/03/2012 // Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.baremetal.manager; package com.cloud.baremetal.manager;
import java.util.Date;
import java.util.List;
import javax.ejb.Local;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.Resource.ResourceType;
import com.cloud.dc.DataCenterVO; import com.cloud.dc.DataCenterVO;
import com.cloud.event.EventTypes; import com.cloud.event.EventTypes;
import com.cloud.event.UsageEventVO; import com.cloud.event.UsageEventVO;
import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceAllocationException;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDao;
import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceManager;
import com.cloud.storage.TemplateProfile; import com.cloud.storage.TemplateProfile;
@ -53,6 +38,16 @@ import com.cloud.template.TemplateAdapterBase;
import com.cloud.user.Account; import com.cloud.user.Account;
import com.cloud.utils.db.DB; import com.cloud.utils.db.DB;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.log4j.Logger;
import javax.ejb.Local;
import javax.inject.Inject;
import java.util.Date;
import java.util.List;
@Local(value = TemplateAdapter.class) @Local(value = TemplateAdapter.class)
public class BareMetalTemplateAdapter extends TemplateAdapterBase implements TemplateAdapter { public class BareMetalTemplateAdapter extends TemplateAdapterBase implements TemplateAdapter {
@ -69,24 +64,7 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem
@Override @Override
public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException { public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException {
TemplateProfile profile = super.prepare(cmd); return super.prepare(cmd);
if (profile.getZoneId() == null || profile.getZoneId() == -1) {
List<DataCenterVO> dcs = _dcDao.listAllIncludingRemoved();
for (DataCenterVO dc : dcs) {
List<HostVO> pxeServers = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.BaremetalPxe, dc.getId());
if (pxeServers.size() == 0) {
throw new CloudRuntimeException("Please add PXE server before adding baremetal template in zone " + dc.getName());
}
}
} else {
List<HostVO> pxeServers = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.BaremetalPxe, profile.getZoneId());
if (pxeServers.size() == 0) {
throw new CloudRuntimeException("Please add PXE server before adding baremetal template in zone " + profile.getZoneId());
}
}
return profile;
} }
@Override @Override

View File

@ -18,44 +18,22 @@
// Automatically generated by addcopyright.py at 01/29/2013 // Automatically generated by addcopyright.py at 01/29/2013
package com.cloud.baremetal.networkservice; 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;
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;
import org.apache.cloudstack.api.AddBaremetalPxeCmd;
import org.apache.cloudstack.api.ListBaremetalPxeServersCmd;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
import com.cloud.agent.api.baremetal.IpmISetBootDevCommand; import com.cloud.agent.api.baremetal.IpmISetBootDevCommand;
import com.cloud.agent.api.baremetal.IpmISetBootDevCommand.BootDev; import com.cloud.agent.api.baremetal.IpmISetBootDevCommand.BootDev;
import com.cloud.baremetal.database.BaremetalPxeDao; import com.cloud.baremetal.database.BaremetalPxeDao;
import com.cloud.baremetal.database.BaremetalPxeVO; import com.cloud.baremetal.database.BaremetalPxeVO;
import com.cloud.baremetal.networkservice.BaremetalPxeManager.BaremetalPxeType; import com.cloud.baremetal.networkservice.BaremetalPxeManager.BaremetalPxeType;
import com.cloud.configuration.Config;
import com.cloud.dc.DataCenter;
import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeployDestination;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.host.Host; import com.cloud.host.Host;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDetailsDao; import com.cloud.host.dao.HostDetailsDao;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.network.Network;
import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PhysicalNetworkServiceProvider;
import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.NetworkVO;
@ -63,21 +41,44 @@ import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.guru.ControlNetworkGuru;
import com.cloud.network.router.VirtualRouter;
import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceManager;
import com.cloud.resource.ServerResource; import com.cloud.resource.ServerResource;
import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.uservm.UserVm; import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
import com.cloud.utils.db.DB; import com.cloud.utils.db.DB;
import com.cloud.utils.db.QueryBuilder; import com.cloud.utils.db.QueryBuilder;
import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.ssh.SshHelper;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.NicProfile; import com.cloud.vm.NicProfile;
import com.cloud.vm.NicVO;
import com.cloud.vm.ReservationContext; import com.cloud.vm.ReservationContext;
import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfile;
import org.springframework.web.client.RestTemplate; import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
import org.apache.cloudstack.api.AddBaremetalKickStartPxeCmd;
import org.apache.cloudstack.api.AddBaremetalPxeCmd;
import org.apache.cloudstack.api.ListBaremetalPxeServersCmd;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.log4j.Logger;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import javax.ejb.Local;
import javax.inject.Inject;
import java.io.File;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Local(value = BaremetalPxeService.class) @Local(value = BaremetalPxeService.class)
public class BaremetalKickStartServiceImpl extends BareMetalPxeServiceBase implements BaremetalPxeService { public class BaremetalKickStartServiceImpl extends BareMetalPxeServiceBase implements BaremetalPxeService {
private static final Logger s_logger = Logger.getLogger(BaremetalKickStartServiceImpl.class); private static final Logger s_logger = Logger.getLogger(BaremetalKickStartServiceImpl.class);
@ -99,6 +100,8 @@ public class BaremetalKickStartServiceImpl extends BareMetalPxeServiceBase imple
DomainRouterDao _routerDao; DomainRouterDao _routerDao;
@Inject @Inject
NicDao _nicDao; NicDao _nicDao;
@Inject
ConfigurationDao _configDao;
private DomainRouterVO getVirtualRouter(Network network) { private DomainRouterVO getVirtualRouter(Network network) {
List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER); List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), VirtualRouter.Role.VIRTUAL_ROUTER);
@ -155,6 +158,22 @@ public class BaremetalKickStartServiceImpl extends BareMetalPxeServiceBase imple
return Arrays.asList(ks, kernel, initrd); return Arrays.asList(ks, kernel, initrd);
} }
private File getSystemVMKeyFile() {
URL url = this.getClass().getClassLoader().getResource("scripts/vm/systemvm/id_rsa.cloud");
File keyFile = null;
if (url != null) {
keyFile = new File(url.getPath());
}
if (keyFile == null || !keyFile.exists()) {
keyFile = new File("/usr/share/cloudstack-common/scripts/vm/systemvm/id_rsa.cloud");
}
assert (keyFile != null);
if (!keyFile.exists()) {
s_logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile.toString());
}
return keyFile;
}
private boolean preparePxeInBasicZone(VirtualMachineProfile profile, NicProfile nic, DeployDestination dest, ReservationContext context) throws AgentUnavailableException, OperationTimedoutException { private boolean preparePxeInBasicZone(VirtualMachineProfile profile, NicProfile nic, DeployDestination dest, ReservationContext context) throws AgentUnavailableException, OperationTimedoutException {
NetworkVO nwVO = _nwDao.findById(nic.getNetworkId()); NetworkVO nwVO = _nwDao.findById(nic.getNetworkId());
QueryBuilder<BaremetalPxeVO> sc = QueryBuilder.create(BaremetalPxeVO.class); QueryBuilder<BaremetalPxeVO> sc = QueryBuilder.create(BaremetalPxeVO.class);
@ -195,7 +214,7 @@ public class BaremetalKickStartServiceImpl extends BareMetalPxeServiceBase imple
return ub.build().toUri(); return ub.build().toUri();
} }
private boolean preparePxeInAdvancedZone(VirtualMachineProfile profile, NicProfile nic, Network network, DeployDestination dest, ReservationContext context) { private boolean preparePxeInAdvancedZone(VirtualMachineProfile profile, NicProfile nic, Network network, DeployDestination dest, ReservationContext context) throws Exception {
DomainRouterVO vr = getVirtualRouter(network); DomainRouterVO vr = getVirtualRouter(network);
List<NicVO> nics = _nicDao.listByVmId(vr.getId()); List<NicVO> nics = _nicDao.listByVmId(vr.getId());
NicVO mgmtNic = null; NicVO mgmtNic = null;
@ -207,19 +226,24 @@ public class BaremetalKickStartServiceImpl extends BareMetalPxeServiceBase imple
} }
if (mgmtNic == null) { if (mgmtNic == null) {
throw new CloudRuntimeException(String.format("cannot find management nic on virutal router[id:%s]", vr.getId())); throw new CloudRuntimeException(String.format("cannot find management nic on virtual router[id:%s]", vr.getId()));
} }
BaremetalVritualRouterCommands.PreparePxeCmd cmd = new BaremetalVritualRouterCommands.PreparePxeCmd();
List<String> tuple = parseKickstartUrl(profile); List<String> tuple = parseKickstartUrl(profile);
cmd.setKickStartUrl(tuple.get(0)); Pair<Boolean, String> ret = SshHelper.sshExecute(mgmtNic.getIp4Address(), 3922, "root", getSystemVMKeyFile(), null,
cmd.setKernelUrl(tuple.get(1)); String.format("/usr/bin/prepare_pxe.sh %s %s %s %s %s", tuple.get(1), tuple.get(2), profile.getTemplate().getUuid(),
cmd.setInitrdUrl(tuple.get(2)); String.format("01-%s", nic.getMacAddress().replaceAll(":", "-")), tuple.get(0))
cmd.setGuestMac(nic.getMacAddress()); );
RestTemplate rst = new RestTemplate(); if (!ret.first()) {
BaremetalVritualRouterCommands.PreparePxeRsp rsp = rst.getForObject(buildUrl(mgmtNic.getIp4Address(), BaremetalVritualRouterCommands.PREPARE_PXE_URL), BaremetalVritualRouterCommands.PreparePxeRsp.class); throw new CloudRuntimeException(String.format("failed preparing PXE in virtual router[id:%s], because %s", vr.getId(), ret.second()));
if (!rsp.isSuccess()) { }
throw new CloudRuntimeException(String.format("failed preparing PXE in virtual router[id:%s], because %s", vr.getId(), rsp.getError()));
String internalServerIp = _configDao.getValue(Config.BaremetalInternalStorageServer.key());
ret = SshHelper.sshExecute(mgmtNic.getIp4Address(), 3922, "root", getSystemVMKeyFile(), null,
String.format("/usr/bin/baremetal_snat.sh %s %s", mgmtNic.getIp4Address(), internalServerIp)
);
if (!ret.first()) {
throw new CloudRuntimeException(String.format("failed preparing PXE in virtual router[id:%s], because %s", vr.getId(), ret.second()));
} }
return true; return true;

View File

@ -3,8 +3,7 @@ package com.cloud.baremetal.networkservice;
/** /**
* Created by frank on 7/23/14. * Created by frank on 7/23/14.
*/ */
public class BaremetalVritualRouterCommands { public class BaremetalVirtualRouterCommands {
public static String PREPARE_PXE_URL = "/baremetal/pxe/prepare";
public abstract static class AgentCommand { public abstract static class AgentCommand {
} }
@ -32,10 +31,19 @@ public class BaremetalVritualRouterCommands {
public static class PreparePxeCmd extends AgentCommand { public static class PreparePxeCmd extends AgentCommand {
private String guestMac; private String guestMac;
private String templateUuid;
private String kickStartUrl; private String kickStartUrl;
private String initrdUrl; private String initrdUrl;
private String kernelUrl; private String kernelUrl;
public String getTemplateUuid() {
return templateUuid;
}
public void setTemplateUuid(String templateUuid) {
this.templateUuid = templateUuid;
}
public String getGuestMac() { public String getGuestMac() {
return guestMac; return guestMac;
} }
@ -71,4 +79,28 @@ public class BaremetalVritualRouterCommands {
public static class PreparePxeRsp extends AgentResponse { public static class PreparePxeRsp extends AgentResponse {
} }
public static class PrepareSourceNatCmd extends AgentCommand {
private String internalStorageServerIp;
private String managementNicIp;
public String getInternalStorageServerIp() {
return internalStorageServerIp;
}
public void setInternalStorageServerIp(String internalStorageServerIp) {
this.internalStorageServerIp = internalStorageServerIp;
}
public String getManagementNicIp() {
return managementNicIp;
}
public void setManagementNicIp(String managementNicIp) {
this.managementNicIp = managementNicIp;
}
}
public static class PrepareSourceNatRsp extends AgentResponse {
}
} }

View File

@ -1766,9 +1766,17 @@ public enum Config {
ManagementServer.class, ManagementServer.class,
String.class, String.class,
"baremetal.peer.hypervisor.type", "baremetal.peer.hypervisor.type",
"XenServer", "Vmware",
"Hypervisor[Xenserver/KVM/VMWare] used to spring up virtual router for baremetal instances. The cluster having this hypervisor type must be in the same zone with baremetal cluster", "Hypervisor[Xenserver/KVM/VMWare] used to spring up virtual router for baremetal instances. The cluster having this hypervisor type must be in the same zone with baremetal cluster",
null), null),
BaremetalInternalStorageServer(
"Advanced",
ManagementServer.class,
String.class,
"baremetal.internal.storage.server.ip",
null,
"the ip address of server that stores kickstart file, kernel, initrd, ISO for advanced networking baremetal provisioning",
null),
ExternalBaremetalSystemUrl( ExternalBaremetalSystemUrl(
"Advanced", "Advanced",
ManagementServer.class, ManagementServer.class,