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);
+}