mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-6278
Baremetal Advanced Networking support
This commit is contained in:
parent
aed36c2776
commit
01dada100a
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,7 +17,6 @@
|
||||
|
||||
build/replace.properties
|
||||
build/build.number
|
||||
bin/
|
||||
.lock-wscript
|
||||
.waf-*
|
||||
waf-*
|
||||
|
||||
@ -230,7 +230,7 @@ public class BaremetalKickStartServiceImpl extends BareMetalPxeServiceBase imple
|
||||
}
|
||||
|
||||
List<String> tuple = parseKickstartUrl(profile);
|
||||
String cmd = String.format("/usr/bin/prepare_pxe.sh %s %s %s %s %s %s", tuple.get(1), tuple.get(2), profile.getTemplate().getUuid(),
|
||||
String cmd = String.format("/opt/cloud/bin/prepare_pxe.sh %s %s %s %s %s %s", tuple.get(1), tuple.get(2), profile.getTemplate().getUuid(),
|
||||
String.format("01-%s", nic.getMacAddress().replaceAll(":", "-")).toLowerCase(), tuple.get(0), nic.getMacAddress().toLowerCase());
|
||||
s_logger.debug(String.format("prepare pxe on virtual router[ip:%s], cmd: %s", mgmtNic.getIp4Address(), cmd));
|
||||
Pair<Boolean, String> ret = SshHelper.sshExecute(mgmtNic.getIp4Address(), 3922, "root", getSystemVMKeyFile(), null, cmd);
|
||||
@ -239,7 +239,7 @@ public class BaremetalKickStartServiceImpl extends BareMetalPxeServiceBase imple
|
||||
}
|
||||
|
||||
//String internalServerIp = "10.223.110.231";
|
||||
cmd = String.format("/usr/bin/baremetal_snat.sh %s %s %s", mgmtNic.getIp4Address(), internalServerIp, mgmtNic.getGateway());
|
||||
cmd = String.format("/opt/cloud/bin/baremetal_snat.sh %s %s %s", mgmtNic.getIp4Address(), internalServerIp, mgmtNic.getGateway());
|
||||
s_logger.debug(String.format("prepare SNAT on virtual router[ip:%s], cmd: %s", mgmtNic.getIp4Address(), cmd));
|
||||
ret = SshHelper.sshExecute(mgmtNic.getIp4Address(), 3922, "root", getSystemVMKeyFile(), null, cmd);
|
||||
if (!ret.first()) {
|
||||
|
||||
@ -42,7 +42,7 @@ then
|
||||
echo 1000000 > /proc/sys/net/nf_conntrack_max
|
||||
fi
|
||||
|
||||
python /usr/bin/baremetal-vr.py &
|
||||
python /opt/cloud/bin/baremetal-vr.py &
|
||||
|
||||
date > /var/cache/cloud/boot_up_done
|
||||
logger -t cloud "Boot up process done"
|
||||
|
||||
145
systemvm/patches/debian/config/opt/cloud/bin/baremetal-vr.py
Executable file
145
systemvm/patches/debian/config/opt/cloud/bin/baremetal-vr.py
Executable file
@ -0,0 +1,145 @@
|
||||
__author__ = 'frank'
|
||||
|
||||
import subprocess
|
||||
import urllib
|
||||
import hmac
|
||||
import hashlib
|
||||
import base64
|
||||
import traceback
|
||||
import logging
|
||||
|
||||
from flask import Flask
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
logger = logging.getLogger('baremetal-vr')
|
||||
hdlr = logging.FileHandler('/var/log/baremetal-vr.log')
|
||||
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
|
||||
hdlr.setFormatter(formatter)
|
||||
logger.addHandler(hdlr)
|
||||
logger.setLevel(logging.WARNING)
|
||||
|
||||
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 Exception('\n'.join(err))
|
||||
|
||||
self.return_code = self.process.returncode
|
||||
return self.stdout
|
||||
|
||||
def shell(cmd):
|
||||
return ShellCmd(cmd)()
|
||||
|
||||
|
||||
class Server(object):
|
||||
CMDLINE = '/var/cache/cloud/cmdline'
|
||||
def __init__(self):
|
||||
self.apikey = None
|
||||
self.secretkey = None
|
||||
self.mgmtIp = None
|
||||
self.mgmtPort = None
|
||||
|
||||
def _get_credentials(self):
|
||||
if not self.apikey or not self.secretkey:
|
||||
with open(self.CMDLINE, 'r') as fd:
|
||||
cmdline = fd.read()
|
||||
for p in cmdline.split():
|
||||
if 'baremetalnotificationsecuritykey' in p:
|
||||
self.secretkey = p.split("=")[1]
|
||||
if 'baremetalnotificationapikey' in p:
|
||||
self.apikey = p.split("=")[1]
|
||||
|
||||
if not self.apikey:
|
||||
raise Exception('cannot find baremetalnotificationapikey in %s' % Server.CMDLINE)
|
||||
if not self.secretkey:
|
||||
raise Exception('cannot find baremetalnotificationsecuritykey in %s' % Server.CMDLINE)
|
||||
|
||||
return self.apikey, self.secretkey
|
||||
|
||||
def _get_mgmt_ip(self):
|
||||
if not self.mgmtIp:
|
||||
with open(self.CMDLINE, 'r') as fd:
|
||||
cmdline = fd.read()
|
||||
for p in cmdline.split():
|
||||
if 'host' in p:
|
||||
self.mgmtIp = p.split("=")[1]
|
||||
break
|
||||
|
||||
if not self.mgmtIp:
|
||||
raise Exception('cannot find host in %s' % Server.CMDLINE)
|
||||
|
||||
return self.mgmtIp
|
||||
|
||||
def _get_mgmt_port(self):
|
||||
if not self.mgmtPort:
|
||||
with open(self.CMDLINE, 'r') as fd:
|
||||
cmdline = fd.read()
|
||||
for p in cmdline.split():
|
||||
if 'port' in p:
|
||||
self.mgmtPort = p.split("=")[1]
|
||||
break
|
||||
|
||||
if not self.mgmtIp:
|
||||
raise Exception('cannot find port in %s' % Server.CMDLINE)
|
||||
|
||||
return self.mgmtPort
|
||||
|
||||
def _make_sign(self, mac):
|
||||
apikey, secretkey = self._get_credentials()
|
||||
reqs = {
|
||||
"apiKey": apikey,
|
||||
"command": 'notifyBaremetalProvisionDone',
|
||||
"mac": mac
|
||||
}
|
||||
|
||||
request = zip(reqs.keys(), reqs.values())
|
||||
request.sort(key=lambda x: str.lower(x[0]))
|
||||
hashStr = "&".join(["=".join([str.lower(r[0]), str.lower(urllib.quote_plus(str(r[1]))).replace("+", "%20").replace('=', '%3d')]) for r in request])
|
||||
sig = urllib.quote_plus(base64.encodestring(hmac.new(secretkey, hashStr, hashlib.sha1).digest()).strip())
|
||||
return sig
|
||||
|
||||
def notify_provisioning_done(self, mac):
|
||||
sig = self._make_sign(mac)
|
||||
cmd = 'http://%s:%s/client/api?command=notifyBaremetalProvisionDone&mac=%s&apiKey=%s&signature=%s' % (self._get_mgmt_ip(), self._get_mgmt_port(), mac, self.apikey, sig)
|
||||
shell("curl -X GET '%s'" % cmd)
|
||||
return ''
|
||||
|
||||
server = None
|
||||
|
||||
@app.route('/baremetal/provisiondone/<mac>', methods=['GET'])
|
||||
def notify_provisioning_done(mac):
|
||||
try:
|
||||
return server.notify_provisioning_done(mac)
|
||||
except:
|
||||
logger.warn(traceback.format_exc())
|
||||
return ''
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
global server
|
||||
server = Server()
|
||||
shell("iptables-save | grep -- '-A INPUT -i eth0 -p tcp -m tcp --dport 10086 -j ACCEPT' > /dev/null || iptables -I INPUT -i eth0 -p tcp -m tcp --dport 10086 -j ACCEPT")
|
||||
app.run(host='0.0.0.0', port=10086, debug=True)
|
||||
Loading…
x
Reference in New Issue
Block a user