Repository: cloudstack
Updated Branches:
refs/heads/master 5fdc8b403 -> 1ee7e0c77
CLOUDSTACK-6278
Baremetal Advanced Networking support
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/66fff6c5
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/66fff6c5
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/66fff6c5
Branch: refs/heads/master
Commit: 66fff6c5747e5f10ae25d1dc8f50ad77d82c96e2
Parents: 5fdc8b4
Author: Frank.Zhang <[email protected]>
Authored: Wed Jul 23 17:25:11 2014 -0700
Committer: Frank.Zhang <[email protected]>
Committed: Mon Aug 4 15:00:43 2014 -0700
----------------------------------------------------------------------
.../BareMetalPingServiceImpl.java | 3 +-
.../BaremetalKickStartServiceImpl.java | 182 ++++++++++++++-----
.../networkservice/BaremetalPxeElement.java | 2 +-
.../networkservice/BaremetalPxeManager.java | 2 +-
.../networkservice/BaremetalPxeManagerImpl.java | 5 +-
.../networkservice/BaremetalPxeService.java | 3 +-
.../BaremetalVritualRouterCommands.java | 74 ++++++++
7 files changed, 224 insertions(+), 47 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66fff6c5/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java
----------------------------------------------------------------------
diff --git
a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java
index 66bbb61..70b9b58 100755
---
a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java
+++
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java
@@ -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());
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66fff6c5/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java
----------------------------------------------------------------------
diff --git
a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java
index 62b3123..cc9fce7 100755
---
a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java
+++
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java
@@ -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,9 +95,67 @@ 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) {
+ 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()));
+ }
+
+ 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(";");
+ CloudRuntimeException err =
+ new CloudRuntimeException(
+ String.format(
+ "template url[%s] is not correctly encoded. it
must be in format of
ks=http_link_to_kickstartfile;kernel=nfs_path_to_pxe_kernel;initrd=nfs_path_to_pxe_initrd",
+ tpl));
+ if (tpls.length != 3) {
+ throw err;
+ }
+
+ String ks = null;
+ String kernel = null;
+ String initrd = null;
+
+ for (String t : tpls) {
+ String[] kv = t.split("=");
+ if (kv.length != 2) {
+ throw err;
+ }
+ if (kv[0].equals("ks")) {
+ ks = kv[1];
+ } else if (kv[0].equals("kernel")) {
+ kernel = kv[1];
+ } else if (kv[0].equals("initrd")) {
+ initrd = kv[1];
+ } else {
+ throw err;
+ }
+ }
+
+ 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());
@@ -92,54 +165,81 @@ public class BaremetalKickStartServiceImpl extends
BareMetalPxeServiceBase imple
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);
- try {
- String tpl = profile.getTemplate().getUrl();
- assert tpl != null : "How can a null template get here!!!";
- String[] tpls = tpl.split(";");
- CloudRuntimeException err =
- new CloudRuntimeException(
- String.format(
- "template url[%s] is not correctly encoded. it must be
in format of
ks=http_link_to_kickstartfile;kernel=nfs_path_to_pxe_kernel;initrd=nfs_path_to_pxe_initrd",
- tpl));
- if (tpls.length != 3) {
- throw err;
+ 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);
+ cmd.setKernel(kernel);
+ cmd.setMac(nic.getMacAddress());
+ cmd.setTemplateUuid(template.getUuid());
+ 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 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;
}
+ }
- String ks = null;
- String kernel = null;
- String initrd = null;
+ 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()));
+ }
- for (String t : tpls) {
- String[] kv = t.split("=");
- if (kv.length != 2) {
- throw err;
+ 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;
}
- if (kv[0].equals("ks")) {
- ks = kv[1];
- } else if (kv[0].equals("kernel")) {
- kernel = kv[1];
- } else if (kv[0].equals("initrd")) {
- initrd = kv[1];
- } else {
- throw err;
+ } else {
+ if (!preparePxeInAdvancedZone(profile, nic, network, dest,
context)) {
+ return false;
}
}
- PrepareKickstartPxeServerCommand cmd = new
PrepareKickstartPxeServerCommand();
- cmd.setKsFile(ks);
- cmd.setInitrd(initrd);
- cmd.setKernel(kernel);
- cmd.setMac(nic.getMacAddress());
- cmd.setTemplateUuid(template.getUuid());
- 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();
- }
-
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());
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66fff6c5/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
----------------------------------------------------------------------
diff --git
a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
index d5a7188..ab8eae9 100755
---
a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
+++
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
@@ -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");
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66fff6c5/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManager.java
----------------------------------------------------------------------
diff --git
a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManager.java
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManager.java
index fce27a4..38f1799 100755
---
a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManager.java
+++
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManager.java
@@ -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);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66fff6c5/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java
----------------------------------------------------------------------
diff --git
a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java
index 261534a..e133f7d 100755
---
a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java
+++
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java
@@ -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
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66fff6c5/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java
----------------------------------------------------------------------
diff --git
a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java
index c45f99e..ef7494a 100755
---
a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java
+++
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java
@@ -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);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/66fff6c5/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalVritualRouterCommands.java
----------------------------------------------------------------------
diff --git
a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalVritualRouterCommands.java
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalVritualRouterCommands.java
new file mode 100755
index 0000000..12bffd4
--- /dev/null
+++
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalVritualRouterCommands.java
@@ -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 {
+ }
+}