Repository: cloudstack
Updated Branches:
  refs/heads/master aed36c277 -> 01dada100


    CLOUDSTACK-6278
    Baremetal Advanced Networking support


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/01dada10
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/01dada10
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/01dada10

Branch: refs/heads/master
Commit: 01dada100a34f42520446a64e02bd8eb2cf4e7fe
Parents: aed36c2
Author: Frank Zhang <frank.zh...@citrix.com>
Authored: Mon Oct 6 15:46:36 2014 -0700
Committer: Frank Zhang <frank.zh...@citrix.com>
Committed: Mon Oct 6 16:03:19 2014 -0700

----------------------------------------------------------------------
 .gitignore                                      |   1 -
 .../BaremetalKickStartServiceImpl.java          |   4 +-
 scripts/network/ping/baremetal_snat.sh          |  54 -------
 scripts/network/ping/prepare_pxe.sh             |  77 ----------
 systemvm/patches/debian/config/etc/rc.local     |   2 +-
 .../debian/config/opt/cloud/bin/baremetal-vr.py | 145 +++++++++++++++++++
 .../config/opt/cloud/bin/baremetal_snat.sh      |  54 +++++++
 .../debian/config/opt/cloud/bin/prepare_pxe.sh  |  77 ++++++++++
 8 files changed, 279 insertions(+), 135 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01dada10/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index fdac72e..4ce64ef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,7 +17,6 @@
 
 build/replace.properties
 build/build.number
-bin/
 .lock-wscript
 .waf-*
 waf-*

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01dada10/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java
 
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java
index 16fc460..7f6b0bf 100755
--- 
a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java
+++ 
b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalKickStartServiceImpl.java
@@ -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()) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01dada10/scripts/network/ping/baremetal_snat.sh
----------------------------------------------------------------------
diff --git a/scripts/network/ping/baremetal_snat.sh 
b/scripts/network/ping/baremetal_snat.sh
deleted file mode 100755
index 22e5669..0000000
--- a/scripts/network/ping/baremetal_snat.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/bash
-
-#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.
-
-set +u
-
-mgmt_nic_ip=$1
-internal_server_ip=$2
-gateway_ip=$3
-
-ip route | grep "$internal_server_ip" > /dev/null
-
-if [ $? -ne 0 ]; then
-    ip route add $internal_server_ip via $gateway_ip
-fi
-
-iptables-save | grep -- "-A POSTROUTING -d $internal_server_ip" > /dev/null
-
-if [ $? -ne 0 ]; then
-    iptables -t nat -A POSTROUTING -d $internal_server_ip -j SNAT --to-source 
$mgmt_nic_ip
-fi
-
-
-iptables-save | grep -- "-A INPUT -i eth0 -p udp -m udp --dport 69 -j ACCEPT" 
> /dev/null
-if [ $? -ne 0 ]; then
-    iptables -I INPUT -i eth0 -p udp -m udp --dport 69 -j ACCEPT
-fi
-
-iptables-save | grep -- "-A FORWARD -i eth1 -o eth0 -j ACCEPT" > /dev/null
-if [ $? -ne 0 ]; then
-    iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
-fi
-
-rule="-A FORWARD -d $internal_server_ip/32 -i eth0 -o eth1 -j ACCEPT"
-iptables-save | grep -- "$rule" > /dev/null
-if [ $? -ne 0 ]; then 
-    iptables -I FORWARD -d $internal_server_ip/32 -i eth0 -o eth1 -j ACCEPT
-fi
-

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01dada10/scripts/network/ping/prepare_pxe.sh
----------------------------------------------------------------------
diff --git a/scripts/network/ping/prepare_pxe.sh 
b/scripts/network/ping/prepare_pxe.sh
deleted file mode 100755
index 5bc1a93..0000000
--- a/scripts/network/ping/prepare_pxe.sh
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/bin/sh
-#
-# 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.
-#
-
-set +u
-
-err_exit() {
-    echo $1
-    exit 1
-}
-
-success() {
-    exit 0
-}
-
-TFTP_ROOT='/opt/tftpboot'
-PXELINUX_CFG_DIR='/opt/tftpboot/pxelinux.cfg'
-
-kernel_nfs_path=$1
-kernel_file_name=`basename $kernel_nfs_path`
-initrd_nfs_path=$2
-initrd_file_name=`basename $initrd_nfs_path`
-tmpt_uuid=$3
-pxe_cfg_filename=$4
-ks_file=$5
-
-kernel_path=$tmpt_uuid/$kernel_file_name
-initrd_path=$tmpt_uuid/$initrd_file_name
-
-cat > $PXELINUX_CFG_DIR/$pxe_cfg_filename <<EOF
-DEFAULT default
-PROMPT 1
-TIMEOUT 26
-DISPLAY boot.msg
-LABEL default
-KERNEL $kernel_path
-APPEND ramdisk_size=66000 initrd=$initrd_path ks=$ks_file
-
-EOF
-
-tmpt_dir=$TFTP_ROOT/$tmpt_uuid
-if [ -d $tmpt_dir ]; then
-    success
-fi
-
-mkdir -p $tmpt_dir
-
-mnt_path=/tmp/$(uuid)
-
-mkdir -p $mnt_path
-mount `dirname $kernel_nfs_path` $mnt_path
-cp -f $mnt_path/$kernel_file_name $tmpt_dir/$kernel_file_name
-umount $mnt_path
-
-mount `dirname $initrd_nfs_path` $mnt_path
-cp -f $mnt_path/$initrd_file_name $tmpt_dir/$initrd_file_name
-umount $mnt_path
-
-success
-
-

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01dada10/systemvm/patches/debian/config/etc/rc.local
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/etc/rc.local 
b/systemvm/patches/debian/config/etc/rc.local
index 78fb5de..23e913e 100755
--- a/systemvm/patches/debian/config/etc/rc.local
+++ b/systemvm/patches/debian/config/etc/rc.local
@@ -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"

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01dada10/systemvm/patches/debian/config/opt/cloud/bin/baremetal-vr.py
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/baremetal-vr.py 
b/systemvm/patches/debian/config/opt/cloud/bin/baremetal-vr.py
new file mode 100755
index 0000000..05188d4
--- /dev/null
+++ b/systemvm/patches/debian/config/opt/cloud/bin/baremetal-vr.py
@@ -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)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01dada10/systemvm/patches/debian/config/opt/cloud/bin/baremetal_snat.sh
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/baremetal_snat.sh 
b/systemvm/patches/debian/config/opt/cloud/bin/baremetal_snat.sh
new file mode 100755
index 0000000..22e5669
--- /dev/null
+++ b/systemvm/patches/debian/config/opt/cloud/bin/baremetal_snat.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+#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.
+
+set +u
+
+mgmt_nic_ip=$1
+internal_server_ip=$2
+gateway_ip=$3
+
+ip route | grep "$internal_server_ip" > /dev/null
+
+if [ $? -ne 0 ]; then
+    ip route add $internal_server_ip via $gateway_ip
+fi
+
+iptables-save | grep -- "-A POSTROUTING -d $internal_server_ip" > /dev/null
+
+if [ $? -ne 0 ]; then
+    iptables -t nat -A POSTROUTING -d $internal_server_ip -j SNAT --to-source 
$mgmt_nic_ip
+fi
+
+
+iptables-save | grep -- "-A INPUT -i eth0 -p udp -m udp --dport 69 -j ACCEPT" 
> /dev/null
+if [ $? -ne 0 ]; then
+    iptables -I INPUT -i eth0 -p udp -m udp --dport 69 -j ACCEPT
+fi
+
+iptables-save | grep -- "-A FORWARD -i eth1 -o eth0 -j ACCEPT" > /dev/null
+if [ $? -ne 0 ]; then
+    iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
+fi
+
+rule="-A FORWARD -d $internal_server_ip/32 -i eth0 -o eth1 -j ACCEPT"
+iptables-save | grep -- "$rule" > /dev/null
+if [ $? -ne 0 ]; then 
+    iptables -I FORWARD -d $internal_server_ip/32 -i eth0 -o eth1 -j ACCEPT
+fi
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/01dada10/systemvm/patches/debian/config/opt/cloud/bin/prepare_pxe.sh
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/prepare_pxe.sh 
b/systemvm/patches/debian/config/opt/cloud/bin/prepare_pxe.sh
new file mode 100755
index 0000000..5bc1a93
--- /dev/null
+++ b/systemvm/patches/debian/config/opt/cloud/bin/prepare_pxe.sh
@@ -0,0 +1,77 @@
+#!/bin/sh
+#
+# 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.
+#
+
+set +u
+
+err_exit() {
+    echo $1
+    exit 1
+}
+
+success() {
+    exit 0
+}
+
+TFTP_ROOT='/opt/tftpboot'
+PXELINUX_CFG_DIR='/opt/tftpboot/pxelinux.cfg'
+
+kernel_nfs_path=$1
+kernel_file_name=`basename $kernel_nfs_path`
+initrd_nfs_path=$2
+initrd_file_name=`basename $initrd_nfs_path`
+tmpt_uuid=$3
+pxe_cfg_filename=$4
+ks_file=$5
+
+kernel_path=$tmpt_uuid/$kernel_file_name
+initrd_path=$tmpt_uuid/$initrd_file_name
+
+cat > $PXELINUX_CFG_DIR/$pxe_cfg_filename <<EOF
+DEFAULT default
+PROMPT 1
+TIMEOUT 26
+DISPLAY boot.msg
+LABEL default
+KERNEL $kernel_path
+APPEND ramdisk_size=66000 initrd=$initrd_path ks=$ks_file
+
+EOF
+
+tmpt_dir=$TFTP_ROOT/$tmpt_uuid
+if [ -d $tmpt_dir ]; then
+    success
+fi
+
+mkdir -p $tmpt_dir
+
+mnt_path=/tmp/$(uuid)
+
+mkdir -p $mnt_path
+mount `dirname $kernel_nfs_path` $mnt_path
+cp -f $mnt_path/$kernel_file_name $tmpt_dir/$kernel_file_name
+umount $mnt_path
+
+mount `dirname $initrd_nfs_path` $mnt_path
+cp -f $mnt_path/$initrd_file_name $tmpt_dir/$initrd_file_name
+umount $mnt_path
+
+success
+
+

Reply via email to