You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ml...@apache.org on 2013/01/30 21:55:08 UTC
[41/50] 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/manager/BaremetalManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java
new file mode 100755
index 0000000..5388864
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManagerImpl.java
@@ -0,0 +1,112 @@
+// 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.manager;
+
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.StopAnswer;
+import com.cloud.agent.manager.Commands;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.fsm.StateListener;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineGuru;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.VirtualMachineName;
+import com.cloud.vm.VirtualMachine.Event;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Local(value = {BaremetalManager.class})
+public class BaremetalManagerImpl implements BaremetalManager, StateListener<State, VirtualMachine.Event, VirtualMachine> {
+ private static final Logger s_logger = Logger.getLogger(BaremetalManagerImpl.class);
+
+ @Inject
+ protected HostDao _hostDao;
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ VirtualMachine.State.getStateMachine().registerListener(this);
+ return true;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return "Baremetal Manager";
+ }
+
+ @Override
+ public boolean preStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) {
+ return false;
+ }
+
+ @Override
+ public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) {
+ if (newState != State.Starting && newState != State.Error && newState != State.Expunging) {
+ return true;
+ }
+
+ if (vo.getHypervisorType() != HypervisorType.BareMetal) {
+ return true;
+ }
+
+ HostVO host = _hostDao.findById(vo.getHostId());
+ if (host == null) {
+ s_logger.debug("Skip oldState " + oldState + " to " + "newState " + newState + " transimtion");
+ return true;
+ }
+ _hostDao.loadDetails(host);
+
+ if (newState == State.Starting) {
+ host.setDetail("vmName", vo.getInstanceName());
+ s_logger.debug("Add vmName " + host.getDetail("vmName") + " to host " + host.getId() + " details");
+ } else {
+ if (host.getDetail("vmName") != null && host.getDetail("vmName").equalsIgnoreCase(vo.getInstanceName())) {
+ s_logger.debug("Remove vmName " + host.getDetail("vmName") + " from host " + host.getId() + " details");
+ host.getDetails().remove("vmName");
+ }
+ }
+ _hostDao.saveDetails(host);
+
+
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalDhcpCmd.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalDhcpCmd.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalDhcpCmd.java
new file mode 100755
index 0000000..6a26fe2
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalDhcpCmd.java
@@ -0,0 +1,149 @@
+// 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.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseCmd.CommandType;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.PlugService;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.log4j.Logger;
+
+import com.cloud.baremetal.database.BaremetalDhcpVO;
+import com.cloud.event.EventTypes;
+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;
+import com.cloud.user.UserContext;
+
+public class AddBaremetalDhcpCmd extends BaseAsyncCmd {
+ private static final String s_name = "addexternaldhcpresponse";
+ public static final Logger s_logger = Logger.getLogger(AddBaremetalDhcpCmd.class);
+
+ @PlugService BaremetalDhcpManager mgr;
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+ @Parameter(name=ApiConstants.PHYSICAL_NETWORK_ID, type=CommandType.LONG, required=true, description="the Physical Network ID")
+ private Long physicalNetworkId;
+
+ @Parameter(name=ApiConstants.POD_ID, type=CommandType.LONG, required = true, description="Pod Id")
+ private Long podId;
+
+ @Parameter(name=ApiConstants.DHCP_SERVER_TYPE, type=CommandType.STRING, required = true, description="Type of dhcp device")
+ private String dhcpType;
+
+ @Parameter(name=ApiConstants.URL, type=CommandType.STRING, required = true, description="URL of the external dhcp appliance.")
+ private String url;
+
+ @Parameter(name=ApiConstants.USERNAME, type=CommandType.STRING, required = true, description="Credentials to reach external dhcp device")
+ private String username;
+
+ @Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, required = true, description="Credentials to reach external dhcp device")
+ private String password;
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_BAREMETAL_DHCP_SERVER_ADD;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Adding an external DHCP server";
+ }
+
+ @Override
+ public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
+ ResourceAllocationException, NetworkRuleConflictException {
+ try {
+ BaremetalDhcpVO vo = mgr.addDchpServer(this);
+ BaremetalDhcpResponse response = mgr.generateApiResponse(vo);
+ response.setObjectName(s_name);
+ response.setResponseName(getCommandName());
+ this.setResponseObject(response);
+ } catch (Exception e) {
+ s_logger.warn("Unable to add external dhcp server with url: " + getUrl(), e);
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+ }
+ }
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return UserContext.current().getCaller().getId();
+ }
+
+ public Long getPodId() {
+ return podId;
+ }
+
+ public void setPodId(Long podId) {
+ this.podId = podId;
+ }
+
+ public String getDhcpType() {
+ return dhcpType;
+ }
+
+ public void setDhcpType(String dhcpType) {
+ this.dhcpType = dhcpType;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public Long getPhysicalNetworkId() {
+ return physicalNetworkId;
+ }
+
+ public void setPhysicalNetworkId(Long physicalNetworkId) {
+ this.physicalNetworkId = physicalNetworkId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalKickStartPxeCmd.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalKickStartPxeCmd.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalKickStartPxeCmd.java
new file mode 100755
index 0000000..4c3d0b2
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalKickStartPxeCmd.java
@@ -0,0 +1,36 @@
+// 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.BaseCmd.CommandType;
+import org.apache.cloudstack.api.Parameter;
+
+public class AddBaremetalKickStartPxeCmd extends AddBaremetalPxeCmd {
+ @Parameter(name=ApiConstants.TFTP_DIR, type=CommandType.STRING, required = true, 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/AddBaremetalPxeCmd.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalPxeCmd.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalPxeCmd.java
new file mode 100755
index 0000000..a1d72a3
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalPxeCmd.java
@@ -0,0 +1,144 @@
+// 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.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseCmd.CommandType;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.PlugService;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.log4j.Logger;
+
+import com.cloud.baremetal.database.BaremetalPxeVO;
+import com.cloud.event.EventTypes;
+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;
+import com.cloud.user.UserContext;
+
+public class AddBaremetalPxeCmd extends BaseAsyncCmd {
+ private static final String s_name = "addexternalpxeresponse";
+ public static final Logger s_logger = Logger.getLogger(AddBaremetalPxeCmd.class);
+
+ @PlugService BaremetalPxeManager pxeMgr;
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+ @Parameter(name=ApiConstants.PHYSICAL_NETWORK_ID, type=CommandType.LONG, required=true, description="the Physical Network ID")
+ private Long physicalNetworkId;
+
+ @Parameter(name=ApiConstants.POD_ID, type=CommandType.LONG, description="Pod Id")
+ private Long podId;
+
+ @Parameter(name=ApiConstants.URL, type=CommandType.STRING, required = true, description="URL of the external pxe device")
+ private String url;
+
+ @Parameter(name=ApiConstants.PXE_SERVER_TYPE, type=CommandType.STRING, required = true, description="type of pxe device")
+ private String deviceType;
+
+ @Parameter(name=ApiConstants.USERNAME, type=CommandType.STRING, required = true, description="Credentials to reach external pxe device")
+ private String username;
+
+ @Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, required = true, description="Credentials to reach external pxe device")
+ private String password;
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_BAREMETAL_PXE_SERVER_ADD;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "Adding an external pxe server";
+ }
+
+ @Override
+ public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
+ ResourceAllocationException, NetworkRuleConflictException {
+ try {
+ BaremetalPxeVO vo = pxeMgr.addPxeServer(this);
+ } catch (Exception e) {
+ s_logger.warn("Unable to add external pxe server with url: " + getUrl(), e);
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+ }
+ }
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+ @Override
+ public long getEntityOwnerId() {
+ return UserContext.current().getCaller().getId();
+ }
+
+ public Long getPhysicalNetworkId() {
+ return physicalNetworkId;
+ }
+
+ public void setPhysicalNetworkId(Long physicalNetworkId) {
+ this.physicalNetworkId = physicalNetworkId;
+ }
+
+ public Long getPodId() {
+ return podId;
+ }
+
+ public void setPodId(Long podId) {
+ this.podId = podId;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ 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/AddBaremetalPxePingServerCmd.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalPxePingServerCmd.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalPxePingServerCmd.java
new file mode 100755
index 0000000..70796f3
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/AddBaremetalPxePingServerCmd.java
@@ -0,0 +1,80 @@
+// 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.Parameter;
+
+public class AddBaremetalPxePingServerCmd extends AddBaremetalPxeCmd {
+
+ @Parameter(name=ApiConstants.PING_STORAGE_SERVER_IP, type=CommandType.STRING, required = true, description="PING storage server ip")
+ private String pingStorageServerIp;
+
+ @Parameter(name=ApiConstants.PING_DIR, type=CommandType.STRING, required = true, description="Root directory on PING storage server")
+ private String pingDir;
+
+ @Parameter(name=ApiConstants.TFTP_DIR, type=CommandType.STRING, required = true, description="Tftp root directory of PXE server")
+ private String tftpDir;
+
+ @Parameter(name=ApiConstants.PING_CIFS_USERNAME, type=CommandType.STRING, description="Username of PING storage server")
+ private String pingStorageServerUserName;
+
+ @Parameter(name=ApiConstants.PING_CIFS_PASSWORD, type=CommandType.STRING, description="Password of PING storage server")
+ private String pingStorageServerPassword;
+
+ 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;
+ }
+
+ public String getPingStorageServerUserName() {
+ return pingStorageServerUserName;
+ }
+
+ public void setPingStorageServerUserName(String pingStorageServerUserName) {
+ this.pingStorageServerUserName = pingStorageServerUserName;
+ }
+
+ public String getPingStorageServerPassword() {
+ return pingStorageServerPassword;
+ }
+
+ public void setPingStorageServerPassword(String pingStorageServerPassword) {
+ this.pingStorageServerPassword = pingStorageServerPassword;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java
new file mode 100755
index 0000000..1f3defb
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPingServiceImpl.java
@@ -0,0 +1,300 @@
+// 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 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.agent.api.baremetal.PreparePxeServerAnswer;
+import com.cloud.agent.api.baremetal.PreparePxeServerCommand;
+import com.cloud.agent.api.baremetal.prepareCreateTemplateCommand;
+import com.cloud.baremetal.database.BaremetalPxeDao;
+import com.cloud.baremetal.database.BaremetalPxeVO;
+import com.cloud.baremetal.networkservice.BaremetalPxeManager.BaremetalPxeType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.HostPodVO;
+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.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.ServerResource;
+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.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Local(value=BaremetalPxeService.class)
+public class BareMetalPingServiceImpl extends BareMetalPxeServiceBase implements BaremetalPxeService {
+ private static final Logger s_logger = Logger.getLogger(BareMetalPingServiceImpl.class);
+ @Inject ResourceManager _resourceMgr;
+ @Inject PhysicalNetworkDao _physicalNetworkDao;
+ @Inject PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
+ @Inject HostDetailsDao _hostDetailsDao;
+ @Inject BaremetalPxeDao _pxeDao;
+
+
+ @Override
+ public boolean prepare(VirtualMachineProfile<UserVmVO> profile, NicProfile pxeNic, DeployDestination dest, ReservationContext context) {
+ SearchCriteriaService<BaremetalPxeVO, BaremetalPxeVO> sc = SearchCriteria2.create(BaremetalPxeVO.class);
+ sc.addAnd(sc.getEntity().getDeviceType(), Op.EQ, BaremetalPxeType.PING.toString());
+ sc.addAnd(sc.getEntity().getPodId(), Op.EQ, dest.getPod().getId());
+ BaremetalPxeVO pxeVo = sc.find();
+ if (pxeVo == null) {
+ throw new CloudRuntimeException("No PING PXE server found in pod: " + dest.getPod().getId() + ", you need to add it before starting VM");
+ }
+ long pxeServerId = pxeVo.getHostId();
+
+ String mac = pxeNic.getMacAddress();
+ String ip = pxeNic.getIp4Address();
+ String gateway = pxeNic.getGateway();
+ String mask = pxeNic.getNetmask();
+ String dns = pxeNic.getDns1();
+ if (dns == null) {
+ dns = pxeNic.getDns2();
+ }
+
+ try {
+ String tpl = profile.getTemplate().getUrl();
+ assert tpl != null : "How can a null template get here!!!";
+ PreparePxeServerCommand cmd = new PreparePxeServerCommand(ip, mac, mask, gateway, dns, tpl,
+ profile.getVirtualMachine().getInstanceName(), dest.getHost().getName());
+ PreparePxeServerAnswer ans = (PreparePxeServerAnswer) _agentMgr.send(pxeServerId, cmd);
+ if (!ans.getResult()) {
+ s_logger.warn("Unable tot program PXE server: " + pxeVo.getId() + " because " + ans.getDetails());
+ return false;
+ }
+
+ IpmISetBootDevCommand bootCmd = new IpmISetBootDevCommand(BootDev.pxe);
+ Answer anw = _agentMgr.send(dest.getHost().getId(), bootCmd);
+ if (!anw.getResult()) {
+ s_logger.warn("Unable to set host: " + dest.getHost().getId() + " to PXE boot because " + anw.getDetails());
+ }
+
+ return anw.getResult();
+ } catch (Exception e) {
+ s_logger.warn("Cannot prepare PXE server", e);
+ return false;
+ }
+ }
+
+
+ @Override
+ public boolean prepareCreateTemplate(Long pxeServerId, UserVm vm, String templateUrl) {
+ List<NicVO> nics = _nicDao.listByVmId(vm.getId());
+ if (nics.size() != 1) {
+ throw new CloudRuntimeException("Wrong nic number " + nics.size() + " of vm " + vm.getId());
+ }
+
+ /* use last host id when VM stopped */
+ Long hostId = (vm.getHostId() == null ? vm.getLastHostId() : vm.getHostId());
+ HostVO host = _hostDao.findById(hostId);
+ DataCenterVO dc = _dcDao.findById(host.getDataCenterId());
+ NicVO nic = nics.get(0);
+ String mask = nic.getNetmask();
+ String mac = nic.getMacAddress();
+ String ip = nic.getIp4Address();
+ String gateway = nic.getGateway();
+ String dns = dc.getDns1();
+ if (dns == null) {
+ dns = dc.getDns2();
+ }
+
+ try {
+ prepareCreateTemplateCommand cmd = new prepareCreateTemplateCommand(ip, mac, mask, gateway, dns, templateUrl);
+ Answer ans = _agentMgr.send(pxeServerId, cmd);
+ return ans.getResult();
+ } catch (Exception e) {
+ s_logger.debug("Prepare for creating baremetal template failed", e);
+ return false;
+ }
+ }
+
+
+ @Override
+ @DB
+ public BaremetalPxeVO addPxeServer(AddBaremetalPxeCmd cmd) {
+ AddBaremetalPxePingServerCmd pcmd = (AddBaremetalPxePingServerCmd)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");
+ }
+
+ HostPodVO pod = _podDao.findById(cmd.getPodId());
+ if (pod == null) {
+ throw new IllegalArgumentException("Could not find pod with ID: " + cmd.getPodId());
+ }
+
+ List<HostVO> pxes = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.BaremetalPxe, null, cmd.getPodId(), zoneId);
+ if (pxes.size() != 0) {
+ throw new IllegalArgumentException("Already had a PXE server in Pod: " + cmd.getPodId() + " zone: " + zoneId);
+ }
+
+ String storageServerIp = pcmd.getPingStorageServerIp();
+ if (storageServerIp == null) {
+ throw new IllegalArgumentException("No IP for storage server specified");
+ }
+ String pingDir = pcmd.getPingDir();
+ if (pingDir == null) {
+ throw new IllegalArgumentException("No direcotry for storage server specified");
+ }
+ String tftpDir = pcmd.getTftpDir();
+ if (tftpDir == null) {
+ throw new IllegalArgumentException("No TFTP directory specified");
+ }
+
+ String cifsUsername = pcmd.getPingStorageServerUserName();
+ if (cifsUsername == null || cifsUsername.equalsIgnoreCase("")) {
+ cifsUsername = "xxx";
+ }
+ String cifsPassword = pcmd.getPingStorageServerPassword();
+ if (cifsPassword == null || cifsPassword.equalsIgnoreCase("")) {
+ cifsPassword = "xxx";
+ }
+
+
+ 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) + "-" + pod.getId(), BaremetalPxeType.PING.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_POD, String.valueOf(pod.getId()));
+ 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_PING_STORAGE_SERVER_IP, storageServerIp);
+ params.put(BaremetalPxeService.PXE_PARAM_PING_ROOT_DIR, pingDir);
+ params.put(BaremetalPxeService.PXE_PARAM_TFTP_DIR, tftpDir);
+ params.put(BaremetalPxeService.PXE_PARAM_PING_STORAGE_SERVER_USERNAME, cifsUsername);
+ params.put(BaremetalPxeService.PXE_PARAM_PING_STORAGE_SERVER_PASSWORD, cifsPassword);
+ params.put(BaremetalPxeService.PXE_PARAM_GUID, guid);
+
+ resource = new BaremetalPingPxeResource();
+ try {
+ resource.configure("PING PXE resource", params);
+ } catch (Exception e) {
+ s_logger.debug(e);
+ throw new CloudRuntimeException(e.getMessage());
+ }
+
+ 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.setPodId(pod.getId());
+ vo.setPhysicalNetworkId(pcmd.getPhysicalNetworkId());
+ vo.setDeviceType(BaremetalPxeType.PING.toString());
+ txn.start();
+ _pxeDao.persist(vo);
+ txn.commit();
+ return vo;
+ }
+
+ @Override
+ public BaremetalPxeResponse getApiResponse(BaremetalPxeVO vo) {
+ BaremetalPxePingResponse response = new BaremetalPxePingResponse();
+ 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.setPingStorageServerIp(details.get(BaremetalPxeService.PXE_PARAM_PING_STORAGE_SERVER_IP));
+ response.setPingDir(details.get(BaremetalPxeService.PXE_PARAM_PING_ROOT_DIR));
+ 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.PING.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/BareMetalPxeServiceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPxeServiceBase.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPxeServiceBase.java
new file mode 100644
index 0000000..85a9b3c
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalPxeServiceBase.java
@@ -0,0 +1,68 @@
+// 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 com.cloud.agent.AgentManager;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.host.dao.HostDao;
+import com.cloud.utils.component.Inject;
+import com.cloud.vm.dao.NicDao;
+
+public abstract class BareMetalPxeServiceBase implements BaremetalPxeService {
+ protected String _name;
+ @Inject DataCenterDao _dcDao;
+ @Inject HostDao _hostDao;
+ @Inject AgentManager _agentMgr;
+ @Inject HostPodDao _podDao;
+ @Inject NicDao _nicDao;
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ _name = name;
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return _name;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ protected String getPxeServerGuid(String zoneId, String name, String ip) {
+ return zoneId + "-" + name + "-" + ip;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java
new file mode 100755
index 0000000..d615d1d
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BareMetalResourceBase.java
@@ -0,0 +1,618 @@
+// 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.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckNetworkAnswer;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.CheckVirtualMachineAnswer;
+import com.cloud.agent.api.CheckVirtualMachineCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.MaintainAnswer;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.MigrateAnswer;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingCommand;
+import com.cloud.agent.api.PrepareForMigrationAnswer;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.RebootAnswer;
+import com.cloud.agent.api.RebootCommand;
+import com.cloud.agent.api.SecurityGroupRulesCmd;
+import com.cloud.agent.api.StartAnswer;
+import com.cloud.agent.api.StartCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.StopAnswer;
+import com.cloud.agent.api.StopCommand;
+import com.cloud.agent.api.baremetal.IpmISetBootDevCommand;
+import com.cloud.agent.api.baremetal.IpmISetBootDevCommand.BootDev;
+import com.cloud.agent.api.baremetal.IpmiBootorResetCommand;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.baremetal.manager.BaremetalManager;
+import com.cloud.host.Host.Type;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.resource.ServerResource;
+import com.cloud.server.ManagementServer;
+import com.cloud.utils.component.ComponentLocator;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.OutputInterpreter;
+import com.cloud.utils.script.Script;
+import com.cloud.utils.script.Script2;
+import com.cloud.utils.script.Script2.ParamType;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.VMInstanceDao;
+
+import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
+
+@Local(value = ServerResource.class)
+public class BareMetalResourceBase implements ServerResource {
+ private static final Logger s_logger = Logger.getLogger(BareMetalResourceBase.class);
+ protected HashMap<String, State> _vms = new HashMap<String, State>(2);
+ protected String _name;
+ protected String _uuid;
+ protected String _zone;
+ protected String _pod;
+ protected Long hostId;
+ protected String _cluster;
+ protected long _memCapacity;
+ protected long _cpuCapacity;
+ protected long _cpuNum;
+ protected String _mac;
+ protected String _username;
+ protected String _password;
+ protected String _ip;
+ protected boolean _isEchoScAgent;
+ protected IAgentControl _agentControl;
+ protected Script2 _pingCommand;
+ protected Script2 _setPxeBootCommand;
+ protected Script2 _setDiskBootCommand;
+ protected Script2 _rebootCommand;
+ protected Script2 _getStatusCommand;
+ protected Script2 _powerOnCommand;
+ protected Script2 _powerOffCommand;
+ protected Script2 _forcePowerOffCommand;
+ protected Script2 _bootOrRebootCommand;
+ protected String _vmName;
+ protected VMInstanceDao vmDao;
+
+ private void changeVmState(String vmName, VirtualMachine.State state) {
+ synchronized (_vms) {
+ _vms.put(vmName, state);
+ }
+ }
+
+ private State removeVmState(String vmName) {
+ synchronized (_vms) {
+ return _vms.remove(vmName);
+ }
+ }
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ _name = name;
+ _uuid = (String) params.get("guid");
+ try {
+ _memCapacity = Long.parseLong((String) params.get(ApiConstants.MEMORY)) * 1024L * 1024L;
+ _cpuCapacity = Long.parseLong((String) params.get(ApiConstants.CPU_SPEED));
+ _cpuNum = Long.parseLong((String) params.get(ApiConstants.CPU_NUMBER));
+ } catch (NumberFormatException e) {
+ throw new ConfigurationException(String.format("Unable to parse number of CPU or memory capacity "
+ + "or cpu capacity(cpu number = %1$s memCapacity=%2$s, cpuCapacity=%3$s", (String) params.get(ApiConstants.CPU_NUMBER),
+ (String) params.get(ApiConstants.MEMORY), (String) params.get(ApiConstants.CPU_SPEED)));
+ }
+
+ _zone = (String) params.get("zone");
+ _pod = (String) params.get("pod");
+ _cluster = (String) params.get("cluster");
+ hostId = (Long) params.get("hostId");
+ _ip = (String) params.get(ApiConstants.PRIVATE_IP);
+ _mac = (String) params.get(ApiConstants.HOST_MAC);
+ _username = (String) params.get(ApiConstants.USERNAME);
+ _password = (String) params.get(ApiConstants.PASSWORD);
+ _vmName = (String) params.get("vmName");
+ String echoScAgent = (String) params.get(BaremetalManager.EchoSecurityGroupAgent);
+
+ if (_pod == null) {
+ throw new ConfigurationException("Unable to get the pod");
+ }
+
+ if (_cluster == null) {
+ throw new ConfigurationException("Unable to get the pod");
+ }
+
+ if (_ip == null) {
+ throw new ConfigurationException("Unable to get the host address");
+ }
+
+ if (_mac.equalsIgnoreCase("unknown")) {
+ throw new ConfigurationException("Unable to get the host mac address");
+ }
+
+ if (_mac.split(":").length != 6) {
+ throw new ConfigurationException("Wrong MAC format(" + _mac
+ + "). It must be in format of for example 00:11:ba:33:aa:dd which is not case sensitive");
+ }
+
+ if (_uuid == null) {
+ throw new ConfigurationException("Unable to get the uuid");
+ }
+
+ if (echoScAgent != null) {
+ _isEchoScAgent = Boolean.valueOf(echoScAgent);
+ }
+
+ String injectScript = "scripts/util/ipmi.py";
+ String scriptPath = Script.findScript("", injectScript);
+ if (scriptPath == null) {
+ throw new ConfigurationException("Cannot find ping script " + scriptPath);
+ }
+ _pingCommand = new Script2(scriptPath, s_logger);
+ _pingCommand.add("ping");
+ _pingCommand.add("hostname=" + _ip);
+ _pingCommand.add("usrname=" + _username);
+ _pingCommand.add("password=" + _password, ParamType.PASSWORD);
+
+ _setPxeBootCommand = new Script2(scriptPath, s_logger);
+ _setPxeBootCommand.add("boot_dev");
+ _setPxeBootCommand.add("hostname=" + _ip);
+ _setPxeBootCommand.add("usrname=" + _username);
+ _setPxeBootCommand.add("password=" + _password, ParamType.PASSWORD);
+ _setPxeBootCommand.add("dev=pxe");
+
+ _setDiskBootCommand = new Script2(scriptPath, s_logger);
+ _setDiskBootCommand.add("boot_dev");
+ _setDiskBootCommand.add("hostname=" + _ip);
+ _setDiskBootCommand.add("usrname=" + _username);
+ _setDiskBootCommand.add("password=" + _password, ParamType.PASSWORD);
+ _setDiskBootCommand.add("dev=disk");
+
+ _rebootCommand = new Script2(scriptPath, s_logger);
+ _rebootCommand.add("reboot");
+ _rebootCommand.add("hostname=" + _ip);
+ _rebootCommand.add("usrname=" + _username);
+ _rebootCommand.add("password=" + _password, ParamType.PASSWORD);
+
+ _getStatusCommand = new Script2(scriptPath, s_logger);
+ _getStatusCommand.add("ping");
+ _getStatusCommand.add("hostname=" + _ip);
+ _getStatusCommand.add("usrname=" + _username);
+ _getStatusCommand.add("password=" + _password, ParamType.PASSWORD);
+
+ _powerOnCommand = new Script2(scriptPath, s_logger);
+ _powerOnCommand.add("power");
+ _powerOnCommand.add("hostname=" + _ip);
+ _powerOnCommand.add("usrname=" + _username);
+ _powerOnCommand.add("password=" + _password, ParamType.PASSWORD);
+ _powerOnCommand.add("action=on");
+
+ _powerOffCommand = new Script2(scriptPath, s_logger);
+ _powerOffCommand.add("power");
+ _powerOffCommand.add("hostname=" + _ip);
+ _powerOffCommand.add("usrname=" + _username);
+ _powerOffCommand.add("password=" + _password, ParamType.PASSWORD);
+ _powerOffCommand.add("action=soft");
+
+ _forcePowerOffCommand = new Script2(scriptPath, s_logger);
+ _forcePowerOffCommand.add("power");
+ _forcePowerOffCommand.add("hostname=" + _ip);
+ _forcePowerOffCommand.add("usrname=" + _username);
+ _forcePowerOffCommand.add("password=" + _password, ParamType.PASSWORD);
+ _forcePowerOffCommand.add("action=off");
+
+ _bootOrRebootCommand = new Script2(scriptPath, s_logger);
+ _bootOrRebootCommand.add("boot_or_reboot");
+ _bootOrRebootCommand.add("hostname=" + _ip);
+ _bootOrRebootCommand.add("usrname=" + _username);
+ _bootOrRebootCommand.add("password=" + _password, ParamType.PASSWORD);
+
+ return true;
+ }
+
+ protected boolean doScript(Script cmd) {
+ return doScript(cmd, null);
+ }
+
+ protected boolean doScript(Script cmd, OutputInterpreter interpreter) {
+ int retry = 5;
+ String res = null;
+ while (retry-- > 0) {
+ if (interpreter == null) {
+ res = cmd.execute();
+ } else {
+ res = cmd.execute(interpreter);
+ }
+ if (res != null && res.startsWith("Error: Unable to establish LAN")) {
+ s_logger.warn("IPMI script timeout(" + cmd.toString() + "), will retry " + retry + " times");
+ continue;
+ } else if (res == null) {
+ return true;
+ } else {
+ break;
+ }
+ }
+
+ s_logger.warn("IPMI Scirpt failed due to " + res + "(" + cmd.toString() + ")");
+ return false;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return _name;
+ }
+
+ @Override
+ public Type getType() {
+ return com.cloud.host.Host.Type.Routing;
+ }
+
+ protected State getVmState() {
+ OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser();
+ if (!doScript(_getStatusCommand, interpreter)) {
+ s_logger.warn("Cannot get power status of " + _name + ", assume VM state was not changed");
+ return null;
+ }
+ if (isPowerOn(interpreter.getLines())) {
+ return State.Running;
+ } else {
+ return State.Stopped;
+ }
+ }
+
+ protected Map<String, State> fullSync() {
+ Map<String, State> states = new HashMap<String, State>();
+ if (hostId != null) {
+ ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name);
+ vmDao = locator.getDao(VMInstanceDao.class);
+ final List<? extends VMInstanceVO> vms = vmDao.listByHostId(hostId);
+ for (VMInstanceVO vm : vms) {
+ states.put(vm.getInstanceName(), vm.getState());
+ }
+ }
+ /*
+ * Map<String, State> changes = new HashMap<String, State>();
+ *
+ * if (_vmName != null) { State state = getVmState(); if (state != null)
+ * { changes.put(_vmName, state); } }
+ */
+
+ return states;
+ }
+
+ @Override
+ public StartupCommand[] initialize() {
+ StartupRoutingCommand cmd = new StartupRoutingCommand(0, 0, 0, 0, null, Hypervisor.HypervisorType.BareMetal, new HashMap<String, String>(), null);
+ cmd.setDataCenter(_zone);
+ cmd.setPod(_pod);
+ cmd.setCluster(_cluster);
+ cmd.setGuid(_uuid);
+ cmd.setName(_ip);
+ cmd.setPrivateIpAddress(_ip);
+ cmd.setStorageIpAddress(_ip);
+ cmd.setVersion(BareMetalResourceBase.class.getPackage().getImplementationVersion());
+ cmd.setCpus((int) _cpuNum);
+ cmd.setSpeed(_cpuCapacity);
+ cmd.setMemory(_memCapacity);
+ cmd.setPrivateMacAddress(_mac);
+ cmd.setPublicMacAddress(_mac);
+ cmd.setStateChanges(fullSync());
+ return new StartupCommand[] { cmd };
+ }
+
+ private boolean ipmiPing() {
+ return doScript(_pingCommand);
+ }
+
+ @Override
+ public PingCommand getCurrentStatus(long id) {
+ try {
+ if (!ipmiPing()) {
+ Thread.sleep(1000);
+ if (!ipmiPing()) {
+ s_logger.warn("Cannot ping ipmi nic " + _ip);
+ return null;
+ }
+ }
+ } catch (Exception e) {
+ s_logger.debug("Cannot ping ipmi nic " + _ip, e);
+ return null;
+ }
+
+ return new PingRoutingCommand(getType(), id, deltaSync());
+ }
+
+ protected Answer execute(IpmISetBootDevCommand cmd) {
+ Script bootCmd = null;
+ if (cmd.getBootDev() == BootDev.disk) {
+ bootCmd = _setDiskBootCommand;
+ } else if (cmd.getBootDev() == BootDev.pxe) {
+ bootCmd = _setPxeBootCommand;
+ } else {
+ throw new CloudRuntimeException("Unkonwn boot dev " + cmd.getBootDev());
+ }
+
+ String bootDev = cmd.getBootDev().name();
+ if (!doScript(bootCmd)) {
+ s_logger.warn("Set " + _ip + " boot dev to " + bootDev + "failed");
+ return new Answer(cmd, false, "Set " + _ip + " boot dev to " + bootDev + "failed");
+ }
+
+ s_logger.warn("Set " + _ip + " boot dev to " + bootDev + "Success");
+ return new Answer(cmd, true, "Set " + _ip + " boot dev to " + bootDev + "Success");
+ }
+
+ protected MaintainAnswer execute(MaintainCommand cmd) {
+ return new MaintainAnswer(cmd, false);
+ }
+
+ protected PrepareForMigrationAnswer execute(PrepareForMigrationCommand cmd) {
+ return new PrepareForMigrationAnswer(cmd);
+ }
+
+ protected MigrateAnswer execute(MigrateCommand cmd) {
+ if (!doScript(_powerOffCommand)) {
+ return new MigrateAnswer(cmd, false, "IPMI power off failed", null);
+ }
+ return new MigrateAnswer(cmd, true, "success", null);
+ }
+
+ protected CheckVirtualMachineAnswer execute(final CheckVirtualMachineCommand cmd) {
+ return new CheckVirtualMachineAnswer(cmd, State.Stopped, null);
+ }
+
+ protected Answer execute(IpmiBootorResetCommand cmd) {
+ if (!doScript(_bootOrRebootCommand)) {
+ return new Answer(cmd, false, "IPMI boot or reboot failed");
+ }
+ return new Answer(cmd, true, "Success");
+
+ }
+
+ protected CheckNetworkAnswer execute(CheckNetworkCommand cmd) {
+ return new CheckNetworkAnswer(cmd, true, "Success");
+ }
+
+ protected Answer execute(SecurityGroupRulesCmd cmd) {
+ SecurityGroupHttpClient hc = new SecurityGroupHttpClient();
+ return hc.call(cmd.getGuestIp(), cmd);
+ }
+
+ @Override
+ public Answer executeRequest(Command cmd) {
+ try {
+ if (cmd instanceof ReadyCommand) {
+ return execute((ReadyCommand) cmd);
+ } else if (cmd instanceof StartCommand) {
+ return execute((StartCommand) cmd);
+ } else if (cmd instanceof StopCommand) {
+ return execute((StopCommand) cmd);
+ } else if (cmd instanceof RebootCommand) {
+ return execute((RebootCommand) cmd);
+ } else if (cmd instanceof IpmISetBootDevCommand) {
+ return execute((IpmISetBootDevCommand) cmd);
+ } else if (cmd instanceof MaintainCommand) {
+ return execute((MaintainCommand) cmd);
+ } else if (cmd instanceof PrepareForMigrationCommand) {
+ return execute((PrepareForMigrationCommand) cmd);
+ } else if (cmd instanceof MigrateCommand) {
+ return execute((MigrateCommand) cmd);
+ } else if (cmd instanceof CheckVirtualMachineCommand) {
+ return execute((CheckVirtualMachineCommand) cmd);
+ } else if (cmd instanceof IpmiBootorResetCommand) {
+ return execute((IpmiBootorResetCommand) cmd);
+ } else if (cmd instanceof SecurityGroupRulesCmd) {
+ return execute((SecurityGroupRulesCmd) cmd);
+ } else if (cmd instanceof CheckNetworkCommand) {
+ return execute((CheckNetworkCommand) cmd);
+ } else {
+ return Answer.createUnsupportedCommandAnswer(cmd);
+ }
+ } catch (Throwable t) {
+ s_logger.debug(t.getMessage(), t);
+ return new Answer(cmd, false, t.getMessage());
+ }
+ }
+
+ protected boolean isPowerOn(String str) {
+ if (str.startsWith("Chassis Power is on")) {
+ return true;
+ } else if (str.startsWith("Chassis Power is off")) {
+ return false;
+ } else {
+ throw new CloudRuntimeException("Cannot parse IPMI power status " + str);
+ }
+ }
+
+ protected RebootAnswer execute(final RebootCommand cmd) {
+ if (!doScript(_rebootCommand)) {
+ return new RebootAnswer(cmd, "IPMI reboot failed", false);
+ }
+
+ return new RebootAnswer(cmd, "reboot succeeded", true);
+ }
+
+ protected StopAnswer execute(final StopCommand cmd) {
+ boolean success = false;
+ int count = 0;
+ Script powerOff = _powerOffCommand;
+
+ while (count < 10) {
+ if (!doScript(powerOff)) {
+ break;
+ }
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ break;
+ }
+
+ OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser();
+ if (!doScript(_getStatusCommand, interpreter)) {
+ s_logger.warn("Cannot get power status of " + _name + ", assume VM state was not changed");
+ break;
+ }
+
+ if (!isPowerOn(interpreter.getLines())) {
+ success = true;
+ break;
+ } else {
+ powerOff = _forcePowerOffCommand;
+ }
+
+ count++;
+ }
+
+ return success ? new StopAnswer(cmd, "Success", 0, true) : new StopAnswer(cmd, "IPMI power off failed", false);
+ }
+
+ protected StartAnswer execute(StartCommand cmd) {
+ VirtualMachineTO vm = cmd.getVirtualMachine();
+ State state = State.Stopped;
+
+ try {
+ changeVmState(vm.getName(), State.Starting);
+
+ OutputInterpreter.AllLinesParser interpreter = new OutputInterpreter.AllLinesParser();
+ if (!doScript(_getStatusCommand, interpreter)) {
+ return new StartAnswer(cmd, "Cannot get current power status of " + _name);
+ }
+
+ if (isPowerOn(interpreter.getLines())) {
+ if (!doScript(_rebootCommand)) {
+ return new StartAnswer(cmd, "IPMI reboot failed");
+ }
+ } else {
+ if (!doScript(_powerOnCommand)) {
+ return new StartAnswer(cmd, "IPMI power on failed");
+ }
+ }
+
+ if (_isEchoScAgent) {
+ SecurityGroupHttpClient hc = new SecurityGroupHttpClient();
+ boolean echoRet = hc.echo(vm.getNics()[0].getIp(), TimeUnit.MINUTES.toMillis(30), TimeUnit.MINUTES.toMillis(1));
+ if (!echoRet) {
+ return new StartAnswer(cmd, String.format("Call security group agent on vm[%s] timeout", vm.getNics()[0].getIp()));
+ }
+ }
+
+ s_logger.debug("Start bare metal vm " + vm.getName() + "successfully");
+ state = State.Running;
+ _vmName = vm.getName();
+ return new StartAnswer(cmd);
+ } finally {
+ if (state != State.Stopped) {
+ changeVmState(vm.getName(), state);
+ } else {
+ removeVmState(vm.getName());
+ }
+ }
+ }
+
+ protected HashMap<String, State> deltaSync() {
+ final HashMap<String, State> changes = new HashMap<String, State>();
+ /*
+ * Disable sync until we find a way that only tracks status but not does
+ * action
+ *
+ * The scenario is: Baremetal will reboot host when creating template.
+ * Given most servers take a long time to boot up, there would be a
+ * period that mgmt server finds the host is stopped through fullsync.
+ * Then mgmt server updates database with marking the host as stopped,
+ * after that, the host comes up and full sync then indicates it's
+ * running. Because in database the host is already stopped, mgmt server
+ * sends out a stop command. As a result, creating image gets never
+ * happened.
+ *
+ * if (_vmName == null) { return null; }
+ *
+ * State newState = getVmState(); if (newState == null) {
+ * s_logger.warn("Cannot get power state of VM " + _vmName); return
+ * null; }
+ *
+ * final State oldState = removeVmState(_vmName); if (oldState == null)
+ * { changeVmState(_vmName, newState); changes.put(_vmName, newState); }
+ * else if (oldState == State.Starting) { if (newState == State.Running)
+ * { changeVmState(_vmName, newState); } else if (newState ==
+ * State.Stopped) { s_logger.debug("Ignoring vm " + _vmName +
+ * " because of a lag in starting the vm."); } } else if (oldState ==
+ * State.Migrating) {
+ * s_logger.warn("How can baremetal VM get into migrating state???"); }
+ * else if (oldState == State.Stopping) { if (newState == State.Stopped)
+ * { changeVmState(_vmName, newState); } else if (newState ==
+ * State.Running) { s_logger.debug("Ignoring vm " + _vmName +
+ * " because of a lag in stopping the vm. "); } } else if (oldState !=
+ * newState) { changeVmState(_vmName, newState); changes.put(_vmName,
+ * newState); }
+ */
+ return changes;
+
+ }
+
+ protected ReadyAnswer execute(ReadyCommand cmd) {
+ // derived resource should check if the PXE server is ready
+ s_logger.debug("Bare metal resource " + _name + " is ready");
+ return new ReadyAnswer(cmd);
+ }
+
+ @Override
+ public void disconnected() {
+
+ }
+
+ @Override
+ public IAgentControl getAgentControl() {
+ return _agentControl;
+ }
+
+ @Override
+ public void setAgentControl(IAgentControl agentControl) {
+ _agentControl = agentControl;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java
new file mode 100755
index 0000000..5414106
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetaNetworkGuru.java
@@ -0,0 +1,173 @@
+// 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 javax.ejb.Local;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.Pod;
+import com.cloud.dc.PodVlanMapVO;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.Vlan.VlanType;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.PodVlanMapDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IPAddressVO;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkManager;
+import com.cloud.network.Networks.AddressFormat;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.guru.DirectPodBasedNetworkGuru;
+import com.cloud.network.guru.NetworkGuru;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.db.Transaction;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Local(value = { NetworkGuru.class })
+public class BaremetaNetworkGuru extends DirectPodBasedNetworkGuru {
+ private static final Logger s_logger = Logger.getLogger(BaremetaNetworkGuru.class);
+ @Inject
+ private HostDao _hostDao;
+ @Inject
+ DataCenterDao _dcDao;
+ @Inject
+ VlanDao _vlanDao;
+ @Inject
+ NetworkManager _networkMgr;
+ @Inject
+ IPAddressDao _ipAddressDao;
+ @Inject
+ NetworkOfferingDao _networkOfferingDao;
+ @Inject
+ PodVlanMapDao _podVlanDao;
+
+ @Override
+ public void reserve(NicProfile nic, Network network, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, ReservationContext context)
+ throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException {
+ if (dest.getHost().getHypervisorType() != HypervisorType.BareMetal) {
+ super.reserve(nic, network, vm, dest, context);
+ return;
+ }
+
+ HostVO host = _hostDao.findById(dest.getHost().getId());
+ _hostDao.loadDetails(host);
+ String intentIp = host.getDetail(ApiConstants.IP_ADDRESS);
+ if (intentIp == null) {
+ super.reserve(nic, network, vm, dest, context);
+ return;
+ }
+
+ String oldIp = nic.getIp4Address();
+ boolean getNewIp = false;
+ if (oldIp == null) {
+ getNewIp = true;
+ } else {
+ // we need to get a new ip address if we try to deploy a vm in a
+ // different pod
+ IPAddressVO ipVO = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), oldIp);
+ if (ipVO != null) {
+ PodVlanMapVO mapVO = _podVlanDao.listPodVlanMapsByVlan(ipVO.getVlanId());
+ if (mapVO.getPodId() != dest.getPod().getId()) {
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+
+ // release the old ip here
+ _networkMgr.markIpAsUnavailable(ipVO.getId());
+ _ipAddressDao.unassignIpAddress(ipVO.getId());
+
+ txn.commit();
+
+ nic.setIp4Address(null);
+ getNewIp = true;
+ }
+ }
+ }
+
+ if (getNewIp) {
+ // we don't set reservationStrategy to Create because we need this
+ // method to be called again for the case when vm fails to deploy in
+ // Pod1, and we try to redeploy it in Pod2
+ getBaremetalIp(nic, dest.getPod(), vm, network, intentIp);
+ }
+
+ DataCenter dc = _dcDao.findById(network.getDataCenterId());
+ nic.setDns1(dc.getDns1());
+ nic.setDns2(dc.getDns2());
+
+ /*
+ * Pod pod = dest.getPod(); Pair<String, Long> ip =
+ * _dcDao.allocatePrivateIpAddress(dest.getDataCenter().getId(),
+ * dest.getPod().getId(), nic.getId(), context.getReservationId(),
+ * intentIp); if (ip == null) { throw new
+ * InsufficientAddressCapacityException
+ * ("Unable to get a management ip address", Pod.class, pod.getId()); }
+ *
+ * nic.setIp4Address(ip.first());
+ * nic.setMacAddress(NetUtils.long2Mac(NetUtils
+ * .createSequenceBasedMacAddress(ip.second())));
+ * nic.setGateway(pod.getGateway()); nic.setFormat(AddressFormat.Ip4);
+ * String netmask = NetUtils.getCidrNetmask(pod.getCidrSize());
+ * nic.setNetmask(netmask);
+ * nic.setBroadcastType(BroadcastDomainType.Native);
+ * nic.setBroadcastUri(null); nic.setIsolationUri(null);
+ */
+
+ s_logger.debug("Allocated a nic " + nic + " for " + vm);
+ }
+
+ private void getBaremetalIp(NicProfile nic, Pod pod, VirtualMachineProfile<? extends VirtualMachine> vm, Network network, String requiredIp)
+ throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException {
+ DataCenter dc = _dcDao.findById(pod.getDataCenterId());
+ if (nic.getIp4Address() == null) {
+ s_logger.debug(String.format("Requiring ip address: %s", nic.getIp4Address()));
+ PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), pod.getId(), vm.getOwner(), VlanType.DirectAttached, network.getId(), requiredIp, false);
+ nic.setIp4Address(ip.getAddress().toString());
+ nic.setFormat(AddressFormat.Ip4);
+ nic.setGateway(ip.getGateway());
+ nic.setNetmask(ip.getNetmask());
+ if (ip.getVlanTag() != null && ip.getVlanTag().equalsIgnoreCase(Vlan.UNTAGGED)) {
+ nic.setIsolationUri(URI.create("ec2://" + Vlan.UNTAGGED));
+ nic.setBroadcastUri(URI.create("vlan://" + Vlan.UNTAGGED));
+ nic.setBroadcastType(BroadcastDomainType.Native);
+ }
+ nic.setReservationId(String.valueOf(ip.getVlanTag()));
+ nic.setMacAddress(ip.getMacAddress());
+ }
+ nic.setDns1(dc.getDns1());
+ nic.setDns2(dc.getDns2());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java
new file mode 100755
index 0000000..968aa6d
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpElement.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.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.baremetal.database.BaremetalDhcpVO;
+import com.cloud.baremetal.database.BaremetalPxeVO;
+import com.cloud.dc.Pod;
+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.host.Host;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Network;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+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.element.DhcpServiceProvider;
+import com.cloud.network.element.IpDeployer;
+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.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Type;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Local(value = NetworkElement.class)
+public class BaremetalDhcpElement extends AdapterBase implements DhcpServiceProvider {
+ private static final Logger s_logger = Logger.getLogger(BaremetalDhcpElement.class);
+ private static final Map<Service, Map<Capability, String>> capabilities;
+
+ @Inject NicDao _nicDao;
+ @Inject BaremetalDhcpManager _dhcpMgr;
+
+ static {
+ Capability cap = new Capability(BaremetalDhcpManager.BAREMETAL_DHCP_SERVICE_CAPABITLITY);
+ Map<Capability, String> baremetalCaps = new HashMap<Capability, String>();
+ baremetalCaps.put(cap, null);
+ capabilities = new HashMap<Service, Map<Capability, String>>();
+ capabilities.put(Service.Dhcp, baremetalCaps);
+ }
+
+ @Override
+ public Map<Service, Map<Capability, String>> getCapabilities() {
+ return capabilities;
+ }
+
+ @Override
+ public Provider getProvider() {
+ return BaremetalDhcpManager.BAREMETAL_DHCP_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<BaremetalDhcpVO, BaremetalDhcpVO> sc = SearchCriteria2.create(BaremetalDhcpVO.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("BaremetalDhcpElement can not handle networkoffering: " + 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 {
+ Host host = dest.getHost();
+ if (vm.getType() != Type.User || vm.getHypervisorType() != HypervisorType.BareMetal) {
+ return false;
+ }
+
+ Transaction txn = Transaction.currentTxn();
+ txn.start();
+ nic.setMacAddress(host.getPrivateMacAddress());
+ NicVO vo = _nicDao.findById(nic.getId());
+ assert vo != null : "Where ths nic " + nic.getId() + " going???";
+ vo.setMacAddress(nic.getMacAddress());
+ _nicDao.update(vo.getId(), vo);
+ txn.commit();
+ return true;
+ }
+
+ @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 destroy(Network network, ReservationContext context) 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 verifyServicesCombination(Set<Service> services) {
+ return true;
+ }
+
+ public boolean addDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest,
+ ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
+ if (vm.getHypervisorType() != HypervisorType.BareMetal || !canHandle(dest, network.getTrafficType(), network.getGuestType())) {
+ return false;
+ }
+ return _dhcpMgr.addVirtualMachineIntoNetwork(network, nic, vm, dest, context);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManager.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManager.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManager.java
new file mode 100644
index 0000000..a9c63bf
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManager.java
@@ -0,0 +1,58 @@
+// 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.BaremetalDhcpVO;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.host.Host;
+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.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+
+public interface BaremetalDhcpManager extends Manager, PluggableService {
+ public static enum BaremetalDhcpType {
+ DNSMASQ,
+ DHCPD,
+ }
+
+ boolean addVirtualMachineIntoNetwork(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> profile, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException;
+
+ BaremetalDhcpVO addDchpServer(AddBaremetalDhcpCmd cmd);
+
+ BaremetalDhcpResponse generateApiResponse(BaremetalDhcpVO vo);
+
+ List<BaremetalDhcpResponse> listBaremetalDhcps(ListBaremetalDhcpCmd cmd);
+
+ public static final String BAREMETAL_DHCP_SERVICE_CAPABITLITY = "BaremetalDhcp";
+ public static final String BAREMETAL_DHCP_SERVICE_PROPERTIES = "baremetaldhcp_commands.properties";
+ public static final Provider BAREMETAL_DHCP_SERVICE_PROVIDER = new Provider("BaremetalDhcpProvider", true);
+}