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
[12/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/BaremetalDhcpManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java
new file mode 100755
index 0000000..ae8482c
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java
@@ -0,0 +1,323 @@
+// 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.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+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.StartupExternalDhcpCommand;
+import com.cloud.agent.api.routing.DhcpEntryCommand;
+import com.cloud.baremetal.database.BaremetalDhcpDao;
+import com.cloud.baremetal.database.BaremetalDhcpVO;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.network.Network;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.PhysicalNetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.SearchCriteria2;
+import com.cloud.utils.db.SearchCriteriaService;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.UserVmDao;
+
+@Local(value = { BaremetalDhcpManager.class })
+public class BaremetalDhcpManagerImpl implements BaremetalDhcpManager, ResourceStateAdapter {
+ private static final org.apache.log4j.Logger s_logger = Logger.getLogger(BaremetalDhcpManagerImpl.class);
+ protected String _name;
+ @Inject
+ DataCenterDao _dcDao;
+ @Inject
+ HostDao _hostDao;
+ @Inject
+ AgentManager _agentMgr;
+ @Inject
+ HostPodDao _podDao;
+ @Inject
+ UserVmDao _userVmDao;
+ @Inject
+ ResourceManager _resourceMgr;
+ @Inject
+ NicDao _nicDao;
+ @Inject
+ PhysicalNetworkDao _physicalNetworkDao;
+ @Inject
+ PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
+ @Inject
+ BaremetalDhcpDao _extDhcpDao;
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ _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 String getDhcpServerGuid(String zoneId, String name, String ip) {
+ return zoneId + "-" + name + "-" + ip;
+ }
+
+ @Override
+ public boolean addVirtualMachineIntoNetwork(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> profile,
+ DeployDestination dest, ReservationContext context) throws ResourceUnavailableException {
+ Long zoneId = profile.getVirtualMachine().getDataCenterIdToDeployIn();
+ Long podId = profile.getVirtualMachine().getPodIdToDeployIn();
+ List<HostVO> hosts = _resourceMgr.listAllUpAndEnabledHosts(Type.BaremetalDhcp, null, podId, zoneId);
+ if (hosts.size() == 0) {
+ throw new CloudRuntimeException("No external Dhcp found in zone " + zoneId + " pod " + podId);
+ }
+
+ if (hosts.size() > 1) {
+ throw new CloudRuntimeException("Something wrong, more than 1 external Dhcp found in zone " + zoneId + " pod " + podId);
+ }
+
+ HostVO h = hosts.get(0);
+ String dns = nic.getDns1();
+ if (dns == null) {
+ dns = nic.getDns2();
+ }
+ DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIp4Address(), profile.getVirtualMachine().getHostName(), dns,
+ nic.getGateway());
+ String errMsg = String.format("Set dhcp entry on external DHCP %1$s failed(ip=%2$s, mac=%3$s, vmname=%4$s)", h.getPrivateIpAddress(),
+ nic.getIp4Address(), nic.getMacAddress(), profile.getVirtualMachine().getHostName());
+ // prepareBareMetalDhcpEntry(nic, dhcpCommand);
+ try {
+ Answer ans = _agentMgr.send(h.getId(), dhcpCommand);
+ if (ans.getResult()) {
+ s_logger.debug(String.format("Set dhcp entry on external DHCP %1$s successfully(ip=%2$s, mac=%3$s, vmname=%4$s)", h.getPrivateIpAddress(),
+ nic.getIp4Address(), nic.getMacAddress(), profile.getVirtualMachine().getHostName()));
+ return true;
+ } else {
+ s_logger.debug(errMsg + " " + ans.getDetails());
+ throw new ResourceUnavailableException(errMsg, DataCenter.class, zoneId);
+ }
+ } catch (Exception e) {
+ s_logger.debug(errMsg, e);
+ throw new ResourceUnavailableException(errMsg + e.getMessage(), DataCenter.class, zoneId);
+ }
+ }
+
+ @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 StartupExternalDhcpCommand)) {
+ return null;
+ }
+
+ host.setType(Host.Type.BaremetalDhcp);
+ return host;
+ }
+
+ @Override
+ public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+ @Override
+ @DB
+ public BaremetalDhcpVO addDchpServer(AddBaremetalDhcpCmd cmd) {
+ PhysicalNetworkVO pNetwork = null;
+ long zoneId;
+
+ if (cmd.getPhysicalNetworkId() == null || cmd.getUrl() == null || cmd.getUsername() == null || cmd.getPassword() == null) {
+ throw new IllegalArgumentException("At least one of the required parameters(physical network id, url, username, password) is null");
+ }
+
+ pNetwork = _physicalNetworkDao.findById(cmd.getPhysicalNetworkId());
+ if (pNetwork == null) {
+ throw new IllegalArgumentException("Could not find phyical network with ID: " + cmd.getPhysicalNetworkId());
+ }
+ zoneId = pNetwork.getDataCenterId();
+ DataCenterVO zone = _dcDao.findById(zoneId);
+
+ PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(),
+ BaremetalDhcpManager.BAREMETAL_DHCP_SERVICE_PROVIDER.getName());
+ if (ntwkSvcProvider == null) {
+ throw new CloudRuntimeException("Network Service Provider: " + BaremetalDhcpManager.BAREMETAL_DHCP_SERVICE_PROVIDER.getName() + " is not enabled in the physical network: "
+ + cmd.getPhysicalNetworkId() + "to add this device");
+ } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) {
+ throw new CloudRuntimeException("Network Service Provider: " + ntwkSvcProvider.getProviderName()
+ + " is in shutdown state in the physical network: " + cmd.getPhysicalNetworkId() + "to add this device");
+ }
+
+ HostPodVO pod = _podDao.findById(cmd.getPodId());
+ if (pod == null) {
+ throw new IllegalArgumentException("Could not find pod with ID: " + cmd.getPodId());
+ }
+
+ List<HostVO> dhcps = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.BaremetalDhcp, null, cmd.getPodId(), zoneId);
+ if (dhcps.size() != 0) {
+ throw new IllegalArgumentException("Already had a DHCP server in Pod: " + cmd.getPodId() + " zone: " + zoneId);
+ }
+
+ URI uri;
+ try {
+ uri = new URI(cmd.getUrl());
+ } catch (Exception e) {
+ s_logger.debug(e);
+ throw new IllegalArgumentException(e.getMessage());
+ }
+
+ String ipAddress = uri.getHost();
+ String guid = getDhcpServerGuid(Long.toString(zoneId) + "-" + Long.toString(cmd.getPodId()), "ExternalDhcp", ipAddress);
+ Map params = new HashMap<String, String>();
+ params.put("type", cmd.getDhcpType());
+ params.put("zone", Long.toString(zoneId));
+ params.put("pod", cmd.getPodId().toString());
+ params.put("ip", ipAddress);
+ params.put("username", cmd.getUsername());
+ params.put("password", cmd.getPassword());
+ params.put("guid", guid);
+ params.put("gateway", pod.getGateway());
+ String dns = zone.getDns1();
+ if (dns == null) {
+ dns = zone.getDns2();
+ }
+ params.put("dns", dns);
+
+ ServerResource resource = null;
+ try {
+ if (cmd.getDhcpType().equalsIgnoreCase(BaremetalDhcpType.DNSMASQ.toString())) {
+ resource = new BaremetalDnsmasqResource();
+ resource.configure("Dnsmasq resource", params);
+ } else if (cmd.getDhcpType().equalsIgnoreCase(BaremetalDhcpType.DHCPD.toString())) {
+ resource = new BaremetalDhcpdResource();
+ resource.configure("Dhcpd resource", params);
+ } else {
+ throw new CloudRuntimeException("Unsupport DHCP server type: " + cmd.getDhcpType());
+ }
+ } catch (Exception e) {
+ s_logger.debug(e);
+ throw new CloudRuntimeException(e.getMessage());
+ }
+
+ Host dhcpServer = _resourceMgr.addHost(zoneId, resource, Host.Type.BaremetalDhcp, params);
+ if (dhcpServer == null) {
+ throw new CloudRuntimeException("Cannot add external Dhcp server as a host");
+ }
+
+ BaremetalDhcpVO vo = new BaremetalDhcpVO();
+ vo.setDeviceType(cmd.getDhcpType());
+ vo.setHostId(dhcpServer.getId());
+ vo.setNetworkServiceProviderId(ntwkSvcProvider.getId());
+ vo.setPhysicalNetworkId(cmd.getPhysicalNetworkId());
+ vo.setPodId(cmd.getPodId());
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ _extDhcpDao.persist(vo);
+ txn.commit();
+ return vo;
+ }
+
+ @Override
+ public BaremetalDhcpResponse generateApiResponse(BaremetalDhcpVO vo) {
+ BaremetalDhcpResponse response = new BaremetalDhcpResponse();
+ response.setDeviceType(vo.getDeviceType());
+ response.setId(String.valueOf(vo.getId()));
+ response.setPhysicalNetworkId(String.valueOf(vo.getPhysicalNetworkId()));
+ response.setProviderId(String.valueOf(vo.getNetworkServiceProviderId()));
+ return response;
+ }
+
+ @Override
+ public List<BaremetalDhcpResponse> listBaremetalDhcps(ListBaremetalDhcpCmd cmd) {
+ SearchCriteriaService<BaremetalDhcpVO, BaremetalDhcpVO> sc = SearchCriteria2.create(BaremetalDhcpVO.class);
+ if (cmd.getDeviceType() != null) {
+ sc.addAnd(sc.getEntity().getDeviceType(), Op.EQ, cmd.getDeviceType());
+ }
+ if (cmd.getPodId() != null) {
+ sc.addAnd(sc.getEntity().getPodId(), Op.EQ, cmd.getPodId());
+ if (cmd.getId() != null) {
+ sc.addAnd(sc.getEntity().getId(), Op.EQ, cmd.getId());
+ }
+ }
+ List<BaremetalDhcpVO> vos = sc.list();
+ List<BaremetalDhcpResponse> responses = new ArrayList<BaremetalDhcpResponse>(vos.size());
+ for (BaremetalDhcpVO vo : vos) {
+ responses.add(generateApiResponse(vo));
+ }
+ return responses;
+ }
+
+ @Override
+ public List<Class<?>> getCommands() {
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpResourceBase.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpResourceBase.java
new file mode 100644
index 0000000..0541415
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpResourceBase.java
@@ -0,0 +1,174 @@
+// 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.HashMap;
+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.PingRoutingCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupExternalDhcpCommand;
+import com.cloud.agent.api.StartupPxeServerCommand;
+import com.cloud.host.Host.Type;
+import com.cloud.resource.ServerResource;
+import com.cloud.utils.script.Script;
+import com.cloud.utils.ssh.SSHCmdHelper;
+import com.cloud.vm.VirtualMachine.State;
+import com.trilead.ssh2.SCPClient;
+
+public class BaremetalDhcpResourceBase implements ServerResource {
+ private static final Logger s_logger = Logger.getLogger(BaremetalDhcpResourceBase.class);
+ String _name;
+ String _guid;
+ String _username;
+ String _password;
+ String _ip;
+ String _zoneId;
+ String _podId;
+ String _gateway;
+ String _dns;
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ _name = name;
+ _guid = (String)params.get("guid");
+ _ip = (String)params.get("ip");
+ _username = (String)params.get("username");
+ _password = (String)params.get("password");
+ _zoneId = (String)params.get("zone");
+ _podId = (String)params.get("pod");
+ _gateway = (String)params.get("gateway");
+ _dns = (String)params.get("dns");
+
+ if (_guid == null) {
+ throw new ConfigurationException("No Guid specified");
+ }
+
+ if (_zoneId == null) {
+ throw new ConfigurationException("No Zone specified");
+ }
+
+ if (_podId == null) {
+ throw new ConfigurationException("No Pod 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");
+ }
+
+ if (_gateway == null) {
+ throw new ConfigurationException("No gateway specified");
+ }
+
+ if (_dns == null) {
+ throw new ConfigurationException("No dns specified");
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return _name;
+ }
+
+ @Override
+ public Type getType() {
+ return Type.BaremetalDhcp;
+ }
+
+ @Override
+ public StartupCommand[] initialize() {
+ StartupExternalDhcpCommand cmd = new StartupExternalDhcpCommand();
+ 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: check server
+ return new PingRoutingCommand(getType(), id, new HashMap<String, State>());
+ }
+
+ protected ReadyAnswer execute(ReadyCommand cmd) {
+ s_logger.debug("External DHCP resource " + _name + " is ready");
+ return new ReadyAnswer(cmd);
+ }
+
+ @Override
+ public Answer executeRequest(Command cmd) {
+ if (cmd instanceof ReadyCommand) {
+ return execute((ReadyCommand) cmd);
+ } else {
+ return Answer.createUnsupportedCommandAnswer(cmd);
+ }
+ }
+
+ @Override
+ public void disconnected() {
+ }
+
+ @Override
+ public IAgentControl getAgentControl() {
+ return null;
+ }
+
+ @Override
+ public void setAgentControl(IAgentControl agentControl) {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpResponse.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpResponse.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpResponse.java
new file mode 100755
index 0000000..952ac41
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpResponse.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 BaremetalDhcpResponse 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.DHCP_SERVER_TYPE) @Param(description="name of the provider")
+ private String deviceType;
+
+ 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 getDeviceType() {
+ return deviceType;
+ }
+
+ public void setDeviceType(String deviceType) {
+ this.deviceType = deviceType;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java
new file mode 100755
index 0000000..a27a6f2
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpdResource.java
@@ -0,0 +1,139 @@
+// 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.HashMap;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingCommand;
+import com.cloud.agent.api.routing.DhcpEntryCommand;
+import com.cloud.utils.script.Script;
+import com.cloud.utils.ssh.SSHCmdHelper;
+import com.cloud.vm.VirtualMachine.State;
+import com.trilead.ssh2.SCPClient;
+
+public class BaremetalDhcpdResource extends BaremetalDhcpResourceBase {
+ private static final Logger s_logger = Logger.getLogger(BaremetalDhcpdResource.class);
+
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ com.trilead.ssh2.Connection sshConnection = null;
+ try {
+ super.configure(name, params);
+ s_logger.debug(String.format("Trying to connect to DHCP server(IP=%1$s, username=%2$s, password=%3$s)", _ip, _username, "******"));
+ sshConnection = SSHCmdHelper.acquireAuthorizedConnection(_ip, _username, _password);
+ if (sshConnection == null) {
+ throw new ConfigurationException(
+ String.format("Cannot connect to DHCP server(IP=%1$s, username=%2$s, password=%3$s", _ip, _username, "******"));
+ }
+
+ if (!SSHCmdHelper.sshExecuteCmd(sshConnection, "[ -f '/usr/sbin/dhcpd' ]")) {
+ throw new ConfigurationException("Cannot find dhcpd.conf /etc/dhcpd.conf at on " + _ip);
+ }
+
+ SCPClient scp = new SCPClient(sshConnection);
+
+ String editHosts = "scripts/network/exdhcp/dhcpd_edithosts.py";
+ String editHostsPath = Script.findScript("", editHosts);
+ if (editHostsPath == null) {
+ throw new ConfigurationException("Can not find script dnsmasq_edithosts.sh at " + editHosts);
+ }
+ scp.put(editHostsPath, "/usr/bin/", "0755");
+
+ String prepareDhcpdScript = "scripts/network/exdhcp/prepare_dhcpd.sh";
+ String prepareDhcpdScriptPath = Script.findScript("", prepareDhcpdScript);
+ if (prepareDhcpdScriptPath == null) {
+ throw new ConfigurationException("Can not find prepare_dhcpd.sh at " + prepareDhcpdScriptPath);
+ }
+ scp.put(prepareDhcpdScriptPath, "/usr/bin/", "0755");
+
+ //TODO: tooooooooooooooo ugly here!!!
+ String[] ips = _ip.split("\\.");
+ ips[3] = "0";
+ StringBuffer buf = new StringBuffer();
+ int i;
+ for (i=0;i<ips.length-1;i++) {
+ buf.append(ips[i]).append(".");
+ }
+ buf.append(ips[i]);
+ String subnet = buf.toString();
+ String cmd = String.format("sh /usr/bin/prepare_dhcpd.sh %1$s", subnet);
+ if (!SSHCmdHelper.sshExecuteCmd(sshConnection, cmd)) {
+ throw new ConfigurationException("prepare Dhcpd at " + _ip + " failed, command:" + cmd);
+ }
+
+ s_logger.debug("Dhcpd resource configure successfully");
+ return true;
+ } catch (Exception e) {
+ s_logger.debug("Dhcpd resorce configure failed", e);
+ throw new ConfigurationException(e.getMessage());
+ } finally {
+ SSHCmdHelper.releaseSshConnection(sshConnection);
+ }
+ }
+
+ @Override
+ public PingCommand getCurrentStatus(long id) {
+ com.trilead.ssh2.Connection sshConnection = SSHCmdHelper.acquireAuthorizedConnection(_ip, _username, _password);
+ if (sshConnection == null) {
+ return null;
+ } else {
+ SSHCmdHelper.releaseSshConnection(sshConnection);
+ return new PingRoutingCommand(getType(), id, new HashMap<String, State>());
+ }
+ }
+
+ Answer execute(DhcpEntryCommand cmd) {
+ com.trilead.ssh2.Connection sshConnection = null;
+ try {
+ sshConnection = SSHCmdHelper.acquireAuthorizedConnection(_ip, _username, _password);
+ if (sshConnection == null) {
+ return new Answer(cmd, false, "ssh authenticate failed");
+ }
+ String addDhcp = String.format("python /usr/bin/dhcpd_edithosts.py %1$s %2$s %3$s %4$s %5$s %6$s",
+ cmd.getVmMac(), cmd.getVmIpAddress(), cmd.getVmName(), cmd.getDns(), cmd.getGateway(), cmd.getNextServer());
+ if (!SSHCmdHelper.sshExecuteCmd(sshConnection, addDhcp)) {
+ return new Answer(cmd, false, "add Dhcp entry failed");
+ } else {
+ return new Answer(cmd);
+ }
+ } finally {
+ SSHCmdHelper.releaseSshConnection(sshConnection);
+ }
+ }
+
+ @Override
+ public Answer executeRequest(Command cmd) {
+ if (cmd instanceof DhcpEntryCommand) {
+ return execute((DhcpEntryCommand)cmd);
+ } else {
+ return super.executeRequest(cmd);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDnsmasqResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDnsmasqResource.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDnsmasqResource.java
new file mode 100644
index 0000000..6841c525
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDnsmasqResource.java
@@ -0,0 +1,129 @@
+// 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.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingCommand;
+import com.cloud.agent.api.routing.DhcpEntryCommand;
+import com.cloud.utils.script.Script;
+import com.cloud.utils.ssh.SSHCmdHelper;
+import com.cloud.vm.VirtualMachine.State;
+import com.trilead.ssh2.SCPClient;
+
+public class BaremetalDnsmasqResource extends BaremetalDhcpResourceBase {
+ private static final Logger s_logger = Logger.getLogger(BaremetalDnsmasqResource.class);
+
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ com.trilead.ssh2.Connection sshConnection = null;
+ try {
+ super.configure(name, params);
+ s_logger.debug(String.format("Trying to connect to DHCP server(IP=%1$s, username=%2$s, password=%3$s)", _ip, _username, _password));
+ sshConnection = SSHCmdHelper.acquireAuthorizedConnection(_ip, _username, _password);
+ if (sshConnection == null) {
+ throw new ConfigurationException(
+ String.format("Cannot connect to DHCP server(IP=%1$s, username=%2$s, password=%3$s", _ip, _username, _password));
+ }
+
+ if (!SSHCmdHelper.sshExecuteCmd(sshConnection, "[ -f '/usr/sbin/dnsmasq' ]")) {
+ throw new ConfigurationException("Cannot find dnsmasq at /usr/sbin/dnsmasq on " + _ip);
+ }
+
+ SCPClient scp = new SCPClient(sshConnection);
+
+ String editHosts = "scripts/network/exdhcp/dnsmasq_edithosts.sh";
+ String editHostsPath = Script.findScript("", editHosts);
+ if (editHostsPath == null) {
+ throw new ConfigurationException("Can not find script dnsmasq_edithosts.sh at " + editHosts);
+ }
+ scp.put(editHostsPath, "/usr/bin/", "0755");
+
+ String prepareDnsmasq = "scripts/network/exdhcp/prepare_dnsmasq.sh";
+ String prepareDnsmasqPath = Script.findScript("", prepareDnsmasq);
+ if (prepareDnsmasqPath == null) {
+ throw new ConfigurationException("Can not find script prepare_dnsmasq.sh at " + prepareDnsmasq);
+ }
+ scp.put(prepareDnsmasqPath, "/usr/bin/", "0755");
+
+ String prepareCmd = String.format("sh /usr/bin/prepare_dnsmasq.sh %1$s %2$s %3$s", _gateway, _dns, _ip);
+ if (!SSHCmdHelper.sshExecuteCmd(sshConnection, prepareCmd)) {
+ throw new ConfigurationException("prepare dnsmasq at " + _ip + " failed");
+ }
+
+ s_logger.debug("Dnsmasq resource configure successfully");
+ return true;
+ } catch (Exception e) {
+ s_logger.debug("Dnsmasq resorce configure failed", e);
+ throw new ConfigurationException(e.getMessage());
+ } finally {
+ SSHCmdHelper.releaseSshConnection(sshConnection);
+ }
+ }
+
+ @Override
+ public PingCommand getCurrentStatus(long id) {
+ com.trilead.ssh2.Connection sshConnection = SSHCmdHelper.acquireAuthorizedConnection(_ip, _username, _password);
+ if (sshConnection == null) {
+ return null;
+ } else {
+ SSHCmdHelper.releaseSshConnection(sshConnection);
+ return new PingRoutingCommand(getType(), id, new HashMap<String, State>());
+ }
+ }
+
+ Answer execute(DhcpEntryCommand cmd) {
+ com.trilead.ssh2.Connection sshConnection = null;
+ try {
+ sshConnection = SSHCmdHelper.acquireAuthorizedConnection(_ip, _username, _password);
+ if (sshConnection == null) {
+ return new Answer(cmd, false, "ssh authenticate failed");
+ }
+ String addDhcp = String.format("/usr/bin/dnsmasq_edithosts.sh %1$s %2$s %3$s", cmd.getVmMac(), cmd.getVmIpAddress(), cmd.getVmName());
+ if (!SSHCmdHelper.sshExecuteCmd(sshConnection, addDhcp)) {
+ return new Answer(cmd, false, "add Dhcp entry failed");
+ } else {
+ return new Answer(cmd);
+ }
+ } finally {
+ SSHCmdHelper.releaseSshConnection(sshConnection);
+ }
+ }
+
+ @Override
+ public Answer executeRequest(Command cmd) {
+ if (cmd instanceof DhcpEntryCommand) {
+ return execute((DhcpEntryCommand)cmd);
+ } else {
+ return super.executeRequest(cmd);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartPxeResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartPxeResource.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartPxeResource.java
new file mode 100755
index 0000000..938b3ac
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartPxeResource.java
@@ -0,0 +1,201 @@
+// 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 javax.naming.ConfigurationException;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingCommand;
+import com.cloud.agent.api.routing.VmDataCommand;
+import com.cloud.utils.script.Script;
+import com.cloud.utils.ssh.SSHCmdHelper;
+import com.cloud.vm.VirtualMachine.State;
+import com.trilead.ssh2.SCPClient;
+
+public class BaremetalKickStartPxeResource extends BaremetalPxeResourceBase {
+ private static final Logger s_logger = Logger.getLogger(BaremetalKickStartPxeResource.class);
+ private static final String _name = "BaremetalKickStartPxeResource";
+ String _tftpDir;
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ super.configure(name, params);
+ _tftpDir = (String) params.get(BaremetalPxeService.PXE_PARAM_TFTP_DIR);
+ if (_tftpDir == null) {
+ throw new ConfigurationException("No tftp directory specified");
+ }
+
+ com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_ip, 22);
+
+ s_logger.debug(String.format("Trying to connect to kickstart PXE server(IP=%1$s, username=%2$s, password=%3$s", _ip, _username, "******"));
+ try {
+ sshConnection.connect(null, 60000, 60000);
+ if (!sshConnection.authenticateWithPassword(_username, _password)) {
+ s_logger.debug("SSH Failed to authenticate");
+ throw new ConfigurationException(String.format("Cannot connect to kickstart PXE server(IP=%1$s, username=%2$s, password=%3$s", _ip, _username,
+ "******"));
+ }
+
+ String cmd = String.format("[ -f /%1$s/pxelinux.0 ]", _tftpDir);
+ if (!SSHCmdHelper.sshExecuteCmd(sshConnection, cmd)) {
+ throw new ConfigurationException("Miss files in TFTP directory at " + _tftpDir + " check if pxelinux.0 are here");
+ }
+
+ SCPClient scp = new SCPClient(sshConnection);
+ String prepareScript = "scripts/network/ping/prepare_kickstart_bootfile.py";
+ String prepareScriptPath = Script.findScript("", prepareScript);
+ if (prepareScriptPath == null) {
+ throw new ConfigurationException("Can not find prepare_kickstart_bootfile.py at " + prepareScriptPath);
+ }
+ scp.put(prepareScriptPath, "/usr/bin/", "0755");
+
+ String cpScript = "scripts/network/ping/prepare_kickstart_kernel_initrd.py";
+ String cpScriptPath = Script.findScript("", cpScript);
+ if (cpScriptPath == null) {
+ throw new ConfigurationException("Can not find prepare_kickstart_kernel_initrd.py at " + cpScriptPath);
+ }
+ scp.put(cpScriptPath, "/usr/bin/", "0755");
+
+ String userDataScript = "scripts/network/ping/baremetal_user_data.py";
+ String userDataScriptPath = Script.findScript("", userDataScript);
+ if (userDataScriptPath == null) {
+ throw new ConfigurationException("Can not find baremetal_user_data.py at " + userDataScriptPath);
+ }
+ scp.put(userDataScriptPath, "/usr/bin/", "0755");
+
+ return true;
+ } catch (Exception e) {
+ throw new ConfigurationException(e.getMessage());
+ } finally {
+ if (sshConnection != null) {
+ sshConnection.close();
+ }
+ }
+ }
+
+ @Override
+ public PingCommand getCurrentStatus(long id) {
+ com.trilead.ssh2.Connection sshConnection = SSHCmdHelper.acquireAuthorizedConnection(_ip, _username, _password);
+ if (sshConnection == null) {
+ return null;
+ } else {
+ SSHCmdHelper.releaseSshConnection(sshConnection);
+ return new PingRoutingCommand(getType(), id, new HashMap<String, State>());
+ }
+ }
+
+ private Answer execute(VmDataCommand cmd) {
+ com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_ip, 22);
+ try {
+ List<String[]> vmData = cmd.getVmData();
+ StringBuilder sb = new StringBuilder();
+ for (String[] data : vmData) {
+ String folder = data[0];
+ String file = data[1];
+ String contents = (data[2] == null) ? "none" : data[2];
+ sb.append(cmd.getVmIpAddress());
+ sb.append(",");
+ sb.append(folder);
+ sb.append(",");
+ sb.append(file);
+ sb.append(",");
+ sb.append(contents);
+ sb.append(";");
+ }
+ String arg = StringUtils.stripEnd(sb.toString(), ";");
+
+ sshConnection.connect(null, 60000, 60000);
+ if (!sshConnection.authenticateWithPassword(_username, _password)) {
+ s_logger.debug("SSH Failed to authenticate");
+ throw new ConfigurationException(String.format("Cannot connect to PING PXE server(IP=%1$s, username=%2$s, password=%3$s", _ip, _username,
+ _password));
+ }
+
+ String script = String.format("python /usr/bin/baremetal_user_data.py '%s'", arg);
+ if (!SSHCmdHelper.sshExecuteCmd(sshConnection, script)) {
+ return new Answer(cmd, false, "Failed to add user data, command:" + script);
+ }
+
+ return new Answer(cmd, true, "Success");
+ } catch (Exception e){
+ s_logger.debug("Prepare for creating baremetal template failed", e);
+ return new Answer(cmd, false, e.getMessage());
+ } finally {
+ if (sshConnection != null) {
+ sshConnection.close();
+ }
+ }
+ }
+
+ @Override
+ public Answer executeRequest(Command cmd) {
+ if (cmd instanceof PrepareKickstartPxeServerCommand) {
+ return execute((PrepareKickstartPxeServerCommand) cmd);
+ } else if (cmd instanceof VmDataCommand) {
+ return execute((VmDataCommand)cmd);
+ } else {
+ return super.executeRequest(cmd);
+ }
+ }
+
+ private Answer execute(PrepareKickstartPxeServerCommand cmd) {
+ com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_ip, 22);
+ try {
+ sshConnection.connect(null, 60000, 60000);
+ if (!sshConnection.authenticateWithPassword(_username, _password)) {
+ s_logger.debug("SSH Failed to authenticate");
+ throw new ConfigurationException(String.format("Cannot connect to PING PXE server(IP=%1$s, username=%2$s, password=%3$s", _ip, _username,
+ _password));
+ }
+
+ String copyTo = String.format("%s/%s", _tftpDir, cmd.getTemplateUuid());
+ String script = String.format("python /usr/bin/prepare_kickstart_kernel_initrd.py %s %s", cmd.getRepo(), copyTo);
+
+ if (!SSHCmdHelper.sshExecuteCmd(sshConnection, script)) {
+ return new Answer(cmd, false, "prepare kickstart at pxe server " + _ip + " failed, command:" + script);
+ }
+
+ String kernelPath = String.format("%s/vmlinuz", cmd.getTemplateUuid());
+ String initrdPath = String.format("%s/initrd.img", cmd.getTemplateUuid());
+ script = String.format("python /usr/bin/prepare_kickstart_bootfile.py %s %s %s %s %s %s", _tftpDir, cmd.getMac(), kernelPath, initrdPath, cmd.getKsFile(), cmd.getMac());
+ if (!SSHCmdHelper.sshExecuteCmd(sshConnection, script)) {
+ return new Answer(cmd, false, "prepare kickstart at pxe server " + _ip + " failed, command:" + script);
+ }
+
+ s_logger.debug("Prepare kickstart PXE server successfully");
+ return new Answer(cmd, true, "Success");
+ } catch (Exception e){
+ s_logger.debug("Prepare for kickstart server failed", e);
+ return new Answer(cmd, false, e.getMessage());
+ } finally {
+ if (sshConnection != null) {
+ sshConnection.close();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/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
new file mode 100755
index 0000000..4a2369b
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java
@@ -0,0 +1,238 @@
+// 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.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.baremetal.IpmISetBootDevCommand;
+import com.cloud.agent.api.baremetal.IpmISetBootDevCommand.BootDev;
+import com.cloud.baremetal.database.BaremetalPxeDao;
+import com.cloud.baremetal.database.BaremetalPxeVO;
+import com.cloud.baremetal.networkservice.BaremetalPxeManager.BaremetalPxeType;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDetailsDao;
+import com.cloud.network.NetworkVO;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.PhysicalNetworkVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ServerResource;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.SearchCriteria2;
+import com.cloud.utils.db.SearchCriteriaService;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Local(value = BaremetalPxeService.class)
+public class BaremetalKickStartServiceImpl extends BareMetalPxeServiceBase implements BaremetalPxeService {
+ private static final Logger s_logger = Logger.getLogger(BaremetalKickStartServiceImpl.class);
+ @Inject
+ ResourceManager _resourceMgr;
+ @Inject
+ PhysicalNetworkDao _physicalNetworkDao;
+ @Inject
+ PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
+ @Inject
+ HostDetailsDao _hostDetailsDao;
+ @Inject
+ BaremetalPxeDao _pxeDao;
+ @Inject
+ NetworkDao _nwDao;
+ @Inject
+ VMTemplateDao _tmpDao;
+
+ @Override
+ public boolean prepare(VirtualMachineProfile<UserVmVO> profile, NicProfile nic, DeployDestination dest, ReservationContext context) {
+ NetworkVO nwVO = _nwDao.findById(nic.getNetworkId());
+ SearchCriteriaService<BaremetalPxeVO, BaremetalPxeVO> sc = SearchCriteria2.create(BaremetalPxeVO.class);
+ sc.addAnd(sc.getEntity().getDeviceType(), Op.EQ, BaremetalPxeType.KICK_START.toString());
+ sc.addAnd(sc.getEntity().getPhysicalNetworkId(), Op.EQ, nwVO.getPhysicalNetworkId());
+ BaremetalPxeVO pxeVo = sc.find();
+ if (pxeVo == null) {
+ throw new CloudRuntimeException("No kickstart PXE server found in pod: " + dest.getPod().getId() + ", you need to add it before starting VM");
+ }
+ VMTemplateVO template = _tmpDao.findById(profile.getTemplateId());
+
+ try {
+ String tpl = profile.getTemplate().getUrl();
+ assert tpl != null : "How can a null template get here!!!";
+ String[] tpls = tpl.split(";");
+ assert tpls.length == 2 : "Template is not correctly encoded. " + tpl;
+ PrepareKickstartPxeServerCommand cmd = new PrepareKickstartPxeServerCommand();
+ cmd.setKsFile(tpls[0]);
+ cmd.setRepo(tpls[1]);
+ 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);
+ if (!aws.getResult()) {
+ s_logger.warn("Unable to set host: " + dest.getHost().getId() + " to PXE boot because " + aws.getDetails());
+ }
+
+ return aws.getResult();
+ } catch (Exception e) {
+ s_logger.warn("Cannot prepare PXE server", e);
+ return false;
+ }
+ }
+
+ @Override
+ public boolean prepareCreateTemplate(Long pxeServerId, UserVm vm, String templateUrl) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ @DB
+ public BaremetalPxeVO addPxeServer(AddBaremetalPxeCmd cmd) {
+ AddBaremetalKickStartPxeCmd kcmd = (AddBaremetalKickStartPxeCmd)cmd;
+ PhysicalNetworkVO pNetwork = null;
+ long zoneId;
+
+ if (cmd.getPhysicalNetworkId() == null || cmd.getUrl() == null || cmd.getUsername() == null || cmd.getPassword() == null) {
+ throw new IllegalArgumentException("At least one of the required parameters(physical network id, url, username, password) is null");
+ }
+
+ pNetwork = _physicalNetworkDao.findById(cmd.getPhysicalNetworkId());
+ if (pNetwork == null) {
+ throw new IllegalArgumentException("Could not find phyical network with ID: " + cmd.getPhysicalNetworkId());
+ }
+ zoneId = pNetwork.getDataCenterId();
+
+ PhysicalNetworkServiceProviderVO ntwkSvcProvider = _physicalNetworkServiceProviderDao.findByServiceProvider(pNetwork.getId(), BaremetalPxeManager.BAREMETAL_PXE_SERVICE_PROVIDER.getName());
+ if (ntwkSvcProvider == null) {
+ throw new CloudRuntimeException("Network Service Provider: " + BaremetalPxeManager.BAREMETAL_PXE_SERVICE_PROVIDER.getName() +
+ " is not enabled in the physical network: " + cmd.getPhysicalNetworkId() + "to add this device");
+ } else if (ntwkSvcProvider.getState() == PhysicalNetworkServiceProvider.State.Shutdown) {
+ throw new CloudRuntimeException("Network Service Provider: " + ntwkSvcProvider.getProviderName() +
+ " is in shutdown state in the physical network: " + cmd.getPhysicalNetworkId() + "to add this device");
+ }
+
+ List<HostVO> pxes = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.BaremetalPxe, zoneId);
+ if (!pxes.isEmpty()) {
+ throw new IllegalArgumentException("Already had a PXE server zone: " + zoneId);
+ }
+
+ String tftpDir = kcmd.getTftpDir();
+ if (tftpDir == null) {
+ throw new IllegalArgumentException("No TFTP directory specified");
+ }
+
+ URI uri;
+ try {
+ uri = new URI(cmd.getUrl());
+ } catch (Exception e) {
+ s_logger.debug(e);
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ String ipAddress = uri.getHost();
+
+ String guid = getPxeServerGuid(Long.toString(zoneId), BaremetalPxeType.KICK_START.toString(), ipAddress);
+
+ ServerResource resource = null;
+ Map params = new HashMap<String, String>();
+ params.put(BaremetalPxeService.PXE_PARAM_ZONE, Long.toString(zoneId));
+ params.put(BaremetalPxeService.PXE_PARAM_IP, ipAddress);
+ params.put(BaremetalPxeService.PXE_PARAM_USERNAME, cmd.getUsername());
+ params.put(BaremetalPxeService.PXE_PARAM_PASSWORD, cmd.getPassword());
+ params.put(BaremetalPxeService.PXE_PARAM_TFTP_DIR, tftpDir);
+ params.put(BaremetalPxeService.PXE_PARAM_GUID, guid);
+ resource = new BaremetalKickStartPxeResource();
+ try {
+ resource.configure("KickStart PXE resource", params);
+ } catch (Exception e) {
+ throw new CloudRuntimeException(e.getMessage(), e);
+ }
+
+ Host pxeServer = _resourceMgr.addHost(zoneId, resource, Host.Type.BaremetalPxe, params);
+ if (pxeServer == null) {
+ throw new CloudRuntimeException("Cannot add PXE server as a host");
+ }
+
+ BaremetalPxeVO vo = new BaremetalPxeVO();
+ Transaction txn = Transaction.currentTxn();
+ vo.setHostId(pxeServer.getId());
+ vo.setNetworkServiceProviderId(ntwkSvcProvider.getId());
+ vo.setPhysicalNetworkId(kcmd.getPhysicalNetworkId());
+ vo.setDeviceType(BaremetalPxeType.KICK_START.toString());
+ txn.start();
+ _pxeDao.persist(vo);
+ txn.commit();
+ return vo;
+ }
+
+ @Override
+ public BaremetalPxeResponse getApiResponse(BaremetalPxeVO vo) {
+ BaremetalPxeKickStartResponse response = new BaremetalPxeKickStartResponse();
+ response.setId(String.valueOf(vo.getId()));
+ response.setPhysicalNetworkId(String.valueOf(vo.getPhysicalNetworkId()));
+ response.setPodId(String.valueOf(vo.getPodId()));
+ Map<String, String> details = _hostDetailsDao.findDetails(vo.getHostId());
+ response.setTftpDir(details.get(BaremetalPxeService.PXE_PARAM_TFTP_DIR));
+ return response;
+ }
+
+ @Override
+ public List<BaremetalPxeResponse> listPxeServers(ListBaremetalPxePingServersCmd cmd) {
+ SearchCriteriaService<BaremetalPxeVO, BaremetalPxeVO> sc = SearchCriteria2.create(BaremetalPxeVO.class);
+ sc.addAnd(sc.getEntity().getDeviceType(), Op.EQ, BaremetalPxeType.KICK_START.toString());
+ if (cmd.getPodId() != null) {
+ sc.addAnd(sc.getEntity().getPodId(), Op.EQ, cmd.getPodId());
+ if (cmd.getId() != null) {
+ sc.addAnd(sc.getEntity().getId(), Op.EQ, cmd.getId());
+ }
+ }
+ List<BaremetalPxeVO> vos = sc.list();
+ List<BaremetalPxeResponse> responses = new ArrayList<BaremetalPxeResponse>(vos.size());
+ for (BaremetalPxeVO vo : vos) {
+ responses.add(getApiResponse(vo));
+ }
+ return responses;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPingPxeResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPingPxeResource.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPingPxeResource.java
new file mode 100755
index 0000000..2fb5415
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPingPxeResource.java
@@ -0,0 +1,260 @@
+// 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.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingCommand;
+import com.cloud.agent.api.baremetal.PreparePxeServerAnswer;
+import com.cloud.agent.api.baremetal.PreparePxeServerCommand;
+import com.cloud.agent.api.baremetal.prepareCreateTemplateCommand;
+import com.cloud.agent.api.routing.VmDataCommand;
+import com.cloud.utils.script.Script;
+import com.cloud.utils.ssh.SSHCmdHelper;
+import com.cloud.vm.VirtualMachine.State;
+import com.trilead.ssh2.SCPClient;
+
+public class BaremetalPingPxeResource extends BaremetalPxeResourceBase {
+ private static final Logger s_logger = Logger.getLogger(BaremetalPingPxeResource.class);
+ private static final String _name = "BaremetalPingPxeResource";
+ String _storageServer;
+ String _pingDir;
+ String _share;
+ String _dir;
+ String _tftpDir;
+ String _cifsUserName;
+ String _cifsPassword;
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ super.configure(name, params);
+ _storageServer = (String)params.get(BaremetalPxeService.PXE_PARAM_PING_STORAGE_SERVER_IP);
+ _pingDir = (String)params.get(BaremetalPxeService.PXE_PARAM_PING_ROOT_DIR);
+ _tftpDir = (String)params.get(BaremetalPxeService.PXE_PARAM_TFTP_DIR);
+ _cifsUserName = (String)params.get(BaremetalPxeService.PXE_PARAM_PING_STORAGE_SERVER_USERNAME);
+ _cifsPassword = (String)params.get(BaremetalPxeService.PXE_PARAM_PING_STORAGE_SERVER_PASSWORD);
+
+ if (_podId == null) {
+ throw new ConfigurationException("No Pod specified");
+ }
+
+ if (_storageServer == null) {
+ throw new ConfigurationException("No stroage server specified");
+ }
+
+ if (_tftpDir == null) {
+ throw new ConfigurationException("No tftp directory specified");
+ }
+
+ if (_pingDir == null) {
+ throw new ConfigurationException("No PING directory specified");
+ }
+
+ if (_cifsUserName == null || _cifsUserName.equalsIgnoreCase("")) {
+ _cifsUserName = "xxx";
+ }
+
+ if (_cifsPassword == null || _cifsPassword.equalsIgnoreCase("")) {
+ _cifsPassword = "xxx";
+ }
+
+ String pingDirs[]= _pingDir.split("/");
+ if (pingDirs.length != 2) {
+ throw new ConfigurationException("PING dir should have format like myshare/direcotry, eg: windows/64bit");
+ }
+ _share = pingDirs[0];
+ _dir = pingDirs[1];
+
+ com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_ip, 22);
+
+ s_logger.debug(String.format("Trying to connect to PING PXE server(IP=%1$s, username=%2$s, password=%3$s", _ip, _username, "******"));
+ try {
+ sshConnection.connect(null, 60000, 60000);
+ if (!sshConnection.authenticateWithPassword(_username, _password)) {
+ s_logger.debug("SSH Failed to authenticate");
+ throw new ConfigurationException(String.format("Cannot connect to PING PXE server(IP=%1$s, username=%2$s, password=%3$s", _ip, _username,
+ "******"));
+ }
+
+ String cmd = String.format("[ -f /%1$s/pxelinux.0 ] && [ -f /%2$s/kernel ] && [ -f /%3$s/initrd.gz ] ", _tftpDir, _tftpDir, _tftpDir);
+ if (!SSHCmdHelper.sshExecuteCmd(sshConnection, cmd)) {
+ throw new ConfigurationException("Miss files in TFTP directory at " + _tftpDir + " check if pxelinux.0, kernel initrd.gz are here");
+ }
+
+ SCPClient scp = new SCPClient(sshConnection);
+ String prepareScript = "scripts/network/ping/prepare_tftp_bootfile.py";
+ String prepareScriptPath = Script.findScript("", prepareScript);
+ if (prepareScriptPath == null) {
+ throw new ConfigurationException("Can not find prepare_tftp_bootfile.py at " + prepareScriptPath);
+ }
+ scp.put(prepareScriptPath, "/usr/bin/", "0755");
+
+ String userDataScript = "scripts/network/ping/baremetal_user_data.py";
+ String userDataScriptPath = Script.findScript("", userDataScript);
+ if (userDataScriptPath == null) {
+ throw new ConfigurationException("Can not find baremetal_user_data.py at " + userDataScriptPath);
+ }
+ scp.put(userDataScriptPath, "/usr/bin/", "0755");
+
+ return true;
+ } catch (Exception e) {
+ throw new ConfigurationException(e.getMessage());
+ } finally {
+ if (sshConnection != null) {
+ sshConnection.close();
+ }
+ }
+ }
+
+ @Override
+ public PingCommand getCurrentStatus(long id) {
+ com.trilead.ssh2.Connection sshConnection = SSHCmdHelper.acquireAuthorizedConnection(_ip, _username, _password);
+ if (sshConnection == null) {
+ return null;
+ } else {
+ SSHCmdHelper.releaseSshConnection(sshConnection);
+ return new PingRoutingCommand(getType(), id, new HashMap<String, State>());
+ }
+ }
+
+ protected PreparePxeServerAnswer execute(PreparePxeServerCommand cmd) {
+ com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_ip, 22);
+ try {
+ sshConnection.connect(null, 60000, 60000);
+ if (!sshConnection.authenticateWithPassword(_username, _password)) {
+ s_logger.debug("SSH Failed to authenticate");
+ throw new ConfigurationException(String.format("Cannot connect to PING PXE server(IP=%1$s, username=%2$s, password=%3$s", _ip, _username,
+ _password));
+ }
+
+ String script = String.format("python /usr/bin/prepare_tftp_bootfile.py restore %1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s %10$s %11$s",
+ _tftpDir, cmd.getMac(), _storageServer, _share, _dir, cmd.getTemplate(), _cifsUserName, _cifsPassword, cmd.getIp(), cmd.getNetMask(), cmd.getGateWay());
+ if (!SSHCmdHelper.sshExecuteCmd(sshConnection, script)) {
+ return new PreparePxeServerAnswer(cmd, "prepare PING at " + _ip + " failed, command:" + script);
+ }
+ s_logger.debug("Prepare Ping PXE server successfully");
+
+ return new PreparePxeServerAnswer(cmd);
+ } catch (Exception e){
+ s_logger.debug("Prepare PING pxe server failed", e);
+ return new PreparePxeServerAnswer(cmd, e.getMessage());
+ } finally {
+ if (sshConnection != null) {
+ sshConnection.close();
+ }
+ }
+ }
+
+ protected Answer execute(prepareCreateTemplateCommand cmd) {
+ com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_ip, 22);
+ try {
+ sshConnection.connect(null, 60000, 60000);
+ if (!sshConnection.authenticateWithPassword(_username, _password)) {
+ s_logger.debug("SSH Failed to authenticate");
+ throw new ConfigurationException(String.format("Cannot connect to PING PXE server(IP=%1$s, username=%2$s, password=%3$s", _ip, _username,
+ _password));
+ }
+
+ String script = String.format("python /usr/bin/prepare_tftp_bootfile.py backup %1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s %10$s %11$s",
+ _tftpDir, cmd.getMac(), _storageServer, _share, _dir, cmd.getTemplate(), _cifsUserName, _cifsPassword, cmd.getIp(), cmd.getNetMask(), cmd.getGateWay());
+ if (!SSHCmdHelper.sshExecuteCmd(sshConnection, script)) {
+ return new Answer(cmd, false, "prepare for creating template failed, command:" + script);
+ }
+ s_logger.debug("Prepare for creating template successfully");
+
+ return new Answer(cmd, true, "Success");
+ } catch (Exception e){
+ s_logger.debug("Prepare for creating baremetal template failed", e);
+ return new Answer(cmd, false, e.getMessage());
+ } finally {
+ if (sshConnection != null) {
+ sshConnection.close();
+ }
+ }
+ }
+
+ @Override
+ public Answer executeRequest(Command cmd) {
+ if (cmd instanceof PreparePxeServerCommand) {
+ return execute((PreparePxeServerCommand) cmd);
+ } else if (cmd instanceof prepareCreateTemplateCommand) {
+ return execute((prepareCreateTemplateCommand)cmd);
+ } else if (cmd instanceof VmDataCommand) {
+ return execute((VmDataCommand)cmd);
+ } else {
+ return super.executeRequest(cmd);
+ }
+ }
+
+ private Answer execute(VmDataCommand cmd) {
+ com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(_ip, 22);
+ try {
+ List<String[]> vmData = cmd.getVmData();
+ StringBuilder sb = new StringBuilder();
+ for (String[] data : vmData) {
+ String folder = data[0];
+ String file = data[1];
+ String contents = (data[2] == null) ? "none" : data[2];
+ sb.append(cmd.getVmIpAddress());
+ sb.append(",");
+ sb.append(folder);
+ sb.append(",");
+ sb.append(file);
+ sb.append(",");
+ sb.append(contents);
+ sb.append(";");
+ }
+ String arg = org.apache.commons.lang.StringUtils.stripEnd(sb.toString(), ";");
+
+ sshConnection.connect(null, 60000, 60000);
+ if (!sshConnection.authenticateWithPassword(_username, _password)) {
+ s_logger.debug("SSH Failed to authenticate");
+ throw new ConfigurationException(String.format("Cannot connect to PING PXE server(IP=%1$s, username=%2$s, password=%3$s", _ip, _username,
+ _password));
+ }
+
+ String script = String.format("python /usr/bin/baremetal_user_data.py '%s'", arg);
+ if (!SSHCmdHelper.sshExecuteCmd(sshConnection, script)) {
+ return new Answer(cmd, false, "Failed to add user data, command:" + script);
+ }
+
+ return new Answer(cmd, true, "Success");
+ } catch (Exception e){
+ s_logger.debug("Prepare for creating baremetal template failed", e);
+ return new Answer(cmd, false, e.getMessage());
+ } finally {
+ if (sshConnection != null) {
+ sshConnection.close();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/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
new file mode 100755
index 0000000..99b9c43
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
@@ -0,0 +1,178 @@
+// 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.Map;
+import java.util.Set;
+
+import javax.ejb.Local;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.baremetal.database.BaremetalPxeVO;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.Pod;
+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.NetworkElement;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.SearchCriteria2;
+import com.cloud.utils.db.SearchCriteriaService;
+import com.cloud.utils.db.Transaction;
+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.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Type;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+@Local(value = NetworkElement.class)
+public class BaremetalPxeElement extends AdapterBase implements NetworkElement {
+ private static final Logger s_logger = Logger.getLogger(BaremetalPxeElement.class);
+ private static final Map<Service, Map<Capability, String>> capabilities;
+
+ @Inject BaremetalPxeManager _pxeMgr;;
+ @Inject VMInstanceDao _vmDao;
+ @Inject NicDao _nicDao;
+
+ static {
+ Capability cap = new Capability(BaremetalPxeManager.BAREMETAL_PXE_CAPABILITY);
+ Map<Capability, String> baremetalCaps = new HashMap<Capability, String>();
+ baremetalCaps.put(cap, null);
+ capabilities = new HashMap<Service, Map<Capability, String>>();
+ capabilities.put(BaremetalPxeManager.BAREMETAL_PXE_SERVICE, baremetalCaps);
+ }
+
+ @Override
+ public Map<Service, Map<Capability, String>> getCapabilities() {
+ return capabilities;
+ }
+
+ @Override
+ public Provider getProvider() {
+ return BaremetalPxeManager.BAREMETAL_PXE_SERVICE_PROVIDER;
+ }
+
+ private boolean canHandle(DeployDestination dest, TrafficType trafficType, GuestType networkType) {
+ Pod pod = dest.getPod();
+ if (pod != null && dest.getDataCenter().getNetworkType() == NetworkType.Basic && trafficType == TrafficType.Guest) {
+ SearchCriteriaService<BaremetalPxeVO, BaremetalPxeVO> sc = SearchCriteria2.create(BaremetalPxeVO.class);
+ sc.addAnd(sc.getEntity().getPodId(), Op.EQ, pod.getId());
+ return sc.find() != null;
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context)
+ throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+ if (offering.isSystemOnly() || !canHandle(dest, offering.getTrafficType(), network.getGuestType())) {
+ s_logger.debug("BaremetalPxeElement can not handle network offering: " + offering.getName());
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ @DB
+ public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest,
+ ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+ if (vm.getType() != Type.User || vm.getHypervisorType() != HypervisorType.BareMetal) {
+ return false;
+ }
+
+ VMInstanceVO vo = _vmDao.findById(vm.getId());
+ if (vo.getLastHostId() == null) {
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ nic.setMacAddress(dest.getHost().getPrivateMacAddress());
+ NicVO nicVo = _nicDao.findById(nic.getId());
+ assert vo != null : "Where ths nic " + nic.getId() + " going???";
+ nicVo.setMacAddress(nic.getMacAddress());
+ _nicDao.update(nicVo.getId(), nicVo);
+ txn.commit();
+
+ /*This vm is just being created */
+ if (!_pxeMgr.prepare(vm, nic, dest, context)) {
+ throw new CloudRuntimeException("Cannot prepare pxe server");
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean release(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, ReservationContext context)
+ throws ConcurrentOperationException, ResourceUnavailableException {
+ return true;
+ }
+
+ @Override
+ public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
+ return true;
+ }
+
+ @Override
+ public boolean isReady(PhysicalNetworkServiceProvider provider) {
+ return true;
+ }
+
+ @Override
+ public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException,
+ ResourceUnavailableException {
+ return true;
+ }
+
+ @Override
+ public boolean canEnableIndividualServices() {
+ 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/BaremetalPxeKickStartResponse.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeKickStartResponse.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeKickStartResponse.java
new file mode 100755
index 0000000..09c6cc6
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeKickStartResponse.java
@@ -0,0 +1,37 @@
+// 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 BaremetalPxeKickStartResponse extends BaremetalPxeResponse {
+ @SerializedName(ApiConstants.TFTP_DIR) @Param(description="Tftp root directory of PXE server")
+ private String tftpDir;
+
+ 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/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
new file mode 100755
index 0000000..e0a5162
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManager.java
@@ -0,0 +1,65 @@
+// 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.HostVO;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Provider;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.component.Manager;
+import com.cloud.utils.component.PluggableService;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachineProfile;
+
+public interface BaremetalPxeManager extends Manager, PluggableService {
+ public enum BaremetalPxeType {
+ PING,
+ KICK_START,
+ }
+
+ boolean prepare(VirtualMachineProfile profile, NicProfile nic, DeployDestination dest, ReservationContext context);
+
+ boolean prepareCreateTemplate(Long pxeServerId, UserVm vm, String templateUrl);
+
+ BaremetalPxeType getPxeServerType(HostVO host);
+
+ BaremetalPxeVO addPxeServer(AddBaremetalPxeCmd cmd);
+
+ BaremetalPxeResponse getApiResponse(BaremetalPxeVO vo);
+
+ List<BaremetalPxeResponse> listPxeServers(ListBaremetalPxePingServersCmd cmd);
+
+ boolean addUserData(NicProfile nic, VirtualMachineProfile<UserVm> vm);
+
+ public static final Network.Service BAREMETAL_PXE_SERVICE = new Network.Service("BaremetalPxeService");
+ public static final String BAREMETAL_PXE_CAPABILITY = "BaremetalPxe";
+ public static final String BAREMETAL_PXE_SERVICE_PROPERTIES = "baremetalpxe_commands.properties";
+ public static final Provider BAREMETAL_PXE_SERVICE_PROVIDER = new Provider("BaremetalPxeProvider", true);;
+ public static final Provider BAREMETAL_USERDATA_PROVIDER = new Provider("BaremetaUserdataProvider", true);
+}