You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ki...@apache.org on 2013/01/31 18:07:19 UTC

[11/43] CloudStack CLOUDSTACK-774 Supporting kickstart in CloudStack baremetal

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java
new file mode 100755
index 0000000..94010ec
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java
@@ -0,0 +1,242 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// 
+// Automatically generated by addcopyright.py at 01/29/2013
+// Apache License, Version 2.0 (the "License"); you may not use this
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// 
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.baremetal.networkservice;
+
+
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupPxeServerCommand;
+import com.cloud.agent.api.routing.VmDataCommand;
+import com.cloud.baremetal.database.BaremetalPxeVO;
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.network.PhysicalNetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.StringUtils;
+import com.cloud.utils.component.Adapters;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.SearchCriteria2;
+import com.cloud.utils.db.SearchCriteriaService;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.UserVmDao;
+
+@Local(value = {BaremetalPxeManager.class})
+public class BaremetalPxeManagerImpl implements BaremetalPxeManager, ResourceStateAdapter {
+	private static final org.apache.log4j.Logger s_logger = Logger.getLogger(BaremetalPxeManagerImpl.class);
+	protected String _name;
+	@Inject DataCenterDao _dcDao;
+	@Inject HostDao _hostDao;
+	@Inject AgentManager _agentMgr;
+	@Inject ResourceManager _resourceMgr;
+	@Inject(adapter=BaremetalPxeService.class)
+	protected Adapters<BaremetalPxeService> _services;
+	@Inject UserVmDao _vmDao;
+	@Inject ServiceOfferingDao _serviceOfferingDao;
+	@Inject NicDao _nicDao;
+	@Inject ConfigurationDao _configDao;
+	@Inject PhysicalNetworkDao _phynwDao;
+	
+	@Override
+	public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+		_name = name;
+		_resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
+		return true;
+	}
+
+	@Override
+	public boolean start() {
+		return true;
+	}
+
+	@Override
+	public boolean stop() {
+    	_resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName());
+		return true;
+	}
+
+	@Override
+	public String getName() {
+		return _name;
+	}
+
+	protected BaremetalPxeService getServiceByType(String type) {
+		BaremetalPxeService _service;
+		_service = _services.get(type);
+		if (_service == null) {
+			throw new CloudRuntimeException("Cannot find PXE service for " + type);
+		}
+		return _service;
+	}
+	
+	@Override
+	public boolean prepare(VirtualMachineProfile profile, NicProfile nic, DeployDestination dest, ReservationContext context) {
+	    //TODO: select type from template
+	    BaremetalPxeType type = BaremetalPxeType.KICK_START;
+		return getServiceByType(type.toString()).prepare(profile, nic, dest, context);
+	}
+
+    @Override
+    public boolean prepareCreateTemplate(Long pxeServerId, UserVm vm, String templateUrl) {
+	    //TODO: select type from template
+	    BaremetalPxeType type = BaremetalPxeType.PING;
+        return getServiceByType(type.toString()).prepareCreateTemplate(pxeServerId, vm, templateUrl);
+    }
+    
+    @Override
+    public BaremetalPxeType getPxeServerType(HostVO host) {
+        if (host.getResource().equalsIgnoreCase(BaremetalPingPxeResource.class.getName())) {
+            return BaremetalPxeType.PING;
+        } else {
+            throw new CloudRuntimeException("Unkown PXE server resource " + host.getResource());
+        }
+    }
+
+	@Override
+    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
+	    // TODO Auto-generated method stub
+	    return null;
+    }
+
+	@Override
+    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details,
+            List<String> hostTags) {
+        if (!(startup[0] instanceof StartupPxeServerCommand)) {
+            return null;
+        }
+        
+        host.setType(Host.Type.BaremetalPxe);
+        return host;
+    }
+
+	@Override
+    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
+	    // TODO Auto-generated method stub
+	    return null;
+    }
+
+    @Override
+    public BaremetalPxeVO addPxeServer(AddBaremetalPxeCmd cmd) {
+        return getServiceByType(cmd.getDeviceType()).addPxeServer(cmd);
+    }
+
+    @Override
+    public BaremetalPxeResponse getApiResponse(BaremetalPxeVO vo) {
+        return getServiceByType(vo.getDeviceType()).getApiResponse(vo);
+    }
+
+    @Override
+    public List<BaremetalPxeResponse> listPxeServers(ListBaremetalPxePingServersCmd cmd) {
+        return getServiceByType(BaremetalPxeManager.BaremetalPxeType.PING.toString()).listPxeServers(cmd);
+    }
+
+    @Override
+    public boolean addUserData(NicProfile nic, VirtualMachineProfile<UserVm> profile) {
+        UserVmVO vm = (UserVmVO) profile.getVirtualMachine();
+        _vmDao.loadDetails(vm);
+        
+        String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId()).getDisplayText();
+        String zoneName = _dcDao.findById(vm.getDataCenterIdToDeployIn()).getName();
+        NicVO nvo = _nicDao.findById(nic.getId());
+        VmDataCommand cmd = new VmDataCommand(nvo.getIp4Address(), vm.getInstanceName());
+        cmd.addVmData("userdata", "user-data", vm.getUserData());
+        cmd.addVmData("metadata", "service-offering", StringUtils.unicodeEscape(serviceOffering));
+        cmd.addVmData("metadata", "availability-zone", StringUtils.unicodeEscape(zoneName));
+        cmd.addVmData("metadata", "local-ipv4", nic.getIp4Address());
+        cmd.addVmData("metadata", "local-hostname", StringUtils.unicodeEscape(vm.getInstanceName()));
+        cmd.addVmData("metadata", "public-ipv4", nic.getIp4Address());
+        cmd.addVmData("metadata", "public-hostname",  StringUtils.unicodeEscape(vm.getInstanceName()));
+        cmd.addVmData("metadata", "instance-id", String.valueOf(vm.getId()));
+        cmd.addVmData("metadata", "vm-id", String.valueOf(vm.getInstanceName()));
+        cmd.addVmData("metadata", "public-keys", null);
+        String cloudIdentifier = _configDao.getValue("cloud.identifier");
+        if (cloudIdentifier == null) {
+            cloudIdentifier = "";
+        } else {
+            cloudIdentifier = "CloudStack-{" + cloudIdentifier + "}";
+        }
+        cmd.addVmData("metadata", "cloud-identifier", cloudIdentifier);
+        
+        List<PhysicalNetworkVO> phys = _phynwDao.listByZone(vm.getDataCenterIdToDeployIn());
+        if (phys.isEmpty()) {
+            throw new CloudRuntimeException(String.format("Cannot find physical network in zone %s", vm.getDataCenterIdToDeployIn()));
+        }
+        if (phys.size() > 1) {
+            throw new CloudRuntimeException(String.format("Baremetal only supports one physical network in zone, but zone %s has %s physical networks", vm.getDataCenterIdToDeployIn(), phys.size()));
+        }
+        PhysicalNetworkVO phy = phys.get(0);
+        
+        SearchCriteriaService<BaremetalPxeVO, BaremetalPxeVO> sc = SearchCriteria2.create(BaremetalPxeVO.class);
+        //TODO: handle both kickstart and PING
+        //sc.addAnd(sc.getEntity().getPodId(), Op.EQ, vm.getPodIdToDeployIn());
+        sc.addAnd(sc.getEntity().getPhysicalNetworkId(), Op.EQ, phy.getId());
+        BaremetalPxeVO pxeVo = sc.find();
+        if (pxeVo == null) {
+            throw new CloudRuntimeException("No PXE server found in pod: " + vm.getPodIdToDeployIn() + ", you need to add it before starting VM");
+        }
+        
+        try {
+            Answer ans = _agentMgr.send(pxeVo.getHostId(), cmd);
+            if (!ans.getResult()) {
+                s_logger.debug(String.format("Add userdata to vm:%s failed because %s", vm.getInstanceName(), ans.getDetails()));
+                return false;
+            } else {
+                return true;
+            }
+        } catch (Exception e) {
+            s_logger.debug(String.format("Add userdata to vm:%s failed", vm.getInstanceName()), e);
+            return false;
+        }
+    }
+
+	@Override
+	public List<Class<?>> getCommands() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxePingResponse.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxePingResponse.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxePingResponse.java
new file mode 100755
index 0000000..adbf053
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxePingResponse.java
@@ -0,0 +1,59 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// 
+// Automatically generated by addcopyright.py at 01/29/2013
+package com.cloud.baremetal.networkservice;
+
+import org.apache.cloudstack.api.ApiConstants;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+public class BaremetalPxePingResponse extends BaremetalPxeResponse {
+    @SerializedName(ApiConstants.PING_STORAGE_SERVER_IP) @Param(description="PING storage server ip")
+    private String pingStorageServerIp;
+    
+    @SerializedName(ApiConstants.PING_DIR) @Param(description="Root directory on PING storage server")
+    private String pingDir;
+    
+    @SerializedName(ApiConstants.TFTP_DIR) @Param(description="Tftp root directory of PXE server")
+    private String tftpDir;
+
+    public String getPingStorageServerIp() {
+        return pingStorageServerIp;
+    }
+
+    public void setPingStorageServerIp(String pingStorageServerIp) {
+        this.pingStorageServerIp = pingStorageServerIp;
+    }
+
+    public String getPingDir() {
+        return pingDir;
+    }
+
+    public void setPingDir(String pingDir) {
+        this.pingDir = pingDir;
+    }
+
+    public String getTftpDir() {
+        return tftpDir;
+    }
+
+    public void setTftpDir(String tftpDir) {
+        this.tftpDir = tftpDir;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResourceBase.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResourceBase.java
new file mode 100755
index 0000000..34175c8
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResourceBase.java
@@ -0,0 +1,157 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// 
+// Automatically generated by addcopyright.py at 01/29/2013
+// Apache License, Version 2.0 (the "License"); you may not use this
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// 
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.baremetal.networkservice;
+
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupPxeServerCommand;
+import com.cloud.host.Host.Type;
+import com.cloud.resource.ServerResource;
+
+public class BaremetalPxeResourceBase implements ServerResource {
+	private static final Logger s_logger = Logger.getLogger(BaremetalPxeResourceBase.class);
+	String _name;
+	String _guid;
+	String _username;
+	String _password;
+	String _ip;
+	String _zoneId;
+	String _podId;
+	
+	@Override
+	public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+		_name = name;
+		_guid = (String)params.get(BaremetalPxeService.PXE_PARAM_GUID);
+		_ip = (String)params.get(BaremetalPxeService.PXE_PARAM_IP);
+		_username = (String)params.get(BaremetalPxeService.PXE_PARAM_USERNAME);
+		_password = (String)params.get(BaremetalPxeService.PXE_PARAM_PASSWORD);
+		_zoneId = (String)params.get(BaremetalPxeService.PXE_PARAM_ZONE);
+		_podId = (String)params.get(BaremetalPxeService.PXE_PARAM_POD);
+
+		if (_guid == null) {
+			throw new ConfigurationException("No Guid specified");
+		}
+		
+		if (_zoneId == null) {
+			throw new ConfigurationException("No Zone specified");
+		}
+		
+		if (_ip == null) {
+			throw new ConfigurationException("No IP specified");
+		}
+		
+		if (_username == null) {
+			throw new ConfigurationException("No username specified");
+		}
+		
+		if (_password == null) {
+			throw new ConfigurationException("No password specified");
+		}
+		
+		return true;
+	}
+	
+	protected ReadyAnswer execute(ReadyCommand cmd) {
+		s_logger.debug("Pxe resource " + _name + " is ready");
+		return new ReadyAnswer(cmd);
+	}
+
+	@Override
+	public boolean start() {
+		return true;
+	}
+
+	@Override
+	public boolean stop() {
+		return true;
+	}
+
+	@Override
+	public String getName() {
+		// TODO Auto-generated method stub
+		return _name;
+	}
+
+	@Override
+	public Type getType() {
+		return Type.BaremetalPxe;
+	}
+
+	@Override
+	public StartupCommand[] initialize() {
+		StartupPxeServerCommand cmd = new StartupPxeServerCommand();
+		cmd.setName(_name);
+		cmd.setDataCenter(_zoneId);
+		cmd.setPod(_podId);
+		cmd.setPrivateIpAddress(_ip);
+		cmd.setStorageIpAddress("");
+		cmd.setVersion("");
+		cmd.setGuid(_guid);
+		return new StartupCommand[]{cmd};
+	}
+
+	@Override
+	public PingCommand getCurrentStatus(long id) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void disconnected() {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	public IAgentControl getAgentControl() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void setAgentControl(IAgentControl agentControl) {
+		// TODO Auto-generated method stub
+
+	}
+	
+	@Override
+	public Answer executeRequest(Command cmd) {
+		if (cmd instanceof ReadyCommand) {
+			return execute((ReadyCommand) cmd);
+		} else {
+			return Answer.createUnsupportedCommandAnswer(cmd);
+		}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResponse.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResponse.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResponse.java
new file mode 100755
index 0000000..2103020
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeResponse.java
@@ -0,0 +1,71 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// 
+// Automatically generated by addcopyright.py at 01/29/2013
+package com.cloud.baremetal.networkservice;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+public class BaremetalPxeResponse extends BaseResponse {
+    @SerializedName(ApiConstants.ID) @Param(description="device id of ")
+    private String id;
+    
+    @SerializedName(ApiConstants.PHYSICAL_NETWORK_ID) @Param(description="the physical network to which this external dhcp device belongs to")
+    private String physicalNetworkId;
+    
+    @SerializedName(ApiConstants.PROVIDER) @Param(description="name of the provider")
+    private String providerId;
+    
+    @SerializedName(ApiConstants.POD_ID) @Param(description="pod id where the device is in")
+    private String podId;
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getPhysicalNetworkId() {
+		return physicalNetworkId;
+	}
+
+	public void setPhysicalNetworkId(String physicalNetworkId) {
+		this.physicalNetworkId = physicalNetworkId;
+	}
+
+	public String getProviderId() {
+		return providerId;
+	}
+
+	public void setProviderId(String providerId) {
+		this.providerId = providerId;
+	}
+
+	public String getPodId() {
+		return podId;
+	}
+
+	public void setPodId(String podId) {
+		this.podId = podId;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java
new file mode 100644
index 0000000..8504f82
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeService.java
@@ -0,0 +1,61 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// 
+// Automatically generated by addcopyright.py at 01/29/2013
+// Apache License, Version 2.0 (the "License"); you may not use this
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// 
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.baremetal.networkservice;
+
+import java.util.List;
+
+import com.cloud.baremetal.database.BaremetalPxeVO;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.host.Host;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.component.Adapter;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachineProfile;
+
+public interface BaremetalPxeService extends Adapter {
+	
+	public boolean prepare(VirtualMachineProfile<UserVmVO> profile, NicProfile nic, DeployDestination dest, ReservationContext context);
+
+    public boolean prepareCreateTemplate(Long pxeServerId, UserVm vm, String templateUrl);
+    
+    BaremetalPxeVO addPxeServer(AddBaremetalPxeCmd cmd);
+	
+    BaremetalPxeResponse getApiResponse(BaremetalPxeVO vo);
+	
+	List<BaremetalPxeResponse> listPxeServers(ListBaremetalPxePingServersCmd cmd);
+	
+	public static final String PXE_PARAM_TYPE = "type";
+	public static final String PXE_PARAM_ZONE = "zone";
+	public static final String PXE_PARAM_POD = "pod";
+	public static final String PXE_PARAM_IP = "ip";
+	public static final String PXE_PARAM_GUID = "guid";
+	public static final String PXE_PARAM_TFTP_DIR = "tftpDir";
+	public static final String PXE_PARAM_USERNAME = "username";
+	public static final String PXE_PARAM_PASSWORD = "password";
+	public static final String PXE_PARAM_PING_STORAGE_SERVER_IP = "pingStorageServerIp";
+	public static final String PXE_PARAM_PING_ROOT_DIR = "pingDir";
+	public static final String PXE_PARAM_PING_STORAGE_SERVER_USERNAME = "pingStorageServerUserName";
+	public static final String PXE_PARAM_PING_STORAGE_SERVER_PASSWORD = "pingStorageServerPassword";	
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
new file mode 100755
index 0000000..d1f0e8b
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
@@ -0,0 +1,169 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// 
+// Automatically generated by addcopyright.py at 01/29/2013
+package com.cloud.baremetal.networkservice;
+
+import java.util.HashMap;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ejb.Local;
+
+import com.cloud.baremetal.manager.BaremetalManager;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.GuestType;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.element.IpDeployer;
+import com.cloud.network.element.NetworkElement;
+import com.cloud.network.element.UserDataServiceProvider;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.component.Inject;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Local(value = NetworkElement.class)
+public class BaremetalUserdataElement extends AdapterBase implements NetworkElement, UserDataServiceProvider {
+    private static Map<Service, Map<Capability, String>> capabilities;
+    
+    @Inject
+    private BaremetalPxeManager pxeMgr;
+    
+    static {
+        capabilities = new HashMap<Service, Map<Capability, String>>();
+        capabilities.put(Service.UserData, null);
+    }
+    
+    private boolean canHandle(DeployDestination dest)  {
+        if (dest.getDataCenter().getNetworkType() == NetworkType.Basic && dest.getHost().getHypervisorType() == HypervisorType.BareMetal) {
+            return true;
+        }
+        return false;
+    }
+    
+    @Override
+    public boolean addPasswordAndUserdata(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest,
+            ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
+        if (!canHandle(dest)) {
+            return false;
+        }
+        
+        if (vm.getType() != VirtualMachine.Type.User) {
+            return false;
+        }
+        
+        return pxeMgr.addUserData(nic, (VirtualMachineProfile<UserVm>) vm);
+    }
+
+    @Override
+    public boolean savePassword(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm) throws ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Map<Service, Map<Capability, String>> getCapabilities() {
+        return capabilities;
+    }
+
+    @Override
+    public Provider getProvider() {
+        return BaremetalPxeManager.BAREMETAL_USERDATA_PROVIDER;
+    }
+
+    @Override
+    public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context)
+            throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest,
+            ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean release(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, ReservationContext context)
+            throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isReady(PhysicalNetworkServiceProvider provider) {
+        return true;
+    }
+
+    @Override
+    public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException,
+            ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean canEnableIndividualServices() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+
+    @Override
+    public boolean saveUserData(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm)
+            throws ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean verifyServicesCombination(Set<Service> services) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalDhcpCmd.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalDhcpCmd.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalDhcpCmd.java
new file mode 100755
index 0000000..ba5128b
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalDhcpCmd.java
@@ -0,0 +1,102 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// 
+// Automatically generated by addcopyright.py at 01/29/2013
+package com.cloud.baremetal.networkservice;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseCmd.CommandType;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.PlugService;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+
+public class ListBaremetalDhcpCmd extends BaseListCmd {
+    private static final Logger s_logger = Logger.getLogger(ListBaremetalDhcpCmd.class);
+    private static final String s_name = "listexternaldhcpresponse";
+    @PlugService BaremetalDhcpManager _dhcpMgr;
+    
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+    @Parameter(name = ApiConstants.ID, type = CommandType.LONG, description = "DHCP server device ID")
+    private Long id;
+    
+    @Parameter(name = ApiConstants.POD_ID, type = CommandType.LONG, description = "Pod ID where pxe server is in")
+    private Long podId;
+    
+    @Parameter(name = ApiConstants.DHCP_SERVER_TYPE, type = CommandType.STRING, description = "Type of DHCP device")
+    private String deviceType;
+    
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getPodId() {
+        return podId;
+    }
+
+    public void setPodId(Long podId) {
+        this.podId = podId;
+    }
+    
+    public String getDeviceType() {
+        return deviceType;
+    }
+
+    public void setDeviceType(String deviceType) {
+        this.deviceType = deviceType;
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
+            ResourceAllocationException, NetworkRuleConflictException {
+    	try {
+            ListResponse<BaremetalDhcpResponse> response = new ListResponse<BaremetalDhcpResponse>();
+            List<BaremetalDhcpResponse> dhcpResponses = _dhcpMgr.listBaremetalDhcps(this);
+            response.setResponses(dhcpResponses);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+    	} catch (Exception e) {
+    		s_logger.debug("Exception happend while executing ListBaremetalDhcpCmd");
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+    	}
+
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalPxePingServersCmd.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalPxePingServersCmd.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalPxePingServersCmd.java
new file mode 100755
index 0000000..dceb8bf
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/ListBaremetalPxePingServersCmd.java
@@ -0,0 +1,92 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// 
+// Automatically generated by addcopyright.py at 01/29/2013
+package com.cloud.baremetal.networkservice;
+
+import java.util.List;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseCmd.CommandType;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.PlugService;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+
+public class ListBaremetalPxePingServersCmd extends BaseListCmd {
+    private static final Logger s_logger = Logger.getLogger(ListBaremetalPxePingServersCmd.class);
+    private static final String s_name = "listpingpxeserverresponse";
+
+    @PlugService
+    BaremetalPxeManager _pxeMgr;
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.LONG, description = "Ping pxe server device ID")
+    private Long id;
+    
+    @Parameter(name = ApiConstants.POD_ID, type = CommandType.LONG, description = "Pod ID where pxe server is in")
+    private Long podId;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getPodId() {
+        return podId;
+    }
+
+    public void setPodId(Long podId) {
+        this.podId = podId;
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
+            ResourceAllocationException, NetworkRuleConflictException {
+        try {
+            ListResponse<BaremetalPxeResponse> response = new ListResponse<BaremetalPxeResponse>();
+            List<BaremetalPxeResponse> pxeResponses = _pxeMgr.listPxeServers(this);
+            response.setResponses(pxeResponses);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } catch (Exception e) {
+            s_logger.debug("Exception happend while executing ListPingPxeServersCmd" ,e);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
+        }
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/PrepareKickstartPxeServerCommand.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/PrepareKickstartPxeServerCommand.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/PrepareKickstartPxeServerCommand.java
new file mode 100755
index 0000000..8951547
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/PrepareKickstartPxeServerCommand.java
@@ -0,0 +1,74 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// 
+// Automatically generated by addcopyright.py at 01/29/2013
+package com.cloud.baremetal.networkservice;
+
+import com.cloud.agent.api.Command;
+
+public class PrepareKickstartPxeServerCommand extends Command {
+    private String ksFile;
+    private String repo;
+    private String templateUuid;
+    private String mac;
+    private String ksDevice;
+    
+    @Override
+    public boolean executeInSequence() {
+        return true;
+    }
+
+    public String getKsFile() {
+        return ksFile;
+    }
+
+    public void setKsFile(String ksFile) {
+        this.ksFile = ksFile;
+    }
+
+    public String getRepo() {
+        return repo;
+    }
+
+    public void setRepo(String repo) {
+        this.repo = repo;
+    }
+
+    public String getTemplateUuid() {
+        return templateUuid;
+    }
+
+    public void setTemplateUuid(String templateUuid) {
+        this.templateUuid = templateUuid;
+    }
+
+    public String getMac() {
+        return mac;
+    }
+
+    public void setMac(String mac) {
+        this.mac = mac;
+    }
+
+    public String getKsDevice() {
+        return ksDevice;
+    }
+
+    public void setKsDevice(String ksDevice) {
+        this.ksDevice = ksDevice;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java
new file mode 100755
index 0000000..203fed3
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/SecurityGroupHttpClient.java
@@ -0,0 +1,18 @@
+package com.cloud.baremetal.networkservice;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.SecurityGroupRulesCmd;
+
+public class SecurityGroupHttpClient {
+
+	public Answer call(String guestIp, SecurityGroupRulesCmd cmd) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public boolean echo(String ip, long millis, long millis2) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/pom.xml b/plugins/pom.xml
index 7bb60a9..c5b6e58 100644
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -42,6 +42,7 @@
     <module>hypervisors/xen</module>
     <module>hypervisors/kvm</module>
     <module>hypervisors/simulator</module>
+    <module>hypervisors/baremetal</module>
     <module>network-elements/elastic-loadbalancer</module>
     <module>network-elements/ovs</module>
     <module>network-elements/nicira-nvp</module>

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/server/src/com/cloud/configuration/Config.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index 4ae144e..5e4996b 100755
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -358,7 +358,13 @@ public enum Config {
     DetailBatchQuerySize("Advanced", ManagementServer.class, Integer.class, "detail.batch.query.size", "2000", "Default entity detail batch query size for listing", null),
 
 	ConcurrentSnapshotsThresholdPerHost("Advanced", ManagementServer.class, Long.class, "concurrent.snapshots.threshold.perhost",
-	                null, "Limits number of snapshots that can be handled by the host concurrently; default is NULL - unlimited", null);
+	                null, "Limits number of snapshots that can be handled by the host concurrently; default is NULL - unlimited", null),
+	
+	ExternalBaremetalSystemUrl("Advanced", ManagementServer.class, String.class, "external.baremetal.system.url", null, "url of external baremetal system that CloudStack will talk to", null),
+	ExternalBaremetalResourceClassName("Advanced", ManagementServer.class, String.class, "external,baremetal.resource.classname", null, "class name for handling external baremetal resource", null),
+	EnableBaremetalSecurityGroupAgentEcho("Advanced", ManagementServer.class, Boolean.class, "enable.baremetal.securitygroup.agent.echo", "false", "After starting provision process, periodcially echo security agent installed in the template. Treat provisioning as success only if echo successfully", null),
+	IntervalToEchoBaremetalSecurityGroupAgent("Advanced", ManagementServer.class, Integer.class, "interval.baremetal.securitygroup.agent.echo", "10", "Interval to echo baremetal security group agent, in seconds", null),
+	TimeoutToEchoBaremetalSecurityGroupAgent("Advanced", ManagementServer.class, Integer.class, "timeout.baremetal.securitygroup.agent.echo", "3600", "Timeout to echo baremetal security group agent, in seconds, the provisioning process will be treated as a failure", null);
 
 	private final String _category;
 	private final Class<?> _componentClass;