Merge "Compile DPDK to use basic cpu features" into stable/colorado
[fuel.git] / deploy / reap.py
index c642a42..69c98d1 100644 (file)
@@ -1,7 +1,8 @@
 #!/usr/bin/python
 ###############################################################################
-# Copyright (c) 2015 Ericsson AB and others.
+# Copyright (c) 2015, 2016 Ericsson AB and others.
 # szilard.cserey@ericsson.com
+# peter.barabas@ericsson.com
 # All rights reserved. This program and the accompanying materials
 # are made available under the terms of the Apache License, Version 2.0
 # which accompanies this distribution, and is available at
@@ -15,6 +16,9 @@ import yaml
 import glob
 import shutil
 import tempfile
+import re
+import netaddr
+import templater
 
 from common import (
     N,
@@ -57,6 +61,8 @@ adapter:
 #       ipmiIp
 #       ipmiUser
 #       ipmiPass
+#     and you *MAY* provide (optional, not added by reap.py):
+#       ipmiPort
 #   - libvirt adapter you need to provide:
 #       libvirtName: <whatever>
 #       libvirtTemplate: [libvirt/vms/controller.xml | libvirt/vms/compute.xml]
@@ -81,10 +87,12 @@ DISKS = {'fuel': '100G',
 
 class Reap(object):
 
-    def __init__(self, dea_file, dha_file, comment):
+    def __init__(self, dea_file, dha_file, comment, base_dea, template):
         self.dea_file = dea_file
         self.dha_file = dha_file
         self.comment = comment
+        self.base_dea = base_dea
+        self.template = template
         self.temp_dir = None
         self.env = None
         self.env_id = None
@@ -246,6 +254,40 @@ class Reap(object):
             if key not in ['ipaddress', 'netmask',
                            'dhcp_pool_start', 'dhcp_pool_end', 'ssh_network']:
                 del fuel['ADMIN_NETWORK'][key]
+
+        ## FIXME(armband): Factor in support for adding public/other interfaces.
+        ## TODO: Following block expects interface name(s) to be lowercase only
+        interfaces_list = exec_cmd('ip -o -4 a | grep -e "e[nt][hopsx].*"')
+        for interface in re.split('\n', interfaces_list):
+            # Sample output line from above cmd:
+            # 3: eth1 inet 10.0.2.10/24 scope global eth1 valid_lft forever ...
+            ifcfg = re.split(r'\s+', interface)
+            ifcfg_name = ifcfg[1]
+            ifcfg_ipaddr = ifcfg[3]
+
+            # Filter out admin interface (device name is not known, match IP)
+            current_network = netaddr.IPNetwork(ifcfg_ipaddr)
+            if str(current_network.ip) == fuel['ADMIN_NETWORK']['ipaddress']:
+                continue
+
+            # Read ifcfg-* network interface config file, write IFCFG_<IFNAME>
+            ifcfg_sec = 'IFCFG_%s' % ifcfg_name.upper()
+            fuel[ifcfg_sec] = {}
+            ifcfg_data = {}
+            ifcfg_f = ('/etc/sysconfig/network-scripts/ifcfg-%s' % ifcfg_name)
+            with open(ifcfg_f) as f:
+                for line in f:
+                    if line.startswith('#'):
+                        continue
+                    (key, val) = line.split('=')
+                    ifcfg_data[key.lower()] = val.rstrip()
+
+            # Keep only needed info (e.g. filter-out type=Ethernet).
+            fuel[ifcfg_sec]['ipaddress'] = ifcfg_data['ipaddr']
+            fuel[ifcfg_sec]['device'] = ifcfg_data['device']
+            fuel[ifcfg_sec]['netmask'] = str(current_network.netmask)
+            fuel[ifcfg_sec]['gateway'] = ifcfg_data['gateway']
+
         self.write_yaml(self.dea_file, {'fuel': fuel})
 
     def reap_network_settings(self):
@@ -291,6 +333,7 @@ class Reap(object):
     def intro(self):
         delete(self.dea_file)
         delete(self.dha_file)
+
         self.temp_dir = tempfile.mkdtemp()
         date = time.strftime('%c')
         self.write(self.dea_file,
@@ -308,10 +351,18 @@ class Reap(object):
         self.download_config('settings')
         self.download_config('network')
 
+    def create_base_dea(self):
+        templater = templater.Templater(self.dea_file,
+                                        self.template,
+                                        self.base_dea)
+        templater.run()
+
     def finale(self):
         log('DEA file is available at %s' % self.dea_file)
         log('DHA file is available at %s (this is just a template)'
             % self.dha_file)
+        if self.base_dea:
+            log('DEA base file is available at %s' % self.base_dea)
         shutil.rmtree(self.temp_dir)
 
     def reap(self):
@@ -321,16 +372,11 @@ class Reap(object):
         self.reap_fuel_settings()
         self.reap_network_settings()
         self.reap_settings()
+        if self.base_dea:
+            self.create_base_dea()
         self.finale()
 
 
-def usage():
-    print '''
-    Usage:
-    python reap.py <dea_file> <dha_file> <comment>
-    '''
-
-
 def parse_arguments():
     parser = ArgParser(prog='python %s' % __file__)
     parser.add_argument('dea_file', nargs='?', action='store',
@@ -340,14 +386,26 @@ def parse_arguments():
                         default='dha.yaml',
                         help='Deployment Hardware Adapter: dha.yaml')
     parser.add_argument('comment', nargs='?', action='store', help='Comment')
+    parser.add_argument('-base_dea',
+                        dest='base_dea',
+                        help='Create specified base DEA file from "dea_file"')
+    parser.add_argument('-template',
+                        dest='template',
+                        nargs='?',
+                        default='base_dea_template.yaml',
+                        help='Base DEA is generated from this template')
     args = parser.parse_args()
-    return (args.dea_file, args.dha_file, args.comment)
+    return (args.dea_file,
+            args.dha_file,
+            args.comment,
+            args.base_dea,
+            args.template)
 
 
 def main():
-    dea_file, dha_file, comment = parse_arguments()
+    dea_file, dha_file, comment, base_dea, template = parse_arguments()
 
-    r = Reap(dea_file, dha_file, comment)
+    r = Reap(dea_file, dha_file, comment, base_dea, template)
     r.reap()