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 {
+    }
+}

Reply via email to