You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ki...@apache.org on 2013/01/31 18:07:19 UTC
[11/43] CloudStack CLOUDSTACK-774 Supporting kickstart in CloudStack
baremetal
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/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
new file mode 100755
index 0000000..94010ec
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java
@@ -0,0 +1,242 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+// Automatically generated by addcopyright.py at 01/29/2013
+// Apache License, Version 2.0 (the "License"); you may not use this
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.baremetal.networkservice;
+
+
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupPxeServerCommand;
+import com.cloud.agent.api.routing.VmDataCommand;
+import com.cloud.baremetal.database.BaremetalPxeVO;
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.network.PhysicalNetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.component.Adapters;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.SearchCriteria2;
+import com.cloud.utils.db.SearchCriteriaService;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.UserVmDao;
+
+@Local(value = {BaremetalPxeManager.class})
+public class BaremetalPxeManagerImpl implements BaremetalPxeManager, ResourceStateAdapter {
+ private static final org.apache.log4j.Logger s_logger = Logger.getLogger(BaremetalPxeManagerImpl.class);
+ protected String _name;
+ @Inject DataCenterDao _dcDao;
+ @Inject HostDao _hostDao;
+ @Inject AgentManager _agentMgr;
+ @Inject ResourceManager _resourceMgr;
+ @Inject(adapter=BaremetalPxeService.class)
+ protected Adapters<BaremetalPxeService> _services;
+ @Inject UserVmDao _vmDao;
+ @Inject ServiceOfferingDao _serviceOfferingDao;
+ @Inject NicDao _nicDao;
+ @Inject ConfigurationDao _configDao;
+ @Inject PhysicalNetworkDao _phynwDao;
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ _name = name;
+ _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
+ return true;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName());
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return _name;
+ }
+
+ protected BaremetalPxeService getServiceByType(String type) {
+ BaremetalPxeService _service;
+ _service = _services.get(type);
+ if (_service == null) {
+ throw new CloudRuntimeException("Cannot find PXE service for " + type);
+ }
+ return _service;
+ }
+
+ @Override
+ public boolean prepare(VirtualMachineProfile profile, NicProfile nic, DeployDestination dest, ReservationContext context) {
+ //TODO: select type from template
+ BaremetalPxeType type = BaremetalPxeType.KICK_START;
+ return getServiceByType(type.toString()).prepare(profile, nic, dest, context);
+ }
+
+ @Override
+ public boolean prepareCreateTemplate(Long pxeServerId, UserVm vm, String templateUrl) {
+ //TODO: select type from template
+ BaremetalPxeType type = BaremetalPxeType.PING;
+ return getServiceByType(type.toString()).prepareCreateTemplate(pxeServerId, vm, templateUrl);
+ }
+
+ @Override
+ public BaremetalPxeType getPxeServerType(HostVO host) {
+ if (host.getResource().equalsIgnoreCase(BaremetalPingPxeResource.class.getName())) {
+ return BaremetalPxeType.PING;
+ } else {
+ throw new CloudRuntimeException("Unkown PXE server resource " + host.getResource());
+ }
+ }
+
+ @Override
+ public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details,
+ List<String> hostTags) {
+ if (!(startup[0] instanceof StartupPxeServerCommand)) {
+ return null;
+ }
+
+ host.setType(Host.Type.BaremetalPxe);
+ return host;
+ }
+
+ @Override
+ public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public BaremetalPxeVO addPxeServer(AddBaremetalPxeCmd cmd) {
+ return getServiceByType(cmd.getDeviceType()).addPxeServer(cmd);
+ }
+
+ @Override
+ public BaremetalPxeResponse getApiResponse(BaremetalPxeVO vo) {
+ return getServiceByType(vo.getDeviceType()).getApiResponse(vo);
+ }
+
+ @Override
+ public List<BaremetalPxeResponse> listPxeServers(ListBaremetalPxePingServersCmd cmd) {
+ return getServiceByType(BaremetalPxeManager.BaremetalPxeType.PING.toString()).listPxeServers(cmd);
+ }
+
+ @Override
+ public boolean addUserData(NicProfile nic, VirtualMachineProfile<UserVm> profile) {
+ UserVmVO vm = (UserVmVO) profile.getVirtualMachine();
+ _vmDao.loadDetails(vm);
+
+ String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId()).getDisplayText();
+ String zoneName = _dcDao.findById(vm.getDataCenterIdToDeployIn()).getName();
+ NicVO nvo = _nicDao.findById(nic.getId());
+ VmDataCommand cmd = new VmDataCommand(nvo.getIp4Address(), vm.getInstanceName());
+ cmd.addVmData("userdata", "user-data", vm.getUserData());
+ cmd.addVmData("metadata", "service-offering", StringUtils.unicodeEscape(serviceOffering));
+ cmd.addVmData("metadata", "availability-zone", StringUtils.unicodeEscape(zoneName));
+ cmd.addVmData("metadata", "local-ipv4", nic.getIp4Address());
+ cmd.addVmData("metadata", "local-hostname", StringUtils.unicodeEscape(vm.getInstanceName()));
+ cmd.addVmData("metadata", "public-ipv4", nic.getIp4Address());
+ cmd.addVmData("metadata", "public-hostname", StringUtils.unicodeEscape(vm.getInstanceName()));
+ cmd.addVmData("metadata", "instance-id", String.valueOf(vm.getId()));
+ cmd.addVmData("metadata", "vm-id", String.valueOf(vm.getInstanceName()));
+ cmd.addVmData("metadata", "public-keys", null);
+ String cloudIdentifier = _configDao.getValue("cloud.identifier");
+ if (cloudIdentifier == null) {
+ cloudIdentifier = "";
+ } else {
+ cloudIdentifier = "CloudStack-{" + cloudIdentifier + "}";
+ }
+ cmd.addVmData("metadata", "cloud-identifier", cloudIdentifier);
+
+ List<PhysicalNetworkVO> phys = _phynwDao.listByZone(vm.getDataCenterIdToDeployIn());
+ if (phys.isEmpty()) {
+ throw new CloudRuntimeException(String.format("Cannot find physical network in zone %s", vm.getDataCenterIdToDeployIn()));
+ }
+ if (phys.size() > 1) {
+ throw new CloudRuntimeException(String.format("Baremetal only supports one physical network in zone, but zone %s has %s physical networks", vm.getDataCenterIdToDeployIn(), phys.size()));
+ }
+ PhysicalNetworkVO phy = phys.get(0);
+
+ SearchCriteriaService<BaremetalPxeVO, BaremetalPxeVO> sc = SearchCriteria2.create(BaremetalPxeVO.class);
+ //TODO: handle both kickstart and PING
+ //sc.addAnd(sc.getEntity().getPodId(), Op.EQ, vm.getPodIdToDeployIn());
+ sc.addAnd(sc.getEntity().getPhysicalNetworkId(), Op.EQ, phy.getId());
+ BaremetalPxeVO pxeVo = sc.find();
+ if (pxeVo == null) {
+ throw new CloudRuntimeException("No PXE server found in pod: " + vm.getPodIdToDeployIn() + ", you need to add it before starting VM");
+ }
+
+ try {
+ Answer ans = _agentMgr.send(pxeVo.getHostId(), cmd);
+ if (!ans.getResult()) {
+ s_logger.debug(String.format("Add userdata to vm:%s failed because %s", vm.getInstanceName(), ans.getDetails()));
+ return false;
+ } else {
+ return true;
+ }
+ } catch (Exception e) {
+ s_logger.debug(String.format("Add userdata to vm:%s failed", vm.getInstanceName()), e);
+ return false;
+ }
+ }
+
+ @Override
+ public List<Class<?>> getCommands() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxePingResponse.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxePingResponse.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxePingResponse.java
new file mode 100755
index 0000000..adbf053
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxePingResponse.java
@@ -0,0 +1,59 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+// Automatically generated by addcopyright.py at 01/29/2013
+package com.cloud.baremetal.networkservice;
+
+import org.apache.cloudstack.api.ApiConstants;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+public class BaremetalPxePingResponse extends BaremetalPxeResponse {
+ @SerializedName(ApiConstants.PING_STORAGE_SERVER_IP) @Param(description="PING storage server ip")
+ private String pingStorageServerIp;
+
+ @SerializedName(ApiConstants.PING_DIR) @Param(description="Root directory on PING storage server")
+ private String pingDir;
+
+ @SerializedName(ApiConstants.TFTP_DIR) @Param(description="Tftp root directory of PXE server")
+ private String tftpDir;
+
+ public String getPingStorageServerIp() {
+ return pingStorageServerIp;
+ }
+
+ public void setPingStorageServerIp(String pingStorageServerIp) {
+ this.pingStorageServerIp = pingStorageServerIp;
+ }
+
+ public String getPingDir() {
+ return pingDir;
+ }
+
+ public void setPingDir(String pingDir) {
+ this.pingDir = pingDir;
+ }
+
+ public String getTftpDir() {
+ return tftpDir;
+ }
+
+ public void setTftpDir(String tftpDir) {
+ this.tftpDir = tftpDir;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResourceBase.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResourceBase.java
new file mode 100755
index 0000000..34175c8
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResourceBase.java
@@ -0,0 +1,157 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+// Automatically generated by addcopyright.py at 01/29/2013
+// Apache License, Version 2.0 (the "License"); you may not use this
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.baremetal.networkservice;
+
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupPxeServerCommand;
+import com.cloud.host.Host.Type;
+import com.cloud.resource.ServerResource;
+
+public class BaremetalPxeResourceBase implements ServerResource {
+ private static final Logger s_logger = Logger.getLogger(BaremetalPxeResourceBase.class);
+ String _name;
+ String _guid;
+ String _username;
+ String _password;
+ String _ip;
+ String _zoneId;
+ String _podId;
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ _name = name;
+ _guid = (String)params.get(BaremetalPxeService.PXE_PARAM_GUID);
+ _ip = (String)params.get(BaremetalPxeService.PXE_PARAM_IP);
+ _username = (String)params.get(BaremetalPxeService.PXE_PARAM_USERNAME);
+ _password = (String)params.get(BaremetalPxeService.PXE_PARAM_PASSWORD);
+ _zoneId = (String)params.get(BaremetalPxeService.PXE_PARAM_ZONE);
+ _podId = (String)params.get(BaremetalPxeService.PXE_PARAM_POD);
+
+ if (_guid == null) {
+ throw new ConfigurationException("No Guid specified");
+ }
+
+ if (_zoneId == null) {
+ throw new ConfigurationException("No Zone specified");
+ }
+
+ if (_ip == null) {
+ throw new ConfigurationException("No IP specified");
+ }
+
+ if (_username == null) {
+ throw new ConfigurationException("No username specified");
+ }
+
+ if (_password == null) {
+ throw new ConfigurationException("No password specified");
+ }
+
+ return true;
+ }
+
+ protected ReadyAnswer execute(ReadyCommand cmd) {
+ s_logger.debug("Pxe resource " + _name + " is ready");
+ return new ReadyAnswer(cmd);
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ // TODO Auto-generated method stub
+ return _name;
+ }
+
+ @Override
+ public Type getType() {
+ return Type.BaremetalPxe;
+ }
+
+ @Override
+ public StartupCommand[] initialize() {
+ StartupPxeServerCommand cmd = new StartupPxeServerCommand();
+ cmd.setName(_name);
+ cmd.setDataCenter(_zoneId);
+ cmd.setPod(_podId);
+ cmd.setPrivateIpAddress(_ip);
+ cmd.setStorageIpAddress("");
+ cmd.setVersion("");
+ cmd.setGuid(_guid);
+ return new StartupCommand[]{cmd};
+ }
+
+ @Override
+ public PingCommand getCurrentStatus(long id) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void disconnected() {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public IAgentControl getAgentControl() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void setAgentControl(IAgentControl agentControl) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public Answer executeRequest(Command cmd) {
+ if (cmd instanceof ReadyCommand) {
+ return execute((ReadyCommand) cmd);
+ } else {
+ return Answer.createUnsupportedCommandAnswer(cmd);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResponse.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResponse.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResponse.java
new file mode 100755
index 0000000..2103020
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResponse.java
@@ -0,0 +1,71 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+// Automatically generated by addcopyright.py at 01/29/2013
+package com.cloud.baremetal.networkservice;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+public class BaremetalPxeResponse extends BaseResponse {
+ @SerializedName(ApiConstants.ID) @Param(description="device id of ")
+ private String id;
+
+ @SerializedName(ApiConstants.PHYSICAL_NETWORK_ID) @Param(description="the physical network to which this external dhcp device belongs to")
+ private String physicalNetworkId;
+
+ @SerializedName(ApiConstants.PROVIDER) @Param(description="name of the provider")
+ private String providerId;
+
+ @SerializedName(ApiConstants.POD_ID) @Param(description="pod id where the device is in")
+ private String podId;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getPhysicalNetworkId() {
+ return physicalNetworkId;
+ }
+
+ public void setPhysicalNetworkId(String physicalNetworkId) {
+ this.physicalNetworkId = physicalNetworkId;
+ }
+
+ public String getProviderId() {
+ return providerId;
+ }
+
+ public void setProviderId(String providerId) {
+ this.providerId = providerId;
+ }
+
+ public String getPodId() {
+ return podId;
+ }
+
+ public void setPodId(String podId) {
+ this.podId = podId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/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
new file mode 100644
index 0000000..8504f82
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java
@@ -0,0 +1,61 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+// Automatically generated by addcopyright.py at 01/29/2013
+// Apache License, Version 2.0 (the "License"); you may not use this
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.baremetal.networkservice;
+
+import java.util.List;
+
+import com.cloud.baremetal.database.BaremetalPxeVO;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.host.Host;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.component.Adapter;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachineProfile;
+
+public interface BaremetalPxeService extends Adapter {
+
+ public boolean prepare(VirtualMachineProfile<UserVmVO> profile, NicProfile nic, DeployDestination dest, ReservationContext context);
+
+ public boolean prepareCreateTemplate(Long pxeServerId, UserVm vm, String templateUrl);
+
+ BaremetalPxeVO addPxeServer(AddBaremetalPxeCmd cmd);
+
+ BaremetalPxeResponse getApiResponse(BaremetalPxeVO vo);
+
+ List<BaremetalPxeResponse> listPxeServers(ListBaremetalPxePingServersCmd cmd);
+
+ public static final String PXE_PARAM_TYPE = "type";
+ public static final String PXE_PARAM_ZONE = "zone";
+ public static final String PXE_PARAM_POD = "pod";
+ public static final String PXE_PARAM_IP = "ip";
+ public static final String PXE_PARAM_GUID = "guid";
+ public static final String PXE_PARAM_TFTP_DIR = "tftpDir";
+ public static final String PXE_PARAM_USERNAME = "username";
+ public static final String PXE_PARAM_PASSWORD = "password";
+ public static final String PXE_PARAM_PING_STORAGE_SERVER_IP = "pingStorageServerIp";
+ public static final String PXE_PARAM_PING_ROOT_DIR = "pingDir";
+ public static final String PXE_PARAM_PING_STORAGE_SERVER_USERNAME = "pingStorageServerUserName";
+ public static final String PXE_PARAM_PING_STORAGE_SERVER_PASSWORD = "pingStorageServerPassword";
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
new file mode 100755
index 0000000..d1f0e8b
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
@@ -0,0 +1,169 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+// Automatically generated by addcopyright.py at 01/29/2013
+package com.cloud.baremetal.networkservice;
+
+import java.util.HashMap;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ejb.Local;
+
+import com.cloud.baremetal.manager.BaremetalManager;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.element.IpDeployer;
+import com.cloud.network.element.NetworkElement;
+import com.cloud.network.element.UserDataServiceProvider;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.component.Inject;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Local(value = NetworkElement.class)
+public class BaremetalUserdataElement extends AdapterBase implements NetworkElement, UserDataServiceProvider {
+ private static Map<Service, Map<Capability, String>> capabilities;
+
+ @Inject
+ private BaremetalPxeManager pxeMgr;
+
+ static {
+ capabilities = new HashMap<Service, Map<Capability, String>>();
+ capabilities.put(Service.UserData, null);
+ }
+
+ private boolean canHandle(DeployDestination dest) {
+ if (dest.getDataCenter().getNetworkType() == NetworkType.Basic && dest.getHost().getHypervisorType() == HypervisorType.BareMetal) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean addPasswordAndUserdata(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest,
+ ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
+ if (!canHandle(dest)) {
+ return false;
+ }
+
+ if (vm.getType() != VirtualMachine.Type.User) {
+ return false;
+ }
+
+ return pxeMgr.addUserData(nic, (VirtualMachineProfile<UserVm>) vm);
+ }
+
+ @Override
+ public boolean savePassword(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm) throws ResourceUnavailableException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public Map<Service, Map<Capability, String>> getCapabilities() {
+ return capabilities;
+ }
+
+ @Override
+ public Provider getProvider() {
+ return BaremetalPxeManager.BAREMETAL_USERDATA_PROVIDER;
+ }
+
+ @Override
+ public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context)
+ throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest,
+ ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean release(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, ReservationContext context)
+ throws ConcurrentOperationException, ResourceUnavailableException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean isReady(PhysicalNetworkServiceProvider provider) {
+ return true;
+ }
+
+ @Override
+ public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException,
+ ResourceUnavailableException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean canEnableIndividualServices() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+
+ @Override
+ public boolean saveUserData(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm)
+ throws ResourceUnavailableException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean verifyServicesCombination(Set<Service> services) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalDhcpCmd.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalDhcpCmd.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalDhcpCmd.java
new file mode 100755
index 0000000..ba5128b
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalDhcpCmd.java
@@ -0,0 +1,102 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+// Automatically generated by addcopyright.py at 01/29/2013
+package com.cloud.baremetal.networkservice;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseCmd.CommandType;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.PlugService;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+
+public class ListBaremetalDhcpCmd extends BaseListCmd {
+ private static final Logger s_logger = Logger.getLogger(ListBaremetalDhcpCmd.class);
+ private static final String s_name = "listexternaldhcpresponse";
+ @PlugService BaremetalDhcpManager _dhcpMgr;
+
+ // ///////////////////////////////////////////////////
+ // ////////////// API parameters /////////////////////
+ // ///////////////////////////////////////////////////
+ @Parameter(name = ApiConstants.ID, type = CommandType.LONG, description = "DHCP server device ID")
+ private Long id;
+
+ @Parameter(name = ApiConstants.POD_ID, type = CommandType.LONG, description = "Pod ID where pxe server is in")
+ private Long podId;
+
+ @Parameter(name = ApiConstants.DHCP_SERVER_TYPE, type = CommandType.STRING, description = "Type of DHCP device")
+ private String deviceType;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getPodId() {
+ return podId;
+ }
+
+ public void setPodId(Long podId) {
+ this.podId = podId;
+ }
+
+ public String getDeviceType() {
+ return deviceType;
+ }
+
+ public void setDeviceType(String deviceType) {
+ this.deviceType = deviceType;
+ }
+
+ @Override
+ public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
+ ResourceAllocationException, NetworkRuleConflictException {
+ try {
+ ListResponse<BaremetalDhcpResponse> response = new ListResponse<BaremetalDhcpResponse>();
+ List<BaremetalDhcpResponse> dhcpResponses = _dhcpMgr.listBaremetalDhcps(this);
+ response.setResponses(dhcpResponses);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } catch (Exception e) {
+ s_logger.debug("Exception happend while executing ListBaremetalDhcpCmd");
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+ }
+
+ }
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalPxePingServersCmd.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalPxePingServersCmd.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalPxePingServersCmd.java
new file mode 100755
index 0000000..dceb8bf
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalPxePingServersCmd.java
@@ -0,0 +1,92 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+// Automatically generated by addcopyright.py at 01/29/2013
+package com.cloud.baremetal.networkservice;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseCmd.CommandType;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.PlugService;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+
+public class ListBaremetalPxePingServersCmd extends BaseListCmd {
+ private static final Logger s_logger = Logger.getLogger(ListBaremetalPxePingServersCmd.class);
+ private static final String s_name = "listpingpxeserverresponse";
+
+ @PlugService
+ BaremetalPxeManager _pxeMgr;
+ // ///////////////////////////////////////////////////
+ // ////////////// API parameters /////////////////////
+ // ///////////////////////////////////////////////////
+
+ @Parameter(name = ApiConstants.ID, type = CommandType.LONG, description = "Ping pxe server device ID")
+ private Long id;
+
+ @Parameter(name = ApiConstants.POD_ID, type = CommandType.LONG, description = "Pod ID where pxe server is in")
+ private Long podId;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getPodId() {
+ return podId;
+ }
+
+ public void setPodId(Long podId) {
+ this.podId = podId;
+ }
+
+ @Override
+ public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
+ ResourceAllocationException, NetworkRuleConflictException {
+ try {
+ ListResponse<BaremetalPxeResponse> response = new ListResponse<BaremetalPxeResponse>();
+ List<BaremetalPxeResponse> pxeResponses = _pxeMgr.listPxeServers(this);
+ response.setResponses(pxeResponses);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } catch (Exception e) {
+ s_logger.debug("Exception happend while executing ListPingPxeServersCmd" ,e);
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+ }
+ }
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/PrepareKickstartPxeServerCommand.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/PrepareKickstartPxeServerCommand.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/PrepareKickstartPxeServerCommand.java
new file mode 100755
index 0000000..8951547
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/PrepareKickstartPxeServerCommand.java
@@ -0,0 +1,74 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+// Automatically generated by addcopyright.py at 01/29/2013
+package com.cloud.baremetal.networkservice;
+
+import com.cloud.agent.api.Command;
+
+public class PrepareKickstartPxeServerCommand extends Command {
+ private String ksFile;
+ private String repo;
+ private String templateUuid;
+ private String mac;
+ private String ksDevice;
+
+ @Override
+ public boolean executeInSequence() {
+ return true;
+ }
+
+ public String getKsFile() {
+ return ksFile;
+ }
+
+ public void setKsFile(String ksFile) {
+ this.ksFile = ksFile;
+ }
+
+ public String getRepo() {
+ return repo;
+ }
+
+ public void setRepo(String repo) {
+ this.repo = repo;
+ }
+
+ public String getTemplateUuid() {
+ return templateUuid;
+ }
+
+ public void setTemplateUuid(String templateUuid) {
+ this.templateUuid = templateUuid;
+ }
+
+ public String getMac() {
+ return mac;
+ }
+
+ public void setMac(String mac) {
+ this.mac = mac;
+ }
+
+ public String getKsDevice() {
+ return ksDevice;
+ }
+
+ public void setKsDevice(String ksDevice) {
+ this.ksDevice = ksDevice;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java
new file mode 100755
index 0000000..203fed3
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java
@@ -0,0 +1,18 @@
+package com.cloud.baremetal.networkservice;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.SecurityGroupRulesCmd;
+
+public class SecurityGroupHttpClient {
+
+ public Answer call(String guestIp, SecurityGroupRulesCmd cmd) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean echo(String ip, long millis, long millis2) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/pom.xml b/plugins/pom.xml
index 7bb60a9..c5b6e58 100644
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -42,6 +42,7 @@
<module>hypervisors/xen</module>
<module>hypervisors/kvm</module>
<module>hypervisors/simulator</module>
+ <module>hypervisors/baremetal</module>
<module>network-elements/elastic-loadbalancer</module>
<module>network-elements/ovs</module>
<module>network-elements/nicira-nvp</module>
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/server/src/com/cloud/configuration/Config.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index 4ae144e..5e4996b 100755
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -358,7 +358,13 @@ public enum Config {
DetailBatchQuerySize("Advanced", ManagementServer.class, Integer.class, "detail.batch.query.size", "2000", "Default entity detail batch query size for listing", null),
ConcurrentSnapshotsThresholdPerHost("Advanced", ManagementServer.class, Long.class, "concurrent.snapshots.threshold.perhost",
- null, "Limits number of snapshots that can be handled by the host concurrently; default is NULL - unlimited", null);
+ null, "Limits number of snapshots that can be handled by the host concurrently; default is NULL - unlimited", null),
+
+ ExternalBaremetalSystemUrl("Advanced", ManagementServer.class, String.class, "external.baremetal.system.url", null, "url of external baremetal system that CloudStack will talk to", null),
+ ExternalBaremetalResourceClassName("Advanced", ManagementServer.class, String.class, "external,baremetal.resource.classname", null, "class name for handling external baremetal resource", null),
+ EnableBaremetalSecurityGroupAgentEcho("Advanced", ManagementServer.class, Boolean.class, "enable.baremetal.securitygroup.agent.echo", "false", "After starting provision process, periodcially echo security agent installed in the template. Treat provisioning as success only if echo successfully", null),
+ IntervalToEchoBaremetalSecurityGroupAgent("Advanced", ManagementServer.class, Integer.class, "interval.baremetal.securitygroup.agent.echo", "10", "Interval to echo baremetal security group agent, in seconds", null),
+ TimeoutToEchoBaremetalSecurityGroupAgent("Advanced", ManagementServer.class, Integer.class, "timeout.baremetal.securitygroup.agent.echo", "3600", "Timeout to echo baremetal security group agent, in seconds, the provisioning process will be treated as a failure", null);
private final String _category;
private final Class<?> _componentClass;