You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ke...@apache.org on 2013/01/31 20:40:12 UTC
[18/50] [abbrv] git commit: refs/heads/javelin - CloudStack
CLOUDSTACK-774 Supporting kickstart in CloudStack baremetal
CloudStack CLOUDSTACK-774
Supporting kickstart in CloudStack baremetal
merge baremetal feature to master
Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/1f7eaf3d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/1f7eaf3d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/1f7eaf3d
Branch: refs/heads/javelin
Commit: 1f7eaf3d61ed780da2df3cbf772c77407dea6f2c
Parents: 867cb4a
Author: frank <fr...@citrix.com>
Authored: Tue Jan 29 17:19:15 2013 -0800
Committer: frank <fr...@citrix.com>
Committed: Tue Jan 29 17:19:57 2013 -0800
----------------------------------------------------------------------
api/src/com/cloud/event/EventTypes.java | 6 +
api/src/com/cloud/host/Host.java | 2 +
.../org/apache/cloudstack/api/ApiConstants.java | 1 +
plugins/hypervisors/baremetal/pom.xml | 37 +
.../resources/security_group_agent/cs-sgagent | 51 ++
.../security_group_agent/__init__.py | 18 +
.../security_group_agent/cs_sg_agent.py | 237 ++++++
.../security_group_agent/sglib.py | 226 ++++++
.../security_group_agent/xmlobject.py | 97 +++
.../resources/security_group_agent/setup.py | 44 +
.../cloud/baremetal/database/BaremetalCmdbDao.java | 25 +
.../baremetal/database/BaremetalCmdbDaoImpl.java | 29 +
.../cloud/baremetal/database/BaremetalCmdbVO.java | 104 +++
.../cloud/baremetal/database/BaremetalDhcpDao.java | 25 +
.../baremetal/database/BaremetalDhcpDaoImpl.java | 42 +
.../cloud/baremetal/database/BaremetalDhcpVO.java | 118 +++
.../cloud/baremetal/database/BaremetalPxeDao.java | 26 +
.../baremetal/database/BaremetalPxeDaoImpl.java | 38 +
.../cloud/baremetal/database/BaremetalPxeVO.java | 115 +++
.../baremetal/manager/AddBaremetalHostCmd.java | 41 +
.../baremetal/manager/BareMetalDiscoverer.java | 280 +++++++
.../com/cloud/baremetal/manager/BareMetalGuru.java | 87 ++
.../manager/BareMetalTemplateAdapter.java | 217 +++++
.../cloud/baremetal/manager/BaremetalManager.java | 28 +
.../baremetal/manager/BaremetalManagerImpl.java | 112 +++
.../networkservice/AddBaremetalDhcpCmd.java | 149 ++++
.../AddBaremetalKickStartPxeCmd.java | 36 +
.../networkservice/AddBaremetalPxeCmd.java | 144 ++++
.../AddBaremetalPxePingServerCmd.java | 80 ++
.../networkservice/BareMetalPingServiceImpl.java | 300 +++++++
.../networkservice/BareMetalPxeServiceBase.java | 68 ++
.../networkservice/BareMetalResourceBase.java | 618 +++++++++++++++
.../networkservice/BaremetaNetworkGuru.java | 173 ++++
.../networkservice/BaremetalDhcpElement.java | 178 +++++
.../networkservice/BaremetalDhcpManager.java | 58 ++
.../networkservice/BaremetalDhcpManagerImpl.java | 323 ++++++++
.../networkservice/BaremetalDhcpResourceBase.java | 174 ++++
.../networkservice/BaremetalDhcpResponse.java | 71 ++
.../networkservice/BaremetalDhcpdResource.java | 139 ++++
.../networkservice/BaremetalDnsmasqResource.java | 129 +++
.../BaremetalKickStartPxeResource.java | 201 +++++
.../BaremetalKickStartServiceImpl.java | 238 ++++++
.../networkservice/BaremetalPingPxeResource.java | 260 ++++++
.../networkservice/BaremetalPxeElement.java | 178 +++++
.../BaremetalPxeKickStartResponse.java | 37 +
.../networkservice/BaremetalPxeManager.java | 65 ++
.../networkservice/BaremetalPxeManagerImpl.java | 242 ++++++
.../networkservice/BaremetalPxePingResponse.java | 59 ++
.../networkservice/BaremetalPxeResourceBase.java | 157 ++++
.../networkservice/BaremetalPxeResponse.java | 71 ++
.../networkservice/BaremetalPxeService.java | 61 ++
.../networkservice/BaremetalUserdataElement.java | 169 ++++
.../networkservice/ListBaremetalDhcpCmd.java | 102 +++
.../ListBaremetalPxePingServersCmd.java | 92 +++
.../PrepareKickstartPxeServerCommand.java | 74 ++
.../networkservice/SecurityGroupHttpClient.java | 18 +
plugins/pom.xml | 1 +
server/src/com/cloud/configuration/Config.java | 8 +-
58 files changed, 6678 insertions(+), 1 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/api/src/com/cloud/event/EventTypes.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java
index 87eddca..63b7cd0 100755
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -313,4 +313,10 @@ public class EventTypes {
public static final String EVENT_AUTOSCALEVMGROUP_UPDATE = "AUTOSCALEVMGROUP.UPDATE";
public static final String EVENT_AUTOSCALEVMGROUP_ENABLE = "AUTOSCALEVMGROUP.ENABLE";
public static final String EVENT_AUTOSCALEVMGROUP_DISABLE = "AUTOSCALEVMGROUP.DISABLE";
+
+ public static final String EVENT_BAREMETAL_DHCP_SERVER_ADD = "PHYSICAL.DHCP.ADD";
+ public static final String EVENT_BAREMETAL_DHCP_SERVER_DELETE = "PHYSICAL.DHCP.DELETE";
+
+ public static final String EVENT_BAREMETAL_PXE_SERVER_ADD = "PHYSICAL.PXE.ADD";
+ public static final String EVENT_BAREMETAL_PXE_SERVER_DELETE = "PHYSICAL.PXE.DELETE";
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/api/src/com/cloud/host/Host.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/host/Host.java b/api/src/com/cloud/host/Host.java
index bd26f81..7236680 100755
--- a/api/src/com/cloud/host/Host.java
+++ b/api/src/com/cloud/host/Host.java
@@ -39,6 +39,8 @@ public interface Host extends StateObject<Status>, Identity, InternalIdentity {
ExternalLoadBalancer(false),
ExternalVirtualSwitchSupervisor(false),
PxeServer(false),
+ BaremetalPxe(false),
+ BaremetalDhcp(false),
TrafficMonitor(false),
ExternalDhcp(false),
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
old mode 100644
new mode 100755
index 58a7831..d084271
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -427,6 +427,7 @@ public class ApiConstants {
public static final String CONDITION_IDS = "conditionids";
public static final String COUNTERPARAM_LIST = "counterparam";
public static final String AUTOSCALE_USER_ID = "autoscaleuserid";
+ public static final String BAREMETAL_DISCOVER_NAME = "baremetaldiscovername";
public enum HostDetails {
all, capacity, events, stats, min;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/pom.xml b/plugins/hypervisors/baremetal/pom.xml
new file mode 100755
index 0000000..600eedb
--- /dev/null
+++ b/plugins/hypervisors/baremetal/pom.xml
@@ -0,0 +1,37 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloudstack-plugins</artifactId>
+ <version>4.1.0-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+ <artifactId>cloud-plugin-hypervisor-baremetal</artifactId>
+ <name>Apache CloudStack Plugin - Hypervisor Baremetal</name>
+ <dependencies>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent b/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent
new file mode 100755
index 0000000..cda7017
--- /dev/null
+++ b/plugins/hypervisors/baremetal/resources/security_group_agent/cs-sgagent
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+# the following is chkconfig init header
+#
+# cs-sgagent: cloudStack baremetal sercurity group agent
+#
+# chkconfig: 345 97 03
+# description: This is a daemon instructed by CloudStack management server \
+# to perform baremetal security group related operations\
+#
+# processname: cs-sgagent
+# pidfile: /var/run/cssgagent.pid
+#
+
+check_status() {
+ pidfile='/var/run/cssgagent.pid'
+ if [ ! -f $pidfile ]; then
+ echo "cloudstack baremetal security group agent is stopped"
+ exit 1
+ else
+ pid=`cat $pidfile`
+ ps -p $pid > /dev/null
+ if [ $? -eq 0 ]; then
+ echo "cloudstack baremetal security group agent is running, pid is $pid"
+ exit 0
+ else
+ echo "cloudstack baremetal security group agent is stopped, but pidfile at $pidfile is not cleaned. It may be caused by the agent crashed at last time, manually cleaning it would be ok"
+ exit 1
+ fi
+ fi
+}
+
+if [ $# -eq 0 ]; then
+ echo "usage: $0
+[start|stop|restart|status]"
+ exit 1
+fi
+
+if [ "$@" = "status" ]; then
+ check_status
+else
+ python -c "from security_group_agent import cs_sg_agent; cs_sg_agent.main()" $@
+fi
+
+if [ $? -eq 0 ]; then
+ echo "$@ cloudstack baremetal security group agent .... SUCCESS"
+ exit 0
+else
+ echo "$@ cloudstack baremetal security group agent .... FAILED"
+ exit 1
+fi
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py
new file mode 100644
index 0000000..f7f5f60
--- /dev/null
+++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/__init__.py
@@ -0,0 +1,18 @@
+# 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
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py
new file mode 100755
index 0000000..a292c0b
--- /dev/null
+++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/cs_sg_agent.py
@@ -0,0 +1,237 @@
+# 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
+'''
+Created on Jan 2, 2013
+
+@author: frank
+'''
+import cherrypy
+import sglib
+import xmlobject
+import types
+import uuid
+import os.path
+import sys
+import os
+
+class SGRule(object):
+ def __init__(self):
+ self.protocol = None
+ self.start_port = None
+ self.end_port = None
+ self.allowed_ips = []
+
+class IPSet(object):
+ IPSET_TYPE = 'hash:ip'
+ def __init__(self, setname, ips):
+ self.ips = ips
+ self.name = setname
+
+ def create(self):
+ tmpname = str(uuid.uuid4()).replace('-', '')[0:30]
+ sglib.ShellCmd('ipset -N %s %s' % (tmpname, self.IPSET_TYPE))()
+ try:
+ for ip in self.ips:
+ sglib.ShellCmd('ipset -A %s %s' % (tmpname, ip))()
+
+ try:
+ sglib.ShellCmd('ipset -N %s %s' % (self.name, self.IPSET_TYPE))()
+ cherrypy.log('created new ipset: %s' % self.name)
+ except Exception:
+ cherrypy.log('%s already exists, no need to create new' % self.name)
+ finally:
+ sglib.ShellCmd('ipset -W %s %s' % (tmpname, self.name))()
+ sglib.ShellCmd('ipset -F %s' % tmpname)()
+ sglib.ShellCmd('ipset -X %s' % tmpname)()
+
+ @staticmethod
+ def destroy_sets(sets_to_keep):
+ sets = sglib.ShellCmd('ipset list')()
+ for s in sets.split('\n'):
+ if 'Name:' in s:
+ set_name = s.split(':', 1)[1].strip()
+ if not set_name in sets_to_keep:
+ sglib.ShellCmd('ipset destroy %s' % set_name)()
+ cherrypy.log('destroyed unused ipset: %s' % set_name)
+
+class SGAgent(object):
+ def __init__(self):
+ pass
+
+ def _self_list(self, obj):
+ if isinstance(obj, types.ListType):
+ return obj
+ else:
+ return [obj]
+
+ def set_rules(self, req):
+ body = req.body
+ doc = xmlobject.loads(body)
+ vm_name = doc.vmName.text_
+ vm_id = doc.vmId.text_
+ vm_ip = doc.vmIp.text_
+ vm_mac = doc.vmMac.text_
+ sig = doc.signature.text_
+ seq = doc.sequenceNumber.text_
+
+ def parse_rules(rules, lst):
+ for i in self._self_list(rules):
+ r = SGRule()
+ r.protocol = i.protocol.text_
+ r.start_port = i.startPort.text_
+ r.end_port = i.endPort.text_
+ if hasattr(i, 'ip'):
+ for ip in self._self_list(i.ip):
+ r.allowed_ips.append(ip.text_)
+ lst.append(r)
+
+ i_rules = []
+ if hasattr(doc, 'ingressRules'):
+ parse_rules(doc.ingressRules, i_rules)
+
+ e_rules = []
+ if hasattr(doc, 'egressRules'):
+ parse_rules(doc.egressRules, e_rules)
+
+ def create_chain(name):
+ try:
+ sglib.ShellCmd('iptables -F %s' % name)()
+ except Exception:
+ sglib.ShellCmd('iptables -N %s' % name)()
+
+ def apply_rules(rules, chainname, direction, action, current_set_names):
+ create_chain(chainname)
+ for r in i_rules:
+ allow_any = False
+ if '0.0.0.0/0' in r.allowed_ips:
+ allow_any = True
+ r.allowed_ips.remove('0.0.0.0/0')
+
+ if r.allowed_ips:
+ setname = '_'.join([chainname, r.protocol, r.start_port, r.end_port])
+ ipset = IPSet(setname, r.allowed_ips)
+ ipset.create()
+ current_set_names.append(setname)
+
+ if r.protocol == 'all':
+ cmd = ['iptables -I', chainname, '-m state --state NEW -m set --set', setname, direction, '-j', action]
+ sglib.ShellCmd(' '.join(cmd))()
+ elif r.protocol != 'icmp':
+ port_range = ":".join([r.start_port, r.end_port])
+ cmd = ['iptables', '-I', chainname, '-p', r.protocol, '-m', r.protocol, '--dport', port_range, '-m state --state NEW -m set --set', setname, direction, '-j', action]
+ sglib.ShellCmd(' '.join(cmd))()
+ else:
+ port_range = "/".join([r.start_port, r.end_port])
+ if r.start_port == "-1":
+ port_range = "any"
+ cmd = ['iptables', '-I', i_chain_name, '-p', 'icmp', '--icmp-type', port_range, '-m set --set', setname, direction, '-j', action]
+ sglib.ShellCmd(' '.join(cmd))()
+
+
+ if allow_any and r.protocol != 'all':
+ if r.protocol != 'icmp':
+ port_range = ":".join([r.start_port, r.end_port])
+ cmd = ['iptables', '-I', chainname, '-p', r.protocol, '-m', r.protocol, '--dport', port_range, '-m', 'state', '--state', 'NEW', '-j', action]
+ sglib.ShellCmd(' '.join(cmd))()
+ else:
+ port_range = "/".join([r.start_port, r.end_port])
+ if r.start_port == "-1":
+ port_range = "any"
+ cmd = ['iptables', '-I', i_chain_name, '-p', 'icmp', '--icmp-type', port_range, '-j', action]
+ sglib.ShellCmd(' '.join(cmd))()
+
+ current_sets = []
+ i_chain_name = vm_name + '-in'
+ apply_rules(i_rules, i_chain_name, 'src', 'ACCEPT', current_sets)
+ e_chain_name = vm_name + '-eg'
+ apply_rules(e_rules, e_chain_name, 'dst', 'RETURN', current_sets)
+
+ if e_rules:
+ sglib.ShellCmd('iptables -A %s -j RETURN' % e_chain_name)
+ else:
+ sglib.ShellCmd('iptables -A %s -j DROP' % e_chain_name)
+
+ sglib.ShellCmd('iptables -A %s -j DROP' % i_chain_name)
+ IPSet.destroy_sets(current_sets)
+
+
+ def echo(self, req):
+ cherrypy.log("echo: I am alive")
+
+ def index(self):
+ req = sglib.Request.from_cherrypy_request(cherrypy.request)
+ cmd_name = req.headers['command']
+
+ if not hasattr(self, cmd_name):
+ raise ValueError("SecurityGroupAgent doesn't have a method called '%s'" % cmd_name)
+ method = getattr(self, cmd_name)
+
+ return method(req)
+ index.exposed = True
+
+ @staticmethod
+ def start():
+ cherrypy.log.access_file = '/var/log/cs-securitygroup.log'
+ cherrypy.log.error_file = '/var/log/cs-securitygroup.log'
+ cherrypy.server.socket_host = '0.0.0.0'
+ cherrypy.server.socket_port = 9988
+ cherrypy.quickstart(SGAgent())
+
+ @staticmethod
+ def stop():
+ cherrypy.engine.exit()
+
+PID_FILE = '/var/run/cssgagent.pid'
+class SGAgentDaemon(sglib.Daemon):
+ def __init__(self):
+ super(SGAgentDaemon, self).__init__(PID_FILE)
+ self.is_stopped = False
+ self.agent = SGAgent()
+ sglib.Daemon.register_atexit_hook(self._do_stop)
+
+ def _do_stop(self):
+ if self.is_stopped:
+ return
+ self.is_stopped = True
+ self.agent.stop()
+
+ def run(self):
+ self.agent.start()
+
+ def stop(self):
+ self.agent.stop()
+ super(SGAgentDaemon, self).stop()
+
+def main():
+ usage = 'usage: python -c "from security_group_agent import cs_sg_agent; cs_sg_agent.main()" start|stop|restart'
+ if len(sys.argv) != 2 or not sys.argv[1] in ['start', 'stop', 'restart']:
+ print usage
+ sys.exit(1)
+
+ cmd = sys.argv[1]
+ agentdaemon = SGAgentDaemon()
+ if cmd == 'start':
+ agentdaemon.start()
+ elif cmd == 'stop':
+ agentdaemon.stop()
+ else:
+ agentdaemon.restart()
+
+ sys.exit(0)
+
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py
new file mode 100755
index 0000000..bf64eff
--- /dev/null
+++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/sglib.py
@@ -0,0 +1,226 @@
+#!/usr/bin/env python
+# 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
+
+import sys, os, time, atexit
+import traceback
+import subprocess
+from signal import SIGTERM
+import cherrypy
+import copy
+
+class Request(object):
+ def __init__(self):
+ self.headers = None
+ self.body = None
+ self.method = None
+ self.query_string = None
+
+ @staticmethod
+ def from_cherrypy_request(creq):
+ req = Request()
+ req.headers = copy.copy(creq.headers)
+ req.body = creq.body.fp.read() if creq.body else None
+ req.method = copy.copy(creq.method)
+ req.query_string = copy.copy(creq.query_string) if creq.query_string else None
+ return req
+
+class ShellError(Exception):
+ '''shell error'''
+
+class ShellCmd(object):
+ '''
+ classdocs
+ '''
+ def __init__(self, cmd, workdir=None, pipe=True):
+ '''
+ Constructor
+ '''
+ self.cmd = cmd
+ if pipe:
+ self.process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, executable='/bin/sh', cwd=workdir)
+ else:
+ self.process = subprocess.Popen(cmd, shell=True, executable='/bin/sh', cwd=workdir)
+
+ self.stdout = None
+ self.stderr = None
+ self.return_code = None
+
+ def __call__(self, is_exception=True):
+ (self.stdout, self.stderr) = self.process.communicate()
+ if is_exception and self.process.returncode != 0:
+ err = []
+ err.append('failed to execute shell command: %s' % self.cmd)
+ err.append('return code: %s' % self.process.returncode)
+ err.append('stdout: %s' % self.stdout)
+ err.append('stderr: %s' % self.stderr)
+ raise ShellError('\n'.join(err))
+
+ self.return_code = self.process.returncode
+ return self.stdout
+
+class Daemon(object):
+ """
+ A generic daemon class.
+
+ Usage: subclass the Daemon class and override the run() method
+ """
+ atexit_hooks = []
+
+ def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
+ self.stdin = stdin
+ self.stdout = stdout
+ self.stderr = stderr
+ self.pidfile = pidfile
+
+ @staticmethod
+ def register_atexit_hook(hook):
+ Daemon.atexit_hooks.append(hook)
+
+ @staticmethod
+ def _atexit():
+ for hook in Daemon.atexit_hooks:
+ try:
+ hook()
+ except Exception:
+ content = traceback.format_exc()
+ err = 'Exception when calling atexit hook[%s]\n%s' % (hook.__name__, content)
+ #logger.error(err)
+
+ def daemonize(self):
+ """
+ do the UNIX double-fork magic, see Stevens' "Advanced
+ Programming in the UNIX Environment" for details (ISBN 0201563177)
+ http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
+ """
+ try:
+ pid = os.fork()
+ if pid > 0:
+ # exit first parent
+ sys.exit(0)
+ except OSError, e:
+ sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
+ sys.exit(1)
+
+ # decouple from parent environment
+ os.chdir("/")
+ os.setsid()
+ os.umask(0)
+
+ # do second fork
+ try:
+ pid = os.fork()
+ if pid > 0:
+ # exit from second parent
+ sys.exit(0)
+ except OSError, e:
+ sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
+ sys.exit(1)
+
+ # redirect standard file descriptors
+ sys.stdout.flush()
+ sys.stderr.flush()
+ si = file(self.stdin, 'r')
+ so = file(self.stdout, 'a+')
+ se = file(self.stderr, 'a+', 0)
+ os.dup2(si.fileno(), sys.stdin.fileno())
+ os.dup2(so.fileno(), sys.stdout.fileno())
+ os.dup2(se.fileno(), sys.stderr.fileno())
+
+ # write pidfile
+ Daemon.register_atexit_hook(self.delpid)
+ atexit.register(Daemon._atexit)
+ pid = str(os.getpid())
+ file(self.pidfile,'w').write("%s\n" % pid)
+
+ def delpid(self):
+ os.remove(self.pidfile)
+
+ def start(self):
+ """
+ Start the daemon
+ """
+ # Check for a pidfile to see if the daemon already runs
+ try:
+ pf = file(self.pidfile,'r')
+ pid = int(pf.read().strip())
+ pf.close()
+ except IOError:
+ pid = None
+
+ if pid:
+ pscmd = ShellCmd('ps -p %s > /dev/null' % pid)
+ pscmd(is_exception=False)
+ if pscmd.return_code == 0:
+ message = "Daemon already running, pid is %s\n"
+ sys.stderr.write(message % pid)
+ sys.exit(0)
+
+ # Start the daemon
+ self.daemonize()
+ try:
+ self.run()
+ except Exception:
+ content = traceback.format_exc()
+ #logger.error(content)
+ sys.exit(1)
+
+ def stop(self):
+ """
+ Stop the daemon
+ """
+ # Get the pid from the pidfile
+ try:
+ pf = file(self.pidfile,'r')
+ pid = int(pf.read().strip())
+ pf.close()
+ except IOError:
+ pid = None
+
+ if not pid:
+ message = "pidfile %s does not exist. Daemon not running?\n"
+ sys.stderr.write(message % self.pidfile)
+ return # not an error in a restart
+
+ # Try killing the daemon process
+ try:
+ while 1:
+ os.kill(pid, SIGTERM)
+ time.sleep(0.1)
+ except OSError, err:
+ err = str(err)
+ if err.find("No such process") > 0:
+ if os.path.exists(self.pidfile):
+ os.remove(self.pidfile)
+ else:
+ print str(err)
+ sys.exit(1)
+
+ def restart(self):
+ """
+ Restart the daemon
+ """
+ self.stop()
+ self.start()
+
+ def run(self):
+ """
+ You should override this method when you subclass Daemon. It will be called after the process has been
+ daemonized by start() or restart().
+ """
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py
new file mode 100755
index 0000000..cb66d26
--- /dev/null
+++ b/plugins/hypervisors/baremetal/resources/security_group_agent/security_group_agent/xmlobject.py
@@ -0,0 +1,97 @@
+# 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
+'''
+Created on Dec 25, 2012
+
+@author: Frank
+'''
+import xml.etree.ElementTree as etree
+import re
+import types
+
+class XmlObject(object):
+ def __init__(self, tag):
+ self.__tag_name__ = tag
+
+ def put_attr(self, name, val):
+ val = val.strip().strip('\t')
+ setattr(self, name + '_', val)
+
+ def put_text(self, val):
+ val = val.strip().strip('\n').strip('\t')
+ if val == "":
+ setattr(self, 'text_', None)
+ else:
+ setattr(self, 'text_', val)
+
+ def put_node(self, name, val):
+ if not hasattr(self, name):
+ setattr(self, name, val)
+ return
+
+ nodes = getattr(self, name)
+ if not isinstance(nodes, types.ListType):
+ nodes = []
+ old = getattr(self, name)
+ nodes.append(old)
+ nodes.append(val)
+ setattr(self, name, nodes)
+ else:
+ nodes.append(val)
+ setattr(self, name, nodes)
+
+ def get(self, name, default=None):
+ if hasattr(self, name):
+ val = getattr(self, name)
+ if name.endswith('_'):
+ return val
+ else:
+ return val.text_
+ else:
+ return default
+
+ def __getattr__(self, name):
+ if name.endswith('__'):
+ n = name[:-1]
+ if hasattr(self, n):
+ return getattr(self, n)
+ else:
+ return None
+ else:
+ e = AttributeError('%s has no attribute %s. missing attribute %s in element <%s>' % (self.__class__.__name__, name, name, self.__tag_name__))
+ setattr(e, 'missing_attrib', name)
+ setattr(e, 'tag_name', self.__tag_name__)
+ raise e
+
+
+def _loads(node):
+ xo = XmlObject(node.tag)
+ for key in node.attrib.keys():
+ xo.put_attr(key, node.attrib.get(key))
+ if node.text:
+ xo.put_text(node.text)
+ for n in list(node):
+ sub_xo = _loads(n)
+ xo.put_node(n.tag, sub_xo)
+ return xo
+
+def loads(xmlstr):
+ xmlstr = re.sub(r'xmlns=".*"', '', xmlstr)
+ root = etree.fromstring(xmlstr)
+ return _loads(root)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py b/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py
new file mode 100755
index 0000000..2de41d2
--- /dev/null
+++ b/plugins/hypervisors/baremetal/resources/security_group_agent/setup.py
@@ -0,0 +1,44 @@
+# 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
+from setuptools import setup, find_packages
+import sys, os
+
+version = '1.0'
+
+setup(name='security_group_agent',
+ version=version,
+ description="security group agent for CloudStack Baremetal",
+ long_description="""\
+security group agent for CloudStack Baremetal""",
+ classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
+ keywords='security group cloudstack',
+ author='Frank Zhang',
+ author_email='frank.zhang@citrix.com',
+ url='http://incubator.apache.org/cloudstack/',
+ license='Apache License 2',
+ packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
+ include_package_data=True,
+ zip_safe=True,
+ install_requires=[
+ 'CherryPy',
+ ],
+ entry_points="""
+ # -*- Entry points: -*-
+ """,
+ )
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalCmdbDao.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalCmdbDao.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalCmdbDao.java
new file mode 100755
index 0000000..0f20c67
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalCmdbDao.java
@@ -0,0 +1,25 @@
+// 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.database;
+
+import com.cloud.utils.db.GenericDao;
+
+public interface BaremetalCmdbDao extends GenericDao<BaremetalCmdbVO, Long> {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalCmdbDaoImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalCmdbDaoImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalCmdbDaoImpl.java
new file mode 100755
index 0000000..fcc95ef
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalCmdbDaoImpl.java
@@ -0,0 +1,29 @@
+// 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.database;
+
+import javax.ejb.Local;
+
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+@Local(value = {BaremetalCmdbDao.class})
+@DB(txn = false)
+public class BaremetalCmdbDaoImpl extends GenericDaoBase<BaremetalCmdbVO, Long> implements BaremetalCmdbDao {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalCmdbVO.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalCmdbVO.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalCmdbVO.java
new file mode 100755
index 0000000..ee3848a
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalCmdbVO.java
@@ -0,0 +1,104 @@
+// 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.database;
+
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="baremetal_cmdb")
+public class BaremetalCmdbVO {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id")
+ private long id;
+
+ @Column(name="uuid")
+ private String uuid;
+
+ @Column(name="zone_id")
+ private long zoneId;
+
+ @Column(name="url")
+ private String url;
+
+ @Column(name="password")
+ private String password;
+
+ @Column(name="username")
+ private String username;
+
+ public BaremetalCmdbVO() {
+ uuid = UUID.randomUUID().toString();
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public long getZoneId() {
+ return zoneId;
+ }
+
+ public void setZoneId(long zoneId) {
+ this.zoneId = zoneId;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpDao.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpDao.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpDao.java
new file mode 100644
index 0000000..fe6d86c
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpDao.java
@@ -0,0 +1,25 @@
+// 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.database;
+
+import com.cloud.utils.db.GenericDao;
+
+public interface BaremetalDhcpDao extends GenericDao<BaremetalDhcpVO, Long> {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpDaoImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpDaoImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpDaoImpl.java
new file mode 100644
index 0000000..3d9c6de
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpDaoImpl.java
@@ -0,0 +1,42 @@
+// 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.database;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria2;
+
+@Local(value=BaremetalDhcpDao.class)
+@DB(txn=false)
+public class BaremetalDhcpDaoImpl extends GenericDaoBase<BaremetalDhcpVO, Long> implements BaremetalDhcpDao {
+
+ public BaremetalDhcpDaoImpl() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpVO.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpVO.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpVO.java
new file mode 100644
index 0000000..0bfd541
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalDhcpVO.java
@@ -0,0 +1,118 @@
+// 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.database;
+
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="baremetal_dhcp_devices")
+public class BaremetalDhcpVO {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id")
+ private long id;
+
+ @Column(name="uuid")
+ private String uuid;
+
+ @Column(name = "host_id")
+ private long hostId;
+
+ @Column(name = "pod_id")
+ private long podId;
+
+ @Column(name = "physical_network_id")
+ private long physicalNetworkId;
+
+ @Column(name = "nsp_id")
+ private long networkServiceProviderId ;
+
+ @Column(name = "device_type")
+ private String deviceType;
+
+ public BaremetalDhcpVO() {
+ super();
+ this.uuid = UUID.randomUUID().toString();
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public long getHostId() {
+ return hostId;
+ }
+
+ public void setHostId(long hostId) {
+ this.hostId = hostId;
+ }
+
+ public long getPhysicalNetworkId() {
+ return physicalNetworkId;
+ }
+
+ public void setPhysicalNetworkId(long physicalNetworkId) {
+ this.physicalNetworkId = physicalNetworkId;
+ }
+
+ public String getDeviceType() {
+ return deviceType;
+ }
+
+ public void setDeviceType(String deviceType) {
+ this.deviceType = deviceType;
+ }
+
+ public long getNetworkServiceProviderId() {
+ return networkServiceProviderId;
+ }
+
+ public void setNetworkServiceProviderId(long networkServiceProviderId) {
+ this.networkServiceProviderId = networkServiceProviderId;
+ }
+
+ public long getPodId() {
+ return podId;
+ }
+
+ public void setPodId(long podId) {
+ this.podId = podId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeDao.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeDao.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeDao.java
new file mode 100644
index 0000000..c640638
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeDao.java
@@ -0,0 +1,26 @@
+// 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.database;
+
+import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.db.GenericDaoBase;
+
+public interface BaremetalPxeDao extends GenericDao<BaremetalPxeVO, Long> {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeDaoImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeDaoImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeDaoImpl.java
new file mode 100644
index 0000000..c47d6b2
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeDaoImpl.java
@@ -0,0 +1,38 @@
+// 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.database;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Filter;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria2;
+
+@Local(value = {BaremetalPxeDao.class})
+@DB(txn = false)
+public class BaremetalPxeDaoImpl extends GenericDaoBase<BaremetalPxeVO, Long> implements BaremetalPxeDao {
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeVO.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeVO.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeVO.java
new file mode 100644
index 0000000..e0daa46
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/database/BaremetalPxeVO.java
@@ -0,0 +1,115 @@
+// 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.database;
+
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="baremetal_pxe_devices")
+public class BaremetalPxeVO {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id")
+ private long id;
+
+ @Column(name="uuid")
+ private String uuid;
+
+ @Column(name = "host_id")
+ private long hostId;
+
+ @Column(name = "pod_id")
+ private long podId;
+
+ @Column(name = "physical_network_id")
+ private long physicalNetworkId;
+
+ @Column(name = "nsp_id")
+ private long networkServiceProviderId ;
+
+ @Column(name = "device_type")
+ private String deviceType;
+
+ public long getId() {
+ return id;
+ }
+
+ public BaremetalPxeVO() {
+ uuid = UUID.randomUUID().toString();
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public long getHostId() {
+ return hostId;
+ }
+
+ public void setHostId(long hostId) {
+ this.hostId = hostId;
+ }
+
+ public long getPhysicalNetworkId() {
+ return physicalNetworkId;
+ }
+
+ public void setPhysicalNetworkId(long physicalNetworkId) {
+ this.physicalNetworkId = physicalNetworkId;
+ }
+
+ public long getNetworkServiceProviderId() {
+ return networkServiceProviderId;
+ }
+
+ public void setNetworkServiceProviderId(long networkServiceProviderId) {
+ this.networkServiceProviderId = networkServiceProviderId;
+ }
+
+ 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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/AddBaremetalHostCmd.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/AddBaremetalHostCmd.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/AddBaremetalHostCmd.java
new file mode 100755
index 0000000..5222d10
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/AddBaremetalHostCmd.java
@@ -0,0 +1,41 @@
+// 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 org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.command.admin.host.AddHostCmd;
+
+public class AddBaremetalHostCmd extends AddHostCmd {
+
+ @Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, description="ip address intentionally allocated to this host after provisioning")
+ private String vmIpAddress;
+
+ public AddBaremetalHostCmd() {
+ this.getFullUrlParams().put(ApiConstants.BAREMETAL_DISCOVER_NAME, BareMetalDiscoverer.class.getName());
+ }
+
+ public String getVmIpAddress() {
+ return vmIpAddress;
+ }
+
+ public void setVmIpAddress(String vmIpAddress) {
+ this.vmIpAddress = vmIpAddress;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java
new file mode 100755
index 0000000..64eeaea
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalDiscoverer.java
@@ -0,0 +1,280 @@
+// 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.manager;
+
+import java.net.InetAddress;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.baremetal.networkservice.BareMetalResourceBase;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.exception.DiscoveryException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Network;
+import com.cloud.resource.Discoverer;
+import com.cloud.resource.DiscovererBase;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.exception.CloudRuntimeException;
+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.State;
+import com.cloud.vm.dao.VMInstanceDao;
+
+@Local(value=Discoverer.class)
+public class BareMetalDiscoverer extends DiscovererBase implements Discoverer, ResourceStateAdapter {
+ protected static final Logger s_logger = Logger.getLogger(BareMetalDiscoverer.class);
+ @Inject protected ClusterDao _clusterDao;
+ @Inject protected HostDao _hostDao;
+ @Inject protected DataCenterDao _dcDao;
+ @Inject protected VMInstanceDao _vmDao = null;
+ @Inject protected ResourceManager _resourceMgr;
+ @Inject protected ConfigurationDao _configDao;
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
+ return super.configure(name, params);
+ }
+
+ @Override
+ public boolean stop() {
+ _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName());
+ return super.stop();
+ }
+
+ @Override
+ public Map<? extends ServerResource, Map<String, String>> find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List<String> hostTags)
+ throws DiscoveryException {
+
+ String discoverName = _params.get(ApiConstants.BAREMETAL_DISCOVER_NAME);
+ if (!this.getClass().getName().equals(discoverName)) {
+ return null;
+ }
+
+ Map<BareMetalResourceBase, Map<String, String>> resources = new HashMap<BareMetalResourceBase, Map<String, String>>();
+ Map<String, String> details = new HashMap<String, String>();
+
+ if (!url.getScheme().equals("http")) {
+ String msg = "urlString is not http so we're not taking care of the discovery for this: " + url;
+ s_logger.debug(msg);
+ return null;
+ }
+ if (clusterId == null) {
+ String msg = "must specify cluster Id when add host";
+ s_logger.debug(msg);
+ throw new RuntimeException(msg);
+ }
+
+ if (podId == null) {
+ String msg = "must specify pod Id when add host";
+ s_logger.debug(msg);
+ throw new RuntimeException(msg);
+ }
+
+ ClusterVO cluster = _clusterDao.findById(clusterId);
+ if (cluster == null || (cluster.getHypervisorType() != HypervisorType.BareMetal)) {
+ if (s_logger.isInfoEnabled())
+ s_logger.info("invalid cluster id or cluster is not for Bare Metal hosts");
+ return null;
+ }
+
+ DataCenterVO zone = _dcDao.findById(dcId);
+ if (zone == null) {
+ throw new RuntimeException("Cannot find zone " + dcId);
+ }
+
+ try {
+ String hostname = url.getHost();
+ InetAddress ia = InetAddress.getByName(hostname);
+ String ipmiIp = ia.getHostAddress();
+ String guid = UUID.nameUUIDFromBytes(ipmiIp.getBytes()).toString();
+
+ String injectScript = "scripts/util/ipmi.py";
+ String scriptPath = Script.findScript("", injectScript);
+ if (scriptPath == null) {
+ throw new CloudRuntimeException("Unable to find key ipmi script "
+ + injectScript);
+ }
+
+ final Script2 command = new Script2(scriptPath, s_logger);
+ command.add("ping");
+ command.add("hostname="+ipmiIp);
+ command.add("usrname="+username);
+ command.add("password="+password, ParamType.PASSWORD);
+ final String result = command.execute();
+ if (result != null) {
+ s_logger.warn(String.format("Can not set up ipmi connection(ip=%1$s, username=%2$s, password=%3$s, args) because %4$s", ipmiIp, username, "******", result));
+ return null;
+ }
+
+ ClusterVO clu = _clusterDao.findById(clusterId);
+ if (clu.getGuid() == null) {
+ clu.setGuid(UUID.randomUUID().toString());
+ _clusterDao.update(clusterId, clu);
+ }
+
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.putAll(_params);
+ params.put("zone", Long.toString(dcId));
+ params.put("pod", Long.toString(podId));
+ params.put("cluster", Long.toString(clusterId));
+ params.put("guid", guid);
+ params.put(ApiConstants.PRIVATE_IP, ipmiIp);
+ params.put(ApiConstants.USERNAME, username);
+ params.put(ApiConstants.PASSWORD, password);
+
+ String resourceClassName = _configDao.getValue(Config.ExternalBaremetalResourceClassName.key());
+ BareMetalResourceBase resource = null;
+ if (resourceClassName != null) {
+ Class<?> clazz = Class.forName(resourceClassName);
+ resource = (BareMetalResourceBase) clazz.newInstance();
+ String externalUrl = _configDao.getValue(Config.ExternalBaremetalSystemUrl.key());
+ if (externalUrl == null) {
+ throw new IllegalArgumentException(String.format("You must specify ExternalBaremetalSystemUrl in global config page as ExternalBaremetalResourceClassName is not null"));
+ }
+ details.put(BaremetalManager.ExternalBaremetalSystemUrl, externalUrl);
+ } else {
+ resource = new BareMetalResourceBase();
+ }
+ resource.configure("Bare Metal Agent", params);
+
+ String memCapacity = (String)params.get(ApiConstants.MEMORY);
+ String cpuCapacity = (String)params.get(ApiConstants.CPU_SPEED);
+ String cpuNum = (String)params.get(ApiConstants.CPU_NUMBER);
+ String mac = (String)params.get(ApiConstants.HOST_MAC);
+ if (hostTags != null && hostTags.size() != 0) {
+ details.put("hostTag", hostTags.get(0));
+ }
+ details.put(ApiConstants.MEMORY, memCapacity);
+ details.put(ApiConstants.CPU_SPEED, cpuCapacity);
+ details.put(ApiConstants.CPU_NUMBER, cpuNum);
+ details.put(ApiConstants.HOST_MAC, mac);
+ details.put(ApiConstants.USERNAME, username);
+ details.put(ApiConstants.PASSWORD, password);
+ details.put(ApiConstants.PRIVATE_IP, ipmiIp);
+ String vmIp = (String)params.get(ApiConstants.IP_ADDRESS);
+ if (vmIp != null) {
+ details.put(ApiConstants.IP_ADDRESS, vmIp);
+ }
+ String isEchoScAgent = _configDao.getValue(Config.EnableBaremetalSecurityGroupAgentEcho.key());
+ details.put(BaremetalManager.EchoSecurityGroupAgent, isEchoScAgent);
+
+ resources.put(resource, details);
+ resource.start();
+
+ zone.setGatewayProvider(Network.Provider.ExternalGateWay.getName());
+ zone.setDnsProvider(Network.Provider.ExternalDhcpServer.getName());
+ zone.setDhcpProvider(Network.Provider.ExternalDhcpServer.getName());
+ _dcDao.update(zone.getId(), zone);
+
+ s_logger.debug(String.format("Discover Bare Metal host successfully(ip=%1$s, username=%2$s, password=%3%s," +
+ "cpuNum=%4$s, cpuCapacity-%5$s, memCapacity=%6$s)", ipmiIp, username, "******", cpuNum, cpuCapacity, memCapacity));
+ return resources;
+ } catch (Exception e) {
+ s_logger.warn("Can not set up bare metal agent", e);
+ }
+
+ return null;
+ }
+
+ @Override
+ public void postDiscovery(List<HostVO> hosts, long msId)
+ throws DiscoveryException {
+ }
+
+ @Override
+ public boolean matchHypervisor(String hypervisor) {
+ return hypervisor.equalsIgnoreCase(Hypervisor.HypervisorType.BareMetal.toString());
+ }
+
+ @Override
+ public HypervisorType getHypervisorType() {
+ return Hypervisor.HypervisorType.BareMetal;
+ }
+
+ @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) {
+ StartupCommand firstCmd = startup[0];
+ if (!(firstCmd instanceof StartupRoutingCommand)) {
+ return null;
+ }
+
+ StartupRoutingCommand ssCmd = ((StartupRoutingCommand) firstCmd);
+ if (ssCmd.getHypervisorType() != HypervisorType.BareMetal) {
+ return null;
+ }
+
+ return _resourceMgr.fillRoutingHostVO(host, ssCmd, HypervisorType.BareMetal, details, hostTags);
+ }
+
+ @Override
+ public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
+ if (host.getType() != Host.Type.Routing || host.getHypervisorType() != HypervisorType.BareMetal) {
+ return null;
+ }
+
+ List<VMInstanceVO> deadVms = _vmDao.listByLastHostId(host.getId());
+ for (VMInstanceVO vm : deadVms) {
+ if (vm.getState() == State.Running || vm.getHostId() != null) {
+ throw new CloudRuntimeException("VM " + vm.getId() + "is still running on host " + host.getId());
+ }
+ _vmDao.remove(vm.getId());
+ }
+
+ return new DeleteHostAnswer(true);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalGuru.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalGuru.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalGuru.java
new file mode 100755
index 0000000..b8a0af3
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalGuru.java
@@ -0,0 +1,87 @@
+// 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.manager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ejb.Local;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorGuru;
+import com.cloud.hypervisor.HypervisorGuruBase;
+import com.cloud.storage.GuestOSVO;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.utils.component.Inject;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.VMInstanceDao;
+
+@Local(value=HypervisorGuru.class)
+public class BareMetalGuru extends HypervisorGuruBase implements HypervisorGuru {
+ private static final Logger s_logger = Logger.getLogger(BareMetalGuru.class);
+ @Inject GuestOSDao _guestOsDao;
+ @Inject HostDao _hostDao;
+ @Inject VMInstanceDao _vmDao;
+
+ protected BareMetalGuru() {
+ super();
+ }
+
+ @Override
+ public HypervisorType getHypervisorType() {
+ return HypervisorType.BareMetal;
+ }
+
+ @Override
+ public <T extends VirtualMachine> VirtualMachineTO implement(VirtualMachineProfile<T> vm) {
+ VirtualMachineTO to = toVirtualMachineTO(vm);
+
+ VMInstanceVO vo = _vmDao.findById(vm.getId());
+ if (vo.getLastHostId() == null) {
+ to.setBootArgs(BaremetalManager.DO_PXE);
+ }
+
+ Map<String, String> details = new HashMap<String, String>();
+ details.put("template", vm.getTemplate().getUrl());
+ to.setDetails(details);
+
+ // Determine the VM's OS description
+ GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId());
+ to.setOs(guestOS.getDisplayName());
+
+ return to;
+ }
+
+ @Override
+ public boolean trackVmHostChange() {
+ return false;
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java
new file mode 100755
index 0000000..15e63b9
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BareMetalTemplateAdapter.java
@@ -0,0 +1,217 @@
+// 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.manager;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.ejb.Local;
+
+import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
+import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd;
+import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
+import org.apache.log4j.Logger;
+
+import com.cloud.configuration.Resource.ResourceType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventVO;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VMTemplateZoneVO;
+import com.cloud.template.TemplateAdapter;
+import com.cloud.template.TemplateAdapterBase;
+import com.cloud.template.TemplateProfile;
+import com.cloud.user.Account;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+@Local(value=TemplateAdapter.class)
+public class BareMetalTemplateAdapter extends TemplateAdapterBase implements TemplateAdapter {
+ private final static Logger s_logger = Logger.getLogger(BareMetalTemplateAdapter.class);
+ @Inject HostDao _hostDao;
+ @Inject ResourceManager _resourceMgr;
+
+ @Override
+ public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException {
+ TemplateProfile profile = super.prepare(cmd);
+
+ if (profile.getZoneId() == null || profile.getZoneId() == -1) {
+ List<DataCenterVO> dcs = _dcDao.listAllIncludingRemoved();
+ for (DataCenterVO dc : dcs) {
+ List<HostVO> pxeServers = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.BaremetalPxe, dc.getId());
+ if (pxeServers.size() == 0) {
+ throw new CloudRuntimeException("Please add PXE server before adding baremetal template in zone " + dc.getName());
+ }
+ }
+ } else {
+ List<HostVO> pxeServers = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.BaremetalPxe, profile.getZoneId());
+ if (pxeServers.size() == 0) {
+ throw new CloudRuntimeException("Please add PXE server before adding baremetal template in zone " + profile.getZoneId());
+ }
+ }
+
+ return profile;
+ }
+
+ @Override
+ public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException {
+ throw new CloudRuntimeException("Baremetal doesn't support ISO template");
+ }
+
+ private void templateCreateUsage(VMTemplateVO template, HostVO host) {
+ if (template.getAccountId() != Account.ACCOUNT_ID_SYSTEM) {
+ UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, template.getAccountId(), host.getDataCenterId(),
+ template.getId(), template.getName(), null, template.getSourceTemplateId(), 0L);
+ _usageEventDao.persist(usageEvent);
+ }
+ }
+
+ @Override
+ public VMTemplateVO create(TemplateProfile profile) {
+ VMTemplateVO template = persistTemplate(profile);
+ Long zoneId = profile.getZoneId();
+
+ /* There is no secondary storage vm for baremetal, we use pxe server id.
+ * Tempalte is not bound to pxeserver right now, and we assume the pxeserver
+ * cannot be removed once it was added. so we use host id of first found pxe
+ * server as reference in template_host_ref.
+ * This maybe a FIXME in future.
+ */
+ VMTemplateHostVO vmTemplateHost = null;
+ if (zoneId == null || zoneId == -1) {
+ List<DataCenterVO> dcs = _dcDao.listAllIncludingRemoved();
+ for (DataCenterVO dc : dcs) {
+ HostVO pxe = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.BaremetalPxe, dc.getId()).get(0);
+
+ vmTemplateHost = _tmpltHostDao.findByHostTemplate(dc.getId(), template.getId());
+ if (vmTemplateHost == null) {
+ vmTemplateHost = new VMTemplateHostVO(pxe.getId(), template.getId(), new Date(), 100,
+ Status.DOWNLOADED, null, null, null, null, template.getUrl());
+ _tmpltHostDao.persist(vmTemplateHost);
+ templateCreateUsage(template, pxe);
+ }
+ }
+ } else {
+ HostVO pxe = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.BaremetalPxe, zoneId).get(0);
+ vmTemplateHost = new VMTemplateHostVO(pxe.getId(), template.getId(), new Date(), 100,
+ Status.DOWNLOADED, null, null, null, null, template.getUrl());
+ _tmpltHostDao.persist(vmTemplateHost);
+ templateCreateUsage(template, pxe);
+ }
+
+ _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template);
+ return template;
+ }
+
+ public TemplateProfile prepareDelete(DeleteIsoCmd cmd) {
+ throw new CloudRuntimeException("Baremetal doesn't support ISO, how the delete get here???");
+ }
+
+ @Override @DB
+ public boolean delete(TemplateProfile profile) {
+ VMTemplateVO template = profile.getTemplate();
+ Long templateId = template.getId();
+ boolean success = true;
+ String zoneName;
+ boolean isAllZone;
+
+ if (!template.isCrossZones() && profile.getZoneId() != null) {
+ isAllZone = false;
+ zoneName = profile.getZoneId().toString();
+ } else {
+ zoneName = "all zones";
+ isAllZone = true;
+ }
+
+ s_logger.debug("Attempting to mark template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName);
+ Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId());
+ String eventType = EventTypes.EVENT_TEMPLATE_DELETE;
+ List<VMTemplateHostVO> templateHostVOs = _tmpltHostDao.listByTemplateId(templateId);
+
+ for (VMTemplateHostVO vo : templateHostVOs) {
+ VMTemplateHostVO lock = null;
+ try {
+ HostVO pxeServer = _hostDao.findById(vo.getHostId());
+ if (!isAllZone && pxeServer.getDataCenterId() != profile.getZoneId()) {
+ continue;
+ }
+
+ lock = _tmpltHostDao.acquireInLockTable(vo.getId());
+ if (lock == null) {
+ s_logger.debug("Failed to acquire lock when deleting templateHostVO with ID: " + vo.getId());
+ success = false;
+ break;
+ }
+
+ vo.setDestroyed(true);
+ _tmpltHostDao.update(vo.getId(), vo);
+ VMTemplateZoneVO templateZone = _tmpltZoneDao.findByZoneTemplate(pxeServer.getDataCenterId(), templateId);
+ if (templateZone != null) {
+ _tmpltZoneDao.remove(templateZone.getId());
+ }
+
+ UsageEventVO usageEvent = new UsageEventVO(eventType, account.getId(), pxeServer.getDataCenterId(), templateId, null);
+ _usageEventDao.persist(usageEvent);
+ } finally {
+ if (lock != null) {
+ _tmpltHostDao.releaseFromLockTable(lock.getId());
+ }
+ }
+ }
+
+ s_logger.debug("Successfully marked template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName);
+
+ // If there are no more non-destroyed template host entries for this template, delete it
+ if (success && (_tmpltHostDao.listByTemplateId(templateId).size() == 0)) {
+ long accountId = template.getAccountId();
+
+ VMTemplateVO lock = _tmpltDao.acquireInLockTable(templateId);
+
+ try {
+ if (lock == null) {
+ s_logger.debug("Failed to acquire lock when deleting template with ID: " + templateId);
+ success = false;
+ } else if (_tmpltDao.remove(templateId)) {
+ // Decrement the number of templates
+ _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
+ }
+
+ } finally {
+ if (lock != null) {
+ _tmpltDao.releaseFromLockTable(lock.getId());
+ }
+ }
+ s_logger.debug("Removed template: " + template.getName() + " because all of its template host refs were marked as destroyed.");
+ }
+
+ return success;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/1f7eaf3d/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManager.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManager.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManager.java
new file mode 100755
index 0000000..1599050
--- /dev/null
+++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/manager/BaremetalManager.java
@@ -0,0 +1,28 @@
+// 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 com.cloud.network.Network.Provider;
+import com.cloud.utils.component.Manager;
+
+public interface BaremetalManager extends Manager {
+ public static final String EchoSecurityGroupAgent = "EchoSecurityGroupAgent";
+ public static final String ExternalBaremetalSystemUrl = "ExternalBaremetalSystemUrl";
+ public static final String DO_PXE = "doPxe";
+}