Alessandro Pilotti 10 лет назад
Родитель
Сommit
44a86e258a
5 измененных файлов с 500 добавлено и 499 удалено
  1. 1 0
      .gitattributes
  2. 135 135
      coriolis/osmorphing/base.py
  3. 47 47
      coriolis/osmorphing/debian.py
  4. 212 212
      coriolis/osmorphing/redhat.py
  5. 105 105
      coriolis/osmorphing/suse.py

+ 1 - 0
.gitattributes

@@ -0,0 +1 @@
+* text eol=lf

+ 135 - 135
coriolis/osmorphing/base.py

@@ -1,135 +1,135 @@
-import abc
-import itertools
-import os
-import re
-import uuid
-
-from coriolis import utils
-
-
-class BaseOSMorphingTools(object):
-    __metaclass__ = abc.ABCMeta
-
-    def __init__(self, conn, os_root_dir, hypervisor, platform, event_manager):
-        self._conn = conn
-        self._os_root_dir = os_root_dir
-        self._hypervisor = hypervisor
-        self._platform = platform
-        self._distro = None
-        self._version = None
-        self._event_manager = event_manager
-
-    def check_os(self):
-        if not self._distro:
-            os_info = self._check_os()
-            if os_info:
-                self._distro, self._version = os_info
-        if self._distro:
-            return self._distro, self._version
-
-    @abc.abstractmethod
-    def _check_os(self):
-        pass
-
-    @abc.abstractmethod
-    def set_net_config(self, nics_info, dhcp):
-        pass
-
-    def get_packages(self):
-        return [], []
-
-    def pre_packages_install(self):
-        pass
-
-    def install_packages(self, package_names):
-        pass
-
-    def uninstall_packages(self, package_names):
-        pass
-
-    def post_packages_install(self):
-        pass
-
-
-class BaseLinuxOSMorphingTools(BaseOSMorphingTools):
-    __metaclass__ = abc.ABCMeta
-
-    _packages = {}
-
-    def __init__(self, conn, os_root_dir, hypervisor, platform, event_manager):
-        super(BaseLinuxOSMorphingTools, self).__init__(
-            conn, os_root_dir, hypervisor, platform, event_manager)
-        self._ssh = conn
-
-    def get_packages(self):
-        k_add = [(h, p) for (h, p) in self._packages.keys() if
-                 (h is None or h == self._hypervisor) and
-                 (p is None or p == self._platform)]
-
-        add = [p[0] for p in itertools.chain.from_iterable(
-               [l for k, l in self._packages.items() if k in k_add])]
-
-        k_remove = set(self._packages.keys()) - set(k_add)
-        remove = [p[0] for p in itertools.chain.from_iterable(
-                  [l for k, l in self._packages.items() if k in k_remove])
-                  if p[1]]
-
-        return add, remove
-
-    def _test_path(self, chroot_path):
-        path = os.path.join(self._os_root_dir, chroot_path)
-        return utils.test_ssh_path(self._ssh, path)
-
-    def _read_file(self, chroot_path):
-        path = os.path.join(self._os_root_dir, chroot_path)
-        return utils.read_ssh_file(self._ssh, path)
-
-    def _write_file(self, chroot_path, content):
-        path = os.path.join(self._os_root_dir, chroot_path)
-        utils.write_ssh_file(self._ssh, path, content)
-
-    def _list_dir(self, chroot_path):
-        path = os.path.join(self._os_root_dir, chroot_path)
-        return utils.list_ssh_dir(self._ssh, path)
-
-    def _exec_cmd(self, cmd):
-        return utils.exec_ssh_cmd(self._ssh, cmd)
-
-    def _exec_cmd_chroot(self, cmd):
-        return utils.exec_ssh_cmd_chroot(self._ssh, self._os_root_dir, cmd)
-
-    def _check_user_exists(self, username):
-        try:
-            self._exec_cmd_chroot("id -u %s" % username)
-            return True
-        except:
-            return False
-
-    def _write_file_sudo(self, chroot_path, content):
-        # NOTE: writes the file to a temp location due to permission issues
-        tmp_file = 'tmp/%s' % str(uuid.uuid4())
-        self._write_file(tmp_file, content)
-        self._exec_cmd_chroot("cp /%s /%s" % (tmp_file, chroot_path))
-        self._exec_cmd_chroot("rm /%s" % tmp_file)
-
-    def _enable_systemd_service(self, service_name):
-        self._exec_cmd_chroot("systemctl enable %s.service" % service_name)
-
-    def _get_os_release(self):
-        return self._read_config_file("etc/os-release", check_exists=True)
-
-    def _read_config_file(self, chroot_path, check_exists=False):
-        if not check_exists or self._test_path(chroot_path):
-            content = self._read_file(chroot_path).decode()
-            return self._get_config(content)
-        else:
-            return {}
-
-    def _get_config(self, config_content):
-        config = {}
-        for config_line in config_content.split('\n'):
-            m = re.match('(.*)="?([^"]*)"?', config_line)
-            if m:
-                name, value = m.groups()
-                config[name] = value
-        return config
+import abc
+import itertools
+import os
+import re
+import uuid
+
+from coriolis import utils
+
+
+class BaseOSMorphingTools(object):
+    __metaclass__ = abc.ABCMeta
+
+    def __init__(self, conn, os_root_dir, hypervisor, platform, event_manager):
+        self._conn = conn
+        self._os_root_dir = os_root_dir
+        self._hypervisor = hypervisor
+        self._platform = platform
+        self._distro = None
+        self._version = None
+        self._event_manager = event_manager
+
+    def check_os(self):
+        if not self._distro:
+            os_info = self._check_os()
+            if os_info:
+                self._distro, self._version = os_info
+        if self._distro:
+            return self._distro, self._version
+
+    @abc.abstractmethod
+    def _check_os(self):
+        pass
+
+    @abc.abstractmethod
+    def set_net_config(self, nics_info, dhcp):
+        pass
+
+    def get_packages(self):
+        return [], []
+
+    def pre_packages_install(self):
+        pass
+
+    def install_packages(self, package_names):
+        pass
+
+    def uninstall_packages(self, package_names):
+        pass
+
+    def post_packages_install(self):
+        pass
+
+
+class BaseLinuxOSMorphingTools(BaseOSMorphingTools):
+    __metaclass__ = abc.ABCMeta
+
+    _packages = {}
+
+    def __init__(self, conn, os_root_dir, hypervisor, platform, event_manager):
+        super(BaseLinuxOSMorphingTools, self).__init__(
+            conn, os_root_dir, hypervisor, platform, event_manager)
+        self._ssh = conn
+
+    def get_packages(self):
+        k_add = [(h, p) for (h, p) in self._packages.keys() if
+                 (h is None or h == self._hypervisor) and
+                 (p is None or p == self._platform)]
+
+        add = [p[0] for p in itertools.chain.from_iterable(
+               [l for k, l in self._packages.items() if k in k_add])]
+
+        k_remove = set(self._packages.keys()) - set(k_add)
+        remove = [p[0] for p in itertools.chain.from_iterable(
+                  [l for k, l in self._packages.items() if k in k_remove])
+                  if p[1]]
+
+        return add, remove
+
+    def _test_path(self, chroot_path):
+        path = os.path.join(self._os_root_dir, chroot_path)
+        return utils.test_ssh_path(self._ssh, path)
+
+    def _read_file(self, chroot_path):
+        path = os.path.join(self._os_root_dir, chroot_path)
+        return utils.read_ssh_file(self._ssh, path)
+
+    def _write_file(self, chroot_path, content):
+        path = os.path.join(self._os_root_dir, chroot_path)
+        utils.write_ssh_file(self._ssh, path, content)
+
+    def _list_dir(self, chroot_path):
+        path = os.path.join(self._os_root_dir, chroot_path)
+        return utils.list_ssh_dir(self._ssh, path)
+
+    def _exec_cmd(self, cmd):
+        return utils.exec_ssh_cmd(self._ssh, cmd)
+
+    def _exec_cmd_chroot(self, cmd):
+        return utils.exec_ssh_cmd_chroot(self._ssh, self._os_root_dir, cmd)
+
+    def _check_user_exists(self, username):
+        try:
+            self._exec_cmd_chroot("id -u %s" % username)
+            return True
+        except:
+            return False
+
+    def _write_file_sudo(self, chroot_path, content):
+        # NOTE: writes the file to a temp location due to permission issues
+        tmp_file = 'tmp/%s' % str(uuid.uuid4())
+        self._write_file(tmp_file, content)
+        self._exec_cmd_chroot("cp /%s /%s" % (tmp_file, chroot_path))
+        self._exec_cmd_chroot("rm /%s" % tmp_file)
+
+    def _enable_systemd_service(self, service_name):
+        self._exec_cmd_chroot("systemctl enable %s.service" % service_name)
+
+    def _get_os_release(self):
+        return self._read_config_file("etc/os-release", check_exists=True)
+
+    def _read_config_file(self, chroot_path, check_exists=False):
+        if not check_exists or self._test_path(chroot_path):
+            content = self._read_file(chroot_path).decode()
+            return self._get_config(content)
+        else:
+            return {}
+
+    def _get_config(self, config_content):
+        config = {}
+        for config_line in config_content.split('\n'):
+            m = re.match('(.*)="?([^"]*)"?', config_line)
+            if m:
+                name, value = m.groups()
+                config[name] = value
+        return config

+ 47 - 47
coriolis/osmorphing/debian.py

@@ -1,47 +1,47 @@
-import os
-
-from coriolis import constants
-from coriolis.osmorphing import base
-
-
-class DebianMorphingTools(base.BaseLinuxOSMorphingTools):
-    _packages = {
-        (constants.HYPERVISOR_VMWARE, None): [("open-vm-tools", True)],
-        # TODO: add cloud-initramfs-growroot
-        (None, constants.PLATFORM_OPENSTACK): [("cloud-init", True)],
-    }
-
-    def _check_os(self):
-        lsb_release_path = "etc/lsb-release"
-        debian_version_path = "etc/debian_version"
-        if self._test_path(lsb_release_path):
-            config = self._read_config_file("etc/lsb-release")
-            dist_id = config.get('DISTRIB_ID')
-            if dist_id == 'Debian':
-                release = config.get('DISTRIB_RELEASE')
-                return (dist_id, release)
-        elif self._test_path(debian_version_path):
-            release = self._read_file(
-                debian_version_path).decode().split('\n')[0]
-            return ('Debian', release)
-
-    def set_net_config(self, nics_info, dhcp):
-        if dhcp:
-            # NOTE: doesn't work with chroot
-            interfaces_path = os.path.join(
-                self._os_root_dir, "etc/network/interfaces")
-            self._exec_cmd('sudo sed -i.bak "s/static/dhcp/g" %s' %
-                           interfaces_path)
-
-    def pre_packages_install(self):
-        apt_get_cmd = 'apt-get update -y'
-        self._exec_cmd_chroot(apt_get_cmd)
-
-    def install_packages(self, package_names):
-        apt_get_cmd = 'apt-get install %s -y' % " ".join(package_names)
-        self._exec_cmd_chroot(apt_get_cmd)
-
-    def uninstall_packages(self, package_names):
-        for package_name in package_names:
-            apt_get_cmd = 'apt-get remove %s -y || true' % package_name
-            self._exec_cmd_chroot(apt_get_cmd)
+import os
+
+from coriolis import constants
+from coriolis.osmorphing import base
+
+
+class DebianMorphingTools(base.BaseLinuxOSMorphingTools):
+    _packages = {
+        (constants.HYPERVISOR_VMWARE, None): [("open-vm-tools", True)],
+        # TODO: add cloud-initramfs-growroot
+        (None, constants.PLATFORM_OPENSTACK): [("cloud-init", True)],
+    }
+
+    def _check_os(self):
+        lsb_release_path = "etc/lsb-release"
+        debian_version_path = "etc/debian_version"
+        if self._test_path(lsb_release_path):
+            config = self._read_config_file("etc/lsb-release")
+            dist_id = config.get('DISTRIB_ID')
+            if dist_id == 'Debian':
+                release = config.get('DISTRIB_RELEASE')
+                return (dist_id, release)
+        elif self._test_path(debian_version_path):
+            release = self._read_file(
+                debian_version_path).decode().split('\n')[0]
+            return ('Debian', release)
+
+    def set_net_config(self, nics_info, dhcp):
+        if dhcp:
+            # NOTE: doesn't work with chroot
+            interfaces_path = os.path.join(
+                self._os_root_dir, "etc/network/interfaces")
+            self._exec_cmd('sudo sed -i.bak "s/static/dhcp/g" %s' %
+                           interfaces_path)
+
+    def pre_packages_install(self):
+        apt_get_cmd = 'apt-get update -y'
+        self._exec_cmd_chroot(apt_get_cmd)
+
+    def install_packages(self, package_names):
+        apt_get_cmd = 'apt-get install %s -y' % " ".join(package_names)
+        self._exec_cmd_chroot(apt_get_cmd)
+
+    def uninstall_packages(self, package_names):
+        for package_name in package_names:
+            apt_get_cmd = 'apt-get remove %s -y || true' % package_name
+            self._exec_cmd_chroot(apt_get_cmd)

+ 212 - 212
coriolis/osmorphing/redhat.py

@@ -1,212 +1,212 @@
-import os
-import re
-import uuid
-
-from oslo_log import log as logging
-import yaml
-
-from coriolis import constants
-from coriolis import exception
-from coriolis.osmorphing import base
-from coriolis import utils
-
-LOG = logging.getLogger(__name__)
-
-RELEASE_RHEL = "Red Hat Enterprise Linux Server"
-RELEASE_CENTOS = "CentOS Linux"
-RELEASE_FEDORA = "Fedora"
-
-DEFAULT_CLOUD_USER = "cloud-user"
-
-
-class RedHatMorphingTools(base.BaseLinuxOSMorphingTools):
-    _packages = {
-        (None, None): [("dracut-config-generic", False)],
-        (constants.HYPERVISOR_VMWARE, None): [("open-vm-tools", True)],
-        (constants.HYPERVISOR_HYPERV, None): [("hyperv-daemons", True)],
-        (None, constants.PLATFORM_OPENSTACK): [
-            ("cloud-init", True),
-            ("cloud-utils", False),
-            ("parted", False),
-            ("git", False),
-            ("cloud-utils-growpart", False)],
-    }
-    _NETWORK_SCRIPTS_PATH = "etc/sysconfig/network-scripts"
-
-    def _check_os(self):
-        redhat_release_path = "etc/redhat-release"
-        if self._test_path(redhat_release_path):
-            release_info = self._read_file(
-                redhat_release_path).decode().split('\n')[0].strip()
-            m = re.match(r"^(.*) release ([0-9].*) \((.*)\).*$", release_info)
-            if m:
-                distro, version, codename = m.groups()
-                return (distro, version)
-
-    def _get_net_ifaces_info(self, ifcfgs_ethernet, mac_addresses):
-        net_ifaces_info = []
-
-        for ifcfg_file, ifcfg in ifcfgs_ethernet:
-            mac_address = ifcfg.get("HWADDR")
-            if not mac_address:
-                if len(ifcfgs_ethernet) == 1 and len(mac_addresses) == 1:
-                    mac_address = mac_addresses[0]
-                    LOG.info("HWADDR not defined in: %s, using migration "
-                             "configuration mac_address: %s",
-                             ifcfg_file, mac_address)
-            if not mac_address:
-                self._event_manager.warn(
-                    "HWADDR not defined, skipping: %s" % ifcfg_file)
-                continue
-            name = ifcfg.get("NAME")
-            if not name:
-                # Get the name from the config file
-                name = re.match("^.*/ifcfg-(.*)", ifcfg_file).groups()[0]
-            net_ifaces_info.append((name, mac_address))
-        return net_ifaces_info
-
-    def _add_net_udev_rules(self, net_ifaces_info):
-        udev_file = "etc/udev/rules.d/70-persistent-net.rules"
-        if not self._test_path(udev_file):
-            if net_ifaces_info:
-                content = utils.get_udev_net_rules(net_ifaces_info)
-                self._write_file_sudo(udev_file, content)
-
-    def _has_systemd(self):
-        try:
-            self._exec_cmd_chroot("rpm -q systemd")
-            return True
-        except:
-            return False
-
-    def _set_dhcp_net_config(self, ifcfgs_ethernet):
-        for ifcfg_file, ifcfg in ifcfgs_ethernet:
-            if ifcfg.get("BOOTPROTO") == "none":
-                ifcfg["BOOTPROTO"] = "dhcp"
-                ifcfg["UUID"] = str(uuid.uuid4())
-
-                if 'IPADDR' in ifcfg:
-                    del ifcfg['IPADDR']
-                if 'GATEWAY' in ifcfg:
-                    del ifcfg['GATEWAY']
-                if 'NETMASK' in ifcfg:
-                    del ifcfg['NETMASK']
-                if 'NETWORK' in ifcfg:
-                    del ifcfg['NETWORK']
-
-                self._write_config_file(ifcfg_file, ifcfg)
-
-        network_cfg_file = "etc/sysconfig/network"
-        network_cfg = self._read_config_file(network_cfg_file,
-                                             check_exists=True)
-        if "GATEWAY" in network_cfg:
-            del network_cfg["GATEWAY"]
-            self._write_config_file(network_cfg_file, network_cfg)
-
-    def _get_ifcfgs_by_type(self, ifcfg_type):
-        ifcfgs = []
-        for ifcfg_file in self._get_net_config_files():
-            ifcfg = self._read_config_file(ifcfg_file)
-            if ifcfg.get("TYPE") == ifcfg_type:
-                ifcfgs.append((ifcfg_file, ifcfg))
-        return ifcfgs
-
-    def set_net_config(self, nics_info, dhcp):
-        ifcfgs_ethernet = self._get_ifcfgs_by_type("Ethernet")
-
-        if dhcp:
-            self._set_dhcp_net_config(ifcfgs_ethernet)
-
-        mac_addresses = [ni.get("mac_address") for ni in nics_info]
-        net_ifaces_info = self._get_net_ifaces_info(ifcfgs_ethernet,
-                                                    mac_addresses)
-        self._add_net_udev_rules(net_ifaces_info)
-
-    def install_packages(self, package_names):
-        yum_cmd = 'yum install %s -y' % " ".join(package_names)
-        self._exec_cmd_chroot(yum_cmd)
-
-    def uninstall_packages(self, package_names):
-        for package_name in package_names:
-            yum_cmd = 'yum remove %s -y' % package_name
-            self._exec_cmd_chroot(yum_cmd)
-
-    def _run_dracut(self):
-        package_names = self._exec_cmd_chroot(
-            'rpm -q kernel').decode().split('\n')[:-1]
-        for package_name in package_names:
-            m = re.match('^kernel-(.*)$', package_name)
-            if m:
-                kernel_version = m.groups()[0]
-                self._event_manager.progress_update(
-                    "Generating initrd for kernel: %s" % kernel_version)
-                self._exec_cmd_chroot(
-                    "dracut -f /boot/initramfs-%(version)s.img %(version)s" %
-                    {"version": kernel_version})
-
-    def _get_default_cloud_user(self):
-        cloud_cfg_path = os.path.join(self._os_root_dir, 'etc/cloud/cloud.cfg')
-        if not self._test_path(cloud_cfg_path):
-            raise exception.CoriolisException(
-                "cloud-init config file not found: %s" % cloud_cfg_path)
-        cloud_cfg_content = self._read_file(cloud_cfg_path)
-        cloud_cfg = yaml.load(cloud_cfg_content)
-        return cloud_cfg.get('system_info', {}).get('default_user', {}).get(
-            'name', DEFAULT_CLOUD_USER)
-
-    def _set_network_nozeroconf_config(self):
-        network_cfg_file = "etc/sysconfig/network"
-        network_cfg = self._read_config_file(network_cfg_file,
-                                             check_exists=True)
-        network_cfg["NOZEROCONF"] = "yes"
-        self._write_config_file(network_cfg_file, network_cfg)
-
-    def _configure_cloud_init(self):
-        if "cloud-init" in self.get_packages()[0]:
-            cloud_user = self._get_default_cloud_user()
-            if not self._check_user_exists(cloud_user):
-                self._exec_cmd_chroot("useradd %s" % cloud_user)
-            self._set_network_nozeroconf_config()
-            if self._has_systemd():
-                self._enable_systemd_service("cloud-init")
-
-    def _add_hyperv_ballooning_udev_rules(self):
-        udev_file = "etc/udev/rules.d/100-balloon.rules"
-        content = 'SUBSYSTEM=="memory", ACTION=="add", ATTR{state}="online"\n'
-
-        if (self._hypervisor == constants.HYPERVISOR_HYPERV and
-                not self._test_path(udev_file)):
-            self._write_file_sudo(udev_file, content)
-
-    def _write_config_file(self, chroot_path, config_data):
-        content = self._get_config_file_content(config_data)
-        self._write_file_sudo(chroot_path, content)
-
-    def _get_config_file_content(self, config):
-        return "%s\n" % "\n".join(
-            ['%s="%s"' % (k, v) for k, v in config.items()])
-
-    def _get_net_config_files(self):
-        dir_content = self._list_dir(self._NETWORK_SCRIPTS_PATH)
-        return [os.path.join(self._NETWORK_SCRIPTS_PATH, f) for f in
-                dir_content if re.match("^ifcfg-(.*)", f)]
-
-    def _set_selinux_autorelabel(self):
-        self._exec_cmd_chroot("touch /.autorelabel")
-
-    def pre_packages_install(self):
-        distro, version = self.check_os()
-        if distro == RELEASE_RHEL and "cloud-init" in self.get_packages()[0]:
-            major_version = version.split(".")[0]
-            repo_name = "rhel-%s-server-rh-common-rpms" % major_version
-            # This is necessary for cloud-init
-            self._event_manager.progress_update(
-                "Enabling repository: %s" % repo_name)
-            self._exec_cmd_chroot(
-                "subscription-manager repos --enable %s" % repo_name)
-
-    def post_packages_install(self):
-        self._add_hyperv_ballooning_udev_rules()
-        self._run_dracut()
-        self._configure_cloud_init()
-        self._set_selinux_autorelabel()
+import os
+import re
+import uuid
+
+from oslo_log import log as logging
+import yaml
+
+from coriolis import constants
+from coriolis import exception
+from coriolis.osmorphing import base
+from coriolis import utils
+
+LOG = logging.getLogger(__name__)
+
+RELEASE_RHEL = "Red Hat Enterprise Linux Server"
+RELEASE_CENTOS = "CentOS Linux"
+RELEASE_FEDORA = "Fedora"
+
+DEFAULT_CLOUD_USER = "cloud-user"
+
+
+class RedHatMorphingTools(base.BaseLinuxOSMorphingTools):
+    _packages = {
+        (None, None): [("dracut-config-generic", False)],
+        (constants.HYPERVISOR_VMWARE, None): [("open-vm-tools", True)],
+        (constants.HYPERVISOR_HYPERV, None): [("hyperv-daemons", True)],
+        (None, constants.PLATFORM_OPENSTACK): [
+            ("cloud-init", True),
+            ("cloud-utils", False),
+            ("parted", False),
+            ("git", False),
+            ("cloud-utils-growpart", False)],
+    }
+    _NETWORK_SCRIPTS_PATH = "etc/sysconfig/network-scripts"
+
+    def _check_os(self):
+        redhat_release_path = "etc/redhat-release"
+        if self._test_path(redhat_release_path):
+            release_info = self._read_file(
+                redhat_release_path).decode().split('\n')[0].strip()
+            m = re.match(r"^(.*) release ([0-9].*) \((.*)\).*$", release_info)
+            if m:
+                distro, version, codename = m.groups()
+                return (distro, version)
+
+    def _get_net_ifaces_info(self, ifcfgs_ethernet, mac_addresses):
+        net_ifaces_info = []
+
+        for ifcfg_file, ifcfg in ifcfgs_ethernet:
+            mac_address = ifcfg.get("HWADDR")
+            if not mac_address:
+                if len(ifcfgs_ethernet) == 1 and len(mac_addresses) == 1:
+                    mac_address = mac_addresses[0]
+                    LOG.info("HWADDR not defined in: %s, using migration "
+                             "configuration mac_address: %s",
+                             ifcfg_file, mac_address)
+            if not mac_address:
+                self._event_manager.warn(
+                    "HWADDR not defined, skipping: %s" % ifcfg_file)
+                continue
+            name = ifcfg.get("NAME")
+            if not name:
+                # Get the name from the config file
+                name = re.match("^.*/ifcfg-(.*)", ifcfg_file).groups()[0]
+            net_ifaces_info.append((name, mac_address))
+        return net_ifaces_info
+
+    def _add_net_udev_rules(self, net_ifaces_info):
+        udev_file = "etc/udev/rules.d/70-persistent-net.rules"
+        if not self._test_path(udev_file):
+            if net_ifaces_info:
+                content = utils.get_udev_net_rules(net_ifaces_info)
+                self._write_file_sudo(udev_file, content)
+
+    def _has_systemd(self):
+        try:
+            self._exec_cmd_chroot("rpm -q systemd")
+            return True
+        except:
+            return False
+
+    def _set_dhcp_net_config(self, ifcfgs_ethernet):
+        for ifcfg_file, ifcfg in ifcfgs_ethernet:
+            if ifcfg.get("BOOTPROTO") == "none":
+                ifcfg["BOOTPROTO"] = "dhcp"
+                ifcfg["UUID"] = str(uuid.uuid4())
+
+                if 'IPADDR' in ifcfg:
+                    del ifcfg['IPADDR']
+                if 'GATEWAY' in ifcfg:
+                    del ifcfg['GATEWAY']
+                if 'NETMASK' in ifcfg:
+                    del ifcfg['NETMASK']
+                if 'NETWORK' in ifcfg:
+                    del ifcfg['NETWORK']
+
+                self._write_config_file(ifcfg_file, ifcfg)
+
+        network_cfg_file = "etc/sysconfig/network"
+        network_cfg = self._read_config_file(network_cfg_file,
+                                             check_exists=True)
+        if "GATEWAY" in network_cfg:
+            del network_cfg["GATEWAY"]
+            self._write_config_file(network_cfg_file, network_cfg)
+
+    def _get_ifcfgs_by_type(self, ifcfg_type):
+        ifcfgs = []
+        for ifcfg_file in self._get_net_config_files():
+            ifcfg = self._read_config_file(ifcfg_file)
+            if ifcfg.get("TYPE") == ifcfg_type:
+                ifcfgs.append((ifcfg_file, ifcfg))
+        return ifcfgs
+
+    def set_net_config(self, nics_info, dhcp):
+        ifcfgs_ethernet = self._get_ifcfgs_by_type("Ethernet")
+
+        if dhcp:
+            self._set_dhcp_net_config(ifcfgs_ethernet)
+
+        mac_addresses = [ni.get("mac_address") for ni in nics_info]
+        net_ifaces_info = self._get_net_ifaces_info(ifcfgs_ethernet,
+                                                    mac_addresses)
+        self._add_net_udev_rules(net_ifaces_info)
+
+    def install_packages(self, package_names):
+        yum_cmd = 'yum install %s -y' % " ".join(package_names)
+        self._exec_cmd_chroot(yum_cmd)
+
+    def uninstall_packages(self, package_names):
+        for package_name in package_names:
+            yum_cmd = 'yum remove %s -y' % package_name
+            self._exec_cmd_chroot(yum_cmd)
+
+    def _run_dracut(self):
+        package_names = self._exec_cmd_chroot(
+            'rpm -q kernel').decode().split('\n')[:-1]
+        for package_name in package_names:
+            m = re.match('^kernel-(.*)$', package_name)
+            if m:
+                kernel_version = m.groups()[0]
+                self._event_manager.progress_update(
+                    "Generating initrd for kernel: %s" % kernel_version)
+                self._exec_cmd_chroot(
+                    "dracut -f /boot/initramfs-%(version)s.img %(version)s" %
+                    {"version": kernel_version})
+
+    def _get_default_cloud_user(self):
+        cloud_cfg_path = os.path.join(self._os_root_dir, 'etc/cloud/cloud.cfg')
+        if not self._test_path(cloud_cfg_path):
+            raise exception.CoriolisException(
+                "cloud-init config file not found: %s" % cloud_cfg_path)
+        cloud_cfg_content = self._read_file(cloud_cfg_path)
+        cloud_cfg = yaml.load(cloud_cfg_content)
+        return cloud_cfg.get('system_info', {}).get('default_user', {}).get(
+            'name', DEFAULT_CLOUD_USER)
+
+    def _set_network_nozeroconf_config(self):
+        network_cfg_file = "etc/sysconfig/network"
+        network_cfg = self._read_config_file(network_cfg_file,
+                                             check_exists=True)
+        network_cfg["NOZEROCONF"] = "yes"
+        self._write_config_file(network_cfg_file, network_cfg)
+
+    def _configure_cloud_init(self):
+        if "cloud-init" in self.get_packages()[0]:
+            cloud_user = self._get_default_cloud_user()
+            if not self._check_user_exists(cloud_user):
+                self._exec_cmd_chroot("useradd %s" % cloud_user)
+            self._set_network_nozeroconf_config()
+            if self._has_systemd():
+                self._enable_systemd_service("cloud-init")
+
+    def _add_hyperv_ballooning_udev_rules(self):
+        udev_file = "etc/udev/rules.d/100-balloon.rules"
+        content = 'SUBSYSTEM=="memory", ACTION=="add", ATTR{state}="online"\n'
+
+        if (self._hypervisor == constants.HYPERVISOR_HYPERV and
+                not self._test_path(udev_file)):
+            self._write_file_sudo(udev_file, content)
+
+    def _write_config_file(self, chroot_path, config_data):
+        content = self._get_config_file_content(config_data)
+        self._write_file_sudo(chroot_path, content)
+
+    def _get_config_file_content(self, config):
+        return "%s\n" % "\n".join(
+            ['%s="%s"' % (k, v) for k, v in config.items()])
+
+    def _get_net_config_files(self):
+        dir_content = self._list_dir(self._NETWORK_SCRIPTS_PATH)
+        return [os.path.join(self._NETWORK_SCRIPTS_PATH, f) for f in
+                dir_content if re.match("^ifcfg-(.*)", f)]
+
+    def _set_selinux_autorelabel(self):
+        self._exec_cmd_chroot("touch /.autorelabel")
+
+    def pre_packages_install(self):
+        distro, version = self.check_os()
+        if distro == RELEASE_RHEL and "cloud-init" in self.get_packages()[0]:
+            major_version = version.split(".")[0]
+            repo_name = "rhel-%s-server-rh-common-rpms" % major_version
+            # This is necessary for cloud-init
+            self._event_manager.progress_update(
+                "Enabling repository: %s" % repo_name)
+            self._exec_cmd_chroot(
+                "subscription-manager repos --enable %s" % repo_name)
+
+    def post_packages_install(self):
+        self._add_hyperv_ballooning_udev_rules()
+        self._run_dracut()
+        self._configure_cloud_init()
+        self._set_selinux_autorelabel()

+ 105 - 105
coriolis/osmorphing/suse.py

@@ -1,105 +1,105 @@
-import os
-import re
-
-from coriolis import constants
-from coriolis.osmorphing import base
-
-
-class SUSEMorphingTools(base.BaseLinuxOSMorphingTools):
-    _packages = {
-        (constants.HYPERVISOR_VMWARE, None): [("open-vm-tools", True)],
-        (None, constants.PLATFORM_OPENSTACK): [("cloud-init", True)],
-    }
-
-    def _check_os(self):
-        os_release = self._get_os_release()
-        name = os_release.get("NAME")
-        if name == "SLES" or name.startswith("openSUSE"):
-            pretty_name = os_release.get("PRETTY_NAME")
-            if name == "openSUSE Tumbleweed":
-                self._version_id = None
-            else:
-                self._version_id = os_release.get("VERSION_ID")
-            return (name, pretty_name)
-
-        suse_release_path = "etc/SuSE-release"
-        if self._test_path(suse_release_path):
-            out = self._read_file(suse_release_path).decode()
-            release = out.split('\n')[0]
-            version_id = re.findall('^VERSION = (.*)$', out, re.MULTILINE)[0]
-            patch_level = re.findall('^PATCHLEVEL = (.*)$', out, re.MULTILINE)
-            if patch_level:
-                version_id = "%s.%s" % (version_id, patch_level[1])
-            self._version_id = version_id
-            return ('SUSE', release)
-
-    def set_net_config(self, nics_info, dhcp):
-        # TODO: add networking support
-        pass
-
-    def _copy_resolv_conf(self):
-        resolv_conf_path = os.path.join(self._os_root_dir, "etc/resolv.conf")
-        self._exec_cmd("sudo cp -f /etc/resolv.conf %s" % resolv_conf_path)
-
-    def pre_packages_install(self):
-        self._copy_resolv_conf()
-
-        if self._platform == constants.PLATFORM_OPENSTACK:
-            # TODO: use OS version to choose the right repo
-            repo_version_map = {("SLES", "11.4"): "SLE_11_SP4",
-                                ("SLES", "11.3"): "SLE_11_SP3",
-                                ("SLES", "11.2"): "SLE_11_SP2",
-                                ("SLES", "12.1"): "SLE_12_SP1",
-                                ("SLES", "12"): "SLE_12",
-                                ("openSUSE", "13.2"): "openSUSE_13.2",
-                                ("openSUSE Leap", "42.1"):
-                                "openSUSE_Leap_42.1",
-                                ("openSUSE Tumbleweed", None):
-                                "openSUSE_Tumbleweed"}
-
-            repo_version = repo_version_map.get(
-                (self._distro, self._version_id), "SLE_12_SP1")
-
-            repo = "obs://Cloud:Tools/%s" % repo_version
-            self._event_manager.progress_update("Adding repository: %s" % repo)
-            self._exec_cmd_chroot("zypper --non-interactive addrepo -f %s "
-                                  "Cloud-Tools" % repo)
-        self._exec_cmd_chroot(
-            "zypper --non-interactive --no-gpg-checks refresh")
-
-    def _run_dracut(self):
-        package_names = self._exec_cmd_chroot(
-            'rpm -q kernel-default').decode().split('\n')[:-1]
-        for package_name in package_names:
-            m = re.match(r'^kernel-default-(.*)\.\d\..*$', package_name)
-            if m:
-                kernel_version = "%s-default" % m.groups()[0]
-                self._event_manager.progress_update(
-                    "Generating initrd for kernel: %s" % kernel_version)
-                self._exec_cmd_chroot(
-                    "dracut -f /boot/initrd-%(version)s %(version)s" %
-                    {"version": kernel_version})
-
-    def _has_systemd(self):
-        try:
-            self._exec_cmd_chroot("rpm -q systemd")
-            return True
-        except:
-            return False
-
-    def _configure_cloud_init(self):
-        if "cloud-init" in self.get_packages()[0]:
-            if self._has_systemd():
-                self._enable_systemd_service("cloud-init")
-
-    def install_packages(self, package_names):
-        self._exec_cmd_chroot(
-            'zypper --non-interactive install %s' % " ".join(package_names))
-
-    def uninstall_packages(self, package_names):
-        self._exec_cmd_chroot(
-            'zypper --non-interactive remove %s' % " ".join(package_names))
-
-    def post_packages_install(self):
-        self._run_dracut()
-        self._configure_cloud_init()
+import os
+import re
+
+from coriolis import constants
+from coriolis.osmorphing import base
+
+
+class SUSEMorphingTools(base.BaseLinuxOSMorphingTools):
+    _packages = {
+        (constants.HYPERVISOR_VMWARE, None): [("open-vm-tools", True)],
+        (None, constants.PLATFORM_OPENSTACK): [("cloud-init", True)],
+    }
+
+    def _check_os(self):
+        os_release = self._get_os_release()
+        name = os_release.get("NAME")
+        if name == "SLES" or name.startswith("openSUSE"):
+            pretty_name = os_release.get("PRETTY_NAME")
+            if name == "openSUSE Tumbleweed":
+                self._version_id = None
+            else:
+                self._version_id = os_release.get("VERSION_ID")
+            return (name, pretty_name)
+
+        suse_release_path = "etc/SuSE-release"
+        if self._test_path(suse_release_path):
+            out = self._read_file(suse_release_path).decode()
+            release = out.split('\n')[0]
+            version_id = re.findall('^VERSION = (.*)$', out, re.MULTILINE)[0]
+            patch_level = re.findall('^PATCHLEVEL = (.*)$', out, re.MULTILINE)
+            if patch_level:
+                version_id = "%s.%s" % (version_id, patch_level[1])
+            self._version_id = version_id
+            return ('SUSE', release)
+
+    def set_net_config(self, nics_info, dhcp):
+        # TODO: add networking support
+        pass
+
+    def _copy_resolv_conf(self):
+        resolv_conf_path = os.path.join(self._os_root_dir, "etc/resolv.conf")
+        self._exec_cmd("sudo cp -f /etc/resolv.conf %s" % resolv_conf_path)
+
+    def pre_packages_install(self):
+        self._copy_resolv_conf()
+
+        if self._platform == constants.PLATFORM_OPENSTACK:
+            # TODO: use OS version to choose the right repo
+            repo_version_map = {("SLES", "11.4"): "SLE_11_SP4",
+                                ("SLES", "11.3"): "SLE_11_SP3",
+                                ("SLES", "11.2"): "SLE_11_SP2",
+                                ("SLES", "12.1"): "SLE_12_SP1",
+                                ("SLES", "12"): "SLE_12",
+                                ("openSUSE", "13.2"): "openSUSE_13.2",
+                                ("openSUSE Leap", "42.1"):
+                                "openSUSE_Leap_42.1",
+                                ("openSUSE Tumbleweed", None):
+                                "openSUSE_Tumbleweed"}
+
+            repo_version = repo_version_map.get(
+                (self._distro, self._version_id), "SLE_12_SP1")
+
+            repo = "obs://Cloud:Tools/%s" % repo_version
+            self._event_manager.progress_update("Adding repository: %s" % repo)
+            self._exec_cmd_chroot("zypper --non-interactive addrepo -f %s "
+                                  "Cloud-Tools" % repo)
+        self._exec_cmd_chroot(
+            "zypper --non-interactive --no-gpg-checks refresh")
+
+    def _run_dracut(self):
+        package_names = self._exec_cmd_chroot(
+            'rpm -q kernel-default').decode().split('\n')[:-1]
+        for package_name in package_names:
+            m = re.match(r'^kernel-default-(.*)\.\d\..*$', package_name)
+            if m:
+                kernel_version = "%s-default" % m.groups()[0]
+                self._event_manager.progress_update(
+                    "Generating initrd for kernel: %s" % kernel_version)
+                self._exec_cmd_chroot(
+                    "dracut -f /boot/initrd-%(version)s %(version)s" %
+                    {"version": kernel_version})
+
+    def _has_systemd(self):
+        try:
+            self._exec_cmd_chroot("rpm -q systemd")
+            return True
+        except:
+            return False
+
+    def _configure_cloud_init(self):
+        if "cloud-init" in self.get_packages()[0]:
+            if self._has_systemd():
+                self._enable_systemd_service("cloud-init")
+
+    def install_packages(self, package_names):
+        self._exec_cmd_chroot(
+            'zypper --non-interactive install %s' % " ".join(package_names))
+
+    def uninstall_packages(self, package_names):
+        self._exec_cmd_chroot(
+            'zypper --non-interactive remove %s' % " ".join(package_names))
+
+    def post_packages_install(self):
+        self._run_dracut()
+        self._configure_cloud_init()