Ejemplo n.º 1
0
    def a90_reinitialise_cloud_init():
        """
        Installs a script to reinitialise the cloud_init service.

        Returns
        -------
            bool: True on success, False otherwise.
        """
        _logger.debug('__ Copy the reinitialise cloud init script.')
        #
        # get the script name
        try:
            #
            # get the script name
            reinitialise_cloud_init_script = \
                get_config_data('reinitialise_cloud_init_script')
            _logger.debug('Got reinitialise_cloud_init_script name: %s',
                          reinitialise_cloud_init_script)
            #
            # write the reinitialise script code
            with open(reinitialise_cloud_init_script, 'w') as fi:
                fi.writelines(
                    ln + '\n'
                    for ln in get_config_data('reinitialise_cloud_init'))
            os.chmod(reinitialise_cloud_init_script, stat.S_IRWXU)
        except Exception as e:
            _logger.warning(
                'Failed to collect the reinitialise_cloud_init_script path: %s',
                str(e))
            return False
        return True
Ejemplo n.º 2
0
    def test_read_single_value(self):
        """
        Test read a single value from the config file.

        Returns
        -------
            No return value.
        """
        mig_single_values = ['dummy_format_key',
                             'ociconfigfile',
                             'lc_all',
                             'result_filepath',
                             'default_interfaces',
                             'default_netplan',
                             'default_nwmconfig',
                             'default_nwconnections',
                             'default_systemd_file',
                             'cloudconfig_file',
                             'ol_os_oracle_cloud_agent_base',
                             'ol_os_oracle_cloud_agent_store',
                             'oracle_cloud_agent_doc',
                             'ol_os_oci_region_script',
                             'ubuntu_os_snap_install_script',
                             'reinitialise_cloud_init_script']
        for mig_single_value in mig_single_values:
            self.assertIsNotNone(migrate_tools.get_config_data(mig_single_value))
Ejemplo n.º 3
0
        def get_ubuntu_snap_package_list():
            """
            Retrieve the list of packages to install from oci-migrate-config file.

            Returns
            -------
            list: list of package names to install.
            """
            _logger.debug('__ Collection list of snap packages.')
            try:
                snap_pkg_list = get_config_data(
                    'ubuntu_os_packages_to_install_snap')
                if bool(snap_pkg_list):
                    pkg_list = '('
                else:
                    _logger.debug('snap package list is empty.')
                    return False
                _logger.debug('Package list: %s', snap_pkg_list)
                for pkg in snap_pkg_list:
                    pkg_list = pkg_list.__add__("'")\
                        .__add__(pkg)\
                        .__add__("'")\
                        .__add__(" ")
                pkg_list = pkg_list.__add__(')')
                _logger.debug('Package list: %s', pkg_list)
                return pkg_list
            except Exception as e:
                _logger.warning('Failed to find a list of packages: %s',
                                str(e))
                return False
Ejemplo n.º 4
0
    def test_read_list(self):
        """
        Test read list.

        Returns
        -------
            No return value.
        """
        mig_list_values = ['filesystem_types',
                           'partition_to_skip',
                           'valid_boot_types',
                           'essential_dir_list',
                           'default_ifcfg_config',
                           'default_interfaces_config',
                           'default_nwm_conf_file',
                           'default_systemd',
                           'default_systemd_config',
                           'valid_os',
                           'ol_os_packages_to_install',
                           'ol_os_for_cloud_agent',
                           'ol_os_oci_region_bash',
                           'ubuntu_os_packages_to_install_apt',
                           'ubuntu_os_packages_to_install_snap',
                           'ubuntu_os_snapd_bash',
                           'reinitialise_cloud_init']
        for mig_list in mig_list_values:
            test_res = migrate_tools.get_config_data(mig_list)
            self.assertIsNotNone(test_res)
            self.assertIsInstance(test_res, list)
Ejemplo n.º 5
0
    def test_read_dict(self):
        """
        Test read a dict.

        Returns
        -------
            No return value.
        """
        mig_dict_values = ['helpers_list',
                           'partition_types',
                           'ol_version_id_dict',
                           'ol_os_oracle_cloud_agent']
        for mig_dict in mig_dict_values:
            test_res = migrate_tools.get_config_data(mig_dict)
            self.assertIsNotNone(test_res)
            self.assertIsInstance(test_res, dict)
Ejemplo n.º 6
0
        def get_ol_package_list():
            """
            Retrieve the list of packages to install from oci-migrate-config file.

            Returns
            -------
            list: list of package names to install.
            """
            _logger.debug('Collection list of packages.')
            try:
                pkg_list = get_config_data('ol_os_packages_to_install')
                _logger.debug('Package list: %s' % pkg_list)
                return pkg_list
            except Exception as e:
                _logger.warning('Failed to find a list of packages: %s' % str(e))
                return False
Ejemplo n.º 7
0
        def get_ubuntu_package_list():
            """
            Retrieve the list of packages to install from oci-migrate-config file.

            Returns
            -------
            list: list of package names to install.
            """
            _logger.debug('Collection list of packages.')
            try:
                pkg_list = get_config_data('ubuntu_os_packages_to_install_apt')
                if not bool(pkg_list):
                    _logger.debug('apt package list is empty.')
                    return False
                _logger.debug('Package list: %s', pkg_list)
                return pkg_list
            except Exception as e:
                _logger.warning('Failed to find a list of packages: %s',
                                str(e))
                return False
Ejemplo n.º 8
0
def reconfigure_networkmanager(rootdir):
    """
    Replace the networkmanager configuration with Oracle Cloud Infrastructure
    compatible version.

    Parameters
    ----------
    rootdir: str
        Full path of image root dir as loopback mounted.
    Returns
    -------
        list: list of nic.
        dict: the network manager system-connections configurations
    """
    _logger.debug('__ The NetworkManager configuration.')
    netwmg_data = dict()
    netwmg_nics = list()
    network_config_dir = rootdir + get_config_data('default_nwconnections')
    _logger.debug('Network manager dir: %s' % network_config_dir)
    nw_mgr_cfg = rootdir + get_config_data('default_nwmconfig')
    _logger.debug('Network manager conf: %s' % nw_mgr_cfg)
    #
    # backup
    try:
        #
        # copy
        if os.path.isfile(nw_mgr_cfg):
            bck_nw_mgr_cfg = system_tools.exec_rename(nw_mgr_cfg)
            if bool(bck_nw_mgr_cfg):
                _logger.debug('Copied %s to %s' % (nw_mgr_cfg, bck_nw_mgr_cfg))
            else:
                _logger.warning(
                    'Failed to backup network manager configuration.')
        else:
            _logger.debug('No %s found.' % nw_mgr_cfg)
        #
        if os.path.isdir(network_config_dir):
            bck_network_config_dir = system_tools.backup_dir(
                network_config_dir)
            _logger.debug('Copied %s to %s' %
                          (network_config_dir, bck_network_config_dir))
        else:
            _logger.debug('%s not found.' % network_config_dir)
    except Exception as e:
        migrate_tools.error_msg('Failed to backup the networkmanager '
                                'configuration: %s' % str(e))
    #
    #
    if os.path.isdir(network_config_dir):
        _logger.debug('NetworkManager/%s directory exists.' %
                      network_config_dir)
        #
        # contains nwm keyfiles?
        nwm_files = glob(network_config_dir + '/*')
        if len(nwm_files) > 0:
            system_tools.exec_rmdir(network_config_dir)
            system_tools.exec_mkdir(network_config_dir)
            _logger.debug('%s emptied.' % network_config_dir)
        else:
            _logger.debug('No network manager keyfiles found.')
        #
        # update networkmanager configuration
        # TODO: write config file with configparser
        nwm_config_data = get_config_data('default_nwm_conf_file')
        with open(nw_mgr_cfg, 'w') as nwmf:
            nwmf.write('\n'.join(str(x) for x in nwm_config_data))
            migrate_tools.result_msg(
                msg='Networkmanager configuration updated.', result=False)
    else:
        _logger.debug(msg='  No NetworkManager configuration present.')

    return netwmg_nics, netwmg_data
Ejemplo n.º 9
0
def reconfigure_netplan(rootdir):
    """
    Parse the yaml netplan files and look for network interface names.

    Parameters
    ----------
    rootdir: str
        Full path of image root dir as loopback mounted.

    Returns
    -------
        list: list of nic.
        dict: the netplan network configurations.
    """

    _logger.debug('__ The netplan configuration.')
    netplan_data = dict()
    netplan_nics = list()
    root_path = rootdir + get_config_data('default_netplan')
    if os.path.isdir(root_path):
        _logger.debug('netplan directory exists.')
        #
        # contains yaml files?
        yaml_files = glob(root_path + '/*.yaml')
        if len(yaml_files) > 0:
            for yf in sorted(yaml_files):
                try:
                    with open(yf, 'r') as yfd:
                        yaml_data = yaml.safe_load(yfd)
                        netplan_data[yf] = yaml_data
                        _logger.debug('netplan: %s' % yaml_data)
                except Exception as e:
                    _logger.error('  Failed to parse %s: %s' % (yf, str(e)))
                    migrate_tools.error_msg('Failed to parse %s: %s' %
                                            (yf, str(e)))
                    break
                #
                if 'network' in yaml_data:
                    if 'ethernets' in yaml_data['network']:
                        for k, _ in sorted(
                                yaml_data['network']['ethernets'].items()):
                            netplan_nics.append(k)
                    else:
                        _logger.debug('ethernets key missing.')
                else:
                    _logger.debug('network key missing.')
            if len(netplan_nics) == 0:
                _logger.debug('No netplan definitions found in %s' % root_path)
            else:
                nicname = sorted(netplan_nics)[0]
                #
                # rename and recreate
                try:
                    #
                    # backup
                    if not bool(system_tools.exec_rename(root_path)):
                        _logger.warning('Failed to backup %s.' % root_path)
                    #
                    # recreate dir
                    os.mkdir(root_path)
                    mode755 = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH | \
                              stat.S_IWUSR | stat.S_IRUSR | stat.S_IRGRP | \
                              stat.S_IROTH
                    os.chmod(root_path, mode755)
                    _logger.debug((' Recreated %s' % root_path))
                    #
                    # recreate netplan config
                    #
                    # __GT__ commenting out this one to avoid conflicts,
                    #  cloud-init recreates it from scratch.
                    #
                    # netplan_config = get_config_data('default_netplan_config')
                    # netplan_config['network']['ethernets'][nicname] \
                    #    = netplan_config['network']['ethernets'].pop('_XXXX_')
                    # with open(root_path + '/'
                    #          + get_config_data('default_netplan_file'), 'w') \
                    #        as yf:
                    #    yaml.safe_dump(netplan_config, yf, default_flow_style=False)
                    # migrate_tools.result_msg(msg='Netplan network configuration '
                    #                         'files replaced.', result=True)
                except Exception as e:
                    migrate_tools.error_msg(
                        'Failed to write new netplan '
                        'configuration file %s: %s' %
                        (get_config_data('default_netplan_file'), str(e)))
                    raise OciMigrateException(
                        'Failed to write new netplan '
                        'configuration file %s: %s' %
                        (get_config_data('default_netplan_file'), str(e)))
        else:
            _logger.debug('  No netplan yaml config files found.')
    else:
        _logger.debug('No netplan configuration found.')

    return netplan_nics, netplan_data
Ejemplo n.º 10
0
def main():
    """
    Main

    Returns
    -------
        int
            0 on success, 1 otherwise.
    """
    #
    # set locale
    lc_all_to_set = get_config_data('lc_all')
    os.environ['LC_ALL'] = "%s" % lc_all_to_set
    _logger.debug('Locale set to %s' % lc_all_to_set)
    #
    # python version
    pythonver = sys.version_info[0]
    _logger.debug('Python version is %s' % pythonver)
    #
    # parse the commandline
    args = parse_args()
    #
    # Operator needs to be root.
    if system_tools.is_root():
        _logger.debug('User is root.')
    else:
        exit_with_msg('  *** ERROR *** You must run this program with root '
                      'privileges')
    #
    # Verbose mode is False by default
    migrate_data.verbose_flag = args.verbose_flag
    _logger.debug('Verbose level set to %s' % migrate_data.verbose_flag)
    #
    # Yes flag
    migrate_data.yes_flag = args.yes_flag
    _logger.debug('Answer to yes/no questions supposed to be yes always.')
    #
    # collect and save configuration data
    migrate_data.oci_image_migrate_config = get_config_data('*')
    #
    try:
        #
        # input image
        if args.input_image:
            imagepath = args.input_image.name
            resultfilename = get_config_data('resultfilepath') + \
                '_' + \
                os.path.splitext(os.path.basename(imagepath))[0] \
                + '.res'
            migrate_data.resultfilename = resultfilename
            migrate_tools.result_msg(msg='\n  Running %s at %s\n'
                                         % ((os.path.basename(sys.argv[0])
                                             + ' '
                                             + ' '.join(sys.argv[1:])),
                                            time.ctime()),
                                     flags='w',
                                     result=True)
        else:
            raise OciMigrateException('Missing argument: input image path.')
        #
        # Import the 'format' modules and collect the format data
        supported_formats = migrate_tools.import_formats()
        if not bool(supported_formats):
            exit_with_msg('  *** ERROR ***  No image format modules found')
        if migrate_data.verbose_flag:
            show_supported_formats_data(supported_formats)
        #
        # Check the utilities installed.
        util_list, missing_list = test_helpers()
        _logger.debug('%s' % util_list)
        if migrate_data.verbose_flag:
            show_utilities(util_list, missing_list)
        if missing_list:
            raise OciMigrateException('%s needs packages %s installed.\n'
                                      % (sys.argv[0], missing_list))
        #
        # if qemu-img is used, the minimal version is 2
        qemuversioninfo = qemu_img_version()
        if qemuversioninfo[1] < 2:
            raise OciMigrateException('Minimal version of qemu-img is 2, '
                                      '%s found.' % qemuversioninfo[0])
        else:
            _logger.debug('release data ok')
        #
        # Get the nameserver definition
        if system_tools.get_nameserver():
            migrate_tools.result_msg(msg='nameserver %s identified.'
                                         % migrate_data.nameserver, result=False)
            _logger.debug('Nameserver identified as %s' % migrate_data.nameserver)
        else:
            migrate_tools.error_msg('Failed to identify nameserver, using %s, '
                                    'but might cause issues.'
                                    % migrate_data.nameserver)
    except Exception as e:
        _logger.error('*** ERROR *** %s\n' % str(e))
        exit_with_msg('  *** ERROR *** %s\n' % str(e))
    #
    # More on command line arguments.
    #
    # initialise output
    migrate_tools.result_msg(msg='Results are written to %s.'
                                 % migrate_data.resultfilename, result=True)
    migrate_tools.result_msg(msg='Input image:  %s' % imagepath, result=True)
    #
    # Verify if readable.
    fn_magic = migrate_tools.get_magic_data(imagepath)
    if fn_magic is None:
        exit_with_msg('*** ERROR *** An error occured while trying to read '
                      'magic number of File %s.' % imagepath)
    else:
        pause_msg('Image Magic Number: %s' % fn_magic)
        _logger.debug('Magic number %s successfully read' % fn_magic)
    #
    # Verify if image type is supported.
    _logger.debug('Magic number of %s is %s' % (imagepath, fn_magic))
    if fn_magic not in supported_formats:
        exit_with_msg('*** ERROR *** Image type %s is not recognised.' % fn_magic)
    else:
        _logger.debug('Image type recognised.')
    #
    # Get the correct class.
    imageclazz = supported_formats[fn_magic]
    migrate_tools.result_msg(msg='Type of image %s identified as %s'
                             % (imagepath, imageclazz['name']), result=True)
    pause_msg('Image type is %s' % imageclazz['name'])
    #
    # Locate the class and module
    imageclassdef = getattr(sys.modules['oci_utils.migrate.image_types.%s'
                                        % supported_formats[fn_magic]['name']],
                            imageclazz['clazz'])
    image_object = imageclassdef(imagepath)
    #
    # Local volume groups.
    vgs_result = system_tools.exec_vgs_noheadings()
    migrate_data.local_volume_groups = \
        vgs_result if bool(vgs_result) \
        else []
    _logger.debug('Workstation volume groups: %s'
                  % migrate_data.local_volume_groups)
    #
    # Rename local volume groups
    if bool(migrate_data.local_volume_groups):
        rename_msg = '\n   The workstation has logical volumes defined. To avoid ' \
                     'duplicates, the \n   logical volume groups will be temporary' \
                     ' renamed to a hexadecimal uuid.\n   If you are sure the ' \
                     'image to be uploaded does not contain logical volumes,\n' \
                     '   or there are no conflicting volume group names, '\
                     'the rename can be skipped\n\n   Keep the volume group names?'
        if not read_yn(rename_msg,
                       waitenter=True,
                       suppose_yes=migrate_data.yes_flag):
            if migrate_tools.verify_local_fstab():
                fstab_msg = '\n   The fstab file on this workstation seems to ' \
                            'contain device references\n   using /dev/mapper ' \
                            'devices. The volume group names on this ' \
                            'workstation\n   will be renamed temporarily. ' \
                            '/dev/mapper devices referring to logical volumes\n' \
                            '   can create problems in this context. To avoid ' \
                            'this situation\n   exit now and modify the ' \
                            'device specification to LABEL or UUID.\n\n   Continue?'
                if not read_yn(fstab_msg,
                               waitenter=True,
                               suppose_yes=migrate_data.yes_flag):
                    exit_with_msg('Exiting')
                _logger.debug('Rename local volume groups to avoid conflicts.')
                vgrename_res = system_tools.exec_rename_volume_groups(
                    migrate_data.local_volume_groups, 'FORWARD')
                migrate_data.local_volume_group_rename = True
            else:
                _logger.debug('fstab file has no /dev/mapper devices.')
        else:
            _logger.debug('Not renaming the volume groups.')
            _ = system_tools.reset_vg_list(migrate_data.local_volume_groups)
    else:
        _logger.debug('No local volume groups, no conflicts.')
    #
    # Generic data collection
    try:
        imgres, imagedata = collect_image_data(image_object)
        if migrate_data.verbose_flag:
            migrate_tools.show_image_data(image_object)
        if imgres:
            _logger.debug('Image processing succeeded.')
        else:
            _logger.critical('   Image processing failed.', exc_info=False)
        #
        if imagedata:
            _logger.debug('%s passed.' % imagepath)
        else:
            _logger.critical('   %s failed.' % imagepath, exc_info=False)
    except Exception as e:
        _logger.critical('   %s failed: %s' % (imagepath, str(e)))
        exit_with_msg('*** ERROR *** Problem detected during investigation of '
                      'the image %s: %s, exiting.' % (imagepath, str(e)))
    #
    # Restore volume group names.
    if migrate_data.local_volume_group_rename:
        _logger.debug('Restore local volume groups.')
        vgrename_res = system_tools.exec_rename_volume_groups(
            migrate_data.local_volume_groups, 'BACKWARD')
    else:
        _logger.debug('No local volume group names to restore.')
    #
    # passed prerequisites and changes?
    prereq_passed = True
    #
    # Image type specific prerequisites
    prereq_msg = ''
    sup, msg = image_object.type_specific_prereq_test()
    if sup:
        migrate_tools.result_msg(msg='%s' % msg, result=True)
    else:
        prereq_passed = False
        prereq_msg = msg
    #
    # Generic prerequisites verification
    try:
        gen_prereq, msg = image_object.generic_prereq_check()
        if gen_prereq:
            prereq_msg += '\n  %s passed the generic preqrequisites.' % imagepath
        else:
            prereq_passed = False
            prereq_msg += msg
        #
        if imgres:
            prereq_msg += '\n\n  %s data collection and processing succeeded.' \
                          % imagepath
        else:
            prereq_passed = False
        #
        if prereq_passed:
            migrate_tools.result_msg(msg=prereq_msg, result=True)
            if imagedata['boot_type'] == 'BIOS':
                migrate_tools.result_msg(msg='\n  Boot type is BIOS, '
                                             'use launch_mode PARAVIRTUALIZED '
                                             '(or EMULATED) at import.',
                                         result=True)
            elif imagedata['boot_type'] == 'UEFI':
                migrate_tools.result_msg(msg='\n  Boot type is UEFI, '
                                             'use launch_mode NATIVE '
                                             '(or EMULATED) at import.',
                                         result=True)
            else:
                raise OciMigrateException('Something wrong checking '
                                          'the boot type')
        else:
            prereq_msg += '\n\n  %s processing failed, check the logfile ' \
                          'and/or set environment variable _OCI_UTILS_DEBUG.' \
                          % imagepath
            raise OciMigrateException(prereq_msg)
    except Exception as e:
        exit_with_msg('*** ERROR ***  %s' % str(e))
    #
    # While prerequisite check did not hit a fatal issue, there might be
    # situations where upload should not proceed.
    if not migrate_data.migrate_preparation:
        exit_with_msg('*** ERROR *** Unable to proceed with uploading image '
                      'to Oracle Cloud Infrastructure: %s'
                      % migrate_data.migrate_non_upload_reason)
    else:
        migrate_tools.result_msg('Successfully verified and processed image %s '
                                 'and is ready for upload.' % imagepath)
    return 0
Ejemplo n.º 11
0
from oci_utils.migrate import exit_with_msg
from oci_utils.migrate import migrate_data
from oci_utils.migrate import migrate_tools
from oci_utils.migrate import pause_msg
from oci_utils.migrate import read_yn
from oci_utils.migrate import system_tools
from oci_utils.migrate.exception import OciMigrateException
from oci_utils.migrate.migrate_tools import get_config_data as get_config_data


_logger = logging.getLogger('oci-utils.oci-image-migrate')
#
# Dictionary containing utilities which might be needed with the packages
# which provide them.
try:
    helpers_list = get_config_data('helpers_list')
except Exception as e:
    exit_with_msg('Failed to retrieve the list of required utilities. Verify '
                  'the existence and contents of the configuration file '
                  'oci-migrate-conf.yaml.')


def parse_args():
    """
    Parse the command line arguments and return an object representing the
    command line (as returned by argparse's parse_args())
    arguments:
     -i|--input-image <on-premise image>; mandatory.
     -y| --yes suppose the answer YES to all Y/N questions
     -v|--verbose produces verbose output.
     -h|--help
Ejemplo n.º 12
0
        def add_oci_region(regionscript):
            """
            Update the default user name in the cloud.cfg file.

            Parameters:
            ----------
                regionscript: str
                    full path of the bash script.

            Returns:
            -------
                bool: True on success, False otherwise.
            """
            _logger.debug('__ Add oci region.')
            try:
                cloudconfig = get_config_data('cloudconfig_file')
                _logger.debug('Updating cloud.cfg file %s, adding oci region '
                              'detection.' % cloudconfig)
            except Exception as e:
                _logger.error('Failed to find cloud config file '
                              'location: %s.' % str(e))
                return False

            if os.path.isfile(cloudconfig):
                with open(cloudconfig, 'r') as f:
                    cloudcfg = yaml.load(f, Loader=yaml.SafeLoader)
                region_definition = False
                if type(cloudcfg) is dict:
                    if 'runcmd' in list(cloudcfg.keys()):
                        #
                        # runcmd present in cloud config file
                        run_cmd = cloudcfg['runcmd']
                        for yaml_key in run_cmd:
                            if type(yaml_key) == 'list':
                                for yamlval in yaml_key:
                                    if regionscript in yamlval:
                                        _logger.debug('%s already in '
                                                      'cloud_init' % regionscript)
                                        region_definition = True
                                        break
                            else:
                                if regionscript in yaml_key:
                                    _logger.debug('%s already in '
                                                  'cloud_init' % regionscript)
                                    region_definition = True
                                    break
                        if not region_definition:
                            #
                            # the regionscript not yet defined in runcmd
                            run_cmd.append(regionscript)
                    else:
                        #
                        # runcmd not yet present in cloud config file
                        cloudcfg['runcmd'] = [regionscript]

                    with open(cloudconfig, 'w') as f:
                        yaml.dump(cloudcfg, f, width=50)
                        _logger.debug('Cloud configuration file %s successfully '
                                      'updated.' % cloudconfig)
                    return True
                else:
                    _logger.error('Invalid cloud config file.')
            else:
                _logger.error('Cloud config file %s does not exist.'
                              % cloudconfig)
                return False
Ejemplo n.º 13
0
def reconfigure_ifcfg_config(rootdir):
    """
    Modify the network configuration in the image file to prevent
    conflicts during import. This is only for ol-type linux.

    Parameters
    ----------
    rootdir: str
        Full path of image root dir as loopback mounted.

    Returns
    -------
        list: list of nic.
        dict: the interfaces configuration.
    """
    #
    # Rename the config files
    _logger.debug('__ The network ifcfg configuration.')
    ifcfg_list = list()
    ifcfg_data = dict()
    ifrootdir = rootdir + get_config_data('default_ifcfg')
    if os.path.isdir(ifrootdir):
        for cfgfile in glob(ifrootdir + '/ifcfg-*'):
            _logger.debug('Checking configfile: %s' % cfgfile)
            try:
                with open(cfgfile, 'r') as f:
                    # nl = filter(None, [x[:x.find('#')] for x in f])
                    nl = [_f for _f in [x[:x.find('#')] for x in f] if _f]
                ifcfg = dict(dl.replace('"', '').split('=') for dl in nl)
                if 'DEVICE' in ifcfg:
                    devname = ifcfg['DEVICE']
                else:
                    _logger.debug('Missing device name in %s' % cfgfile)
                    devname = cfgfile.split('/')[-1]
                ifcfg_list.append(devname)
                ifcfg_data[devname] = ifcfg
                _logger.debug('Network interface: %s' % devname)
            except Exception as e:
                _logger.error(
                    '  Problem reading network configuration file %s: '
                    '%s' % (cfgfile, str(e)))
    else:
        _logger.debug('No ifcfg network configuration.')
    #
    # backup
    for fn in glob(ifrootdir + '/ifcfg-*'):
        if 'ifcfg-lo' not in fn:
            fn_bck = system_tools.exec_rename(fn)
            if bool(fn_bck):
                _logger.debug('Network config file %s successfully '
                              'renamed to %s' % (fn, fn_bck))
            else:
                _logger.debug('Failed to backup network configuration '
                              'file %s to %s.' % (fn, fn_bck))
                # migrate_tools.error_msg('Failed to backup network configuration '
                #                         'file %s to %s.' % (fn, fn_bck))
                # raise OciMigrateException('Failed to rename network config '
                #                           'file %s to %s' % (fn, fn_bck))
        else:
            _logger.debug('ifcfg-lo found.')
    #
    # Generate new default network configuration.
    if len(ifcfg_list) > 0:
        nic0 = sorted(ifcfg_list)[0]
        dhcpniccfg = ifrootdir + '/ifcfg-%s' % nic0
        _logger.debug('Replacing network config file %s' % dhcpniccfg)
        try:
            with open(dhcpniccfg, 'w') as f:
                f.writelines(
                    ln.replace('_XXXX_', nic0) + '\n'
                    for ln in get_config_data('default_ifcfg_config'))
            migrate_tools.result_msg(
                msg='Replaced ifcfg network configuration.', result=False)
        except Exception as e:
            _logger.error('  Failed to write %s/ifcfg-eth0' % ifrootdir)
            migrate_tools.error_msg('Failed to write %s: %s' %
                                    (dhcpniccfg, str(e)))
            raise OciMigrateException('Failed to write %s: %s' %
                                      (dhcpniccfg, str(e)))
    else:
        _logger.debug('No ifcfg definitions found.')

    return ifcfg_list, ifcfg_data
Ejemplo n.º 14
0
    def b30_install_snap_packages(self):
        """
        Add a job to the cloud-init config file to install additional packages
        by snap at first boot. (snapd cannot be run while in chroot during
        image preparation.)

        Returns
        -------
           bool: True on success, False otherwise. (always True as packages to
                 be installed via snap are not considered essential.)
        """
        def get_ubuntu_snap_package_list():
            """
            Retrieve the list of packages to install from oci-migrate-config file.

            Returns
            -------
            list: list of package names to install.
            """
            _logger.debug('__ Collection list of snap packages.')
            try:
                snap_pkg_list = get_config_data(
                    'ubuntu_os_packages_to_install_snap')
                if bool(snap_pkg_list):
                    pkg_list = '('
                else:
                    _logger.debug('snap package list is empty.')
                    return False
                _logger.debug('Package list: %s', snap_pkg_list)
                for pkg in snap_pkg_list:
                    pkg_list = pkg_list.__add__("'")\
                        .__add__(pkg)\
                        .__add__("'")\
                        .__add__(" ")
                pkg_list = pkg_list.__add__(')')
                _logger.debug('Package list: %s', pkg_list)
                return pkg_list
            except Exception as e:
                _logger.warning('Failed to find a list of packages: %s',
                                str(e))
                return False

        _logger.debug('__ Install software packages using snap.')
        try:
            #
            # collect packages to install
            packages = get_ubuntu_snap_package_list()
            if not bool(packages):
                _logger.debug('No extra packages to install.')
                return True
            #
            # get snapd script name
            ubuntu_os_snap_install_script = \
                get_config_data('ubuntu_os_snap_install_script')
            _logger.debug('snap package install script: %s',
                          ubuntu_os_snap_install_script)
            #
            # get, update and write the script.
            with open(ubuntu_os_snap_install_script, 'w') as bashf:
                bashf.writelines(
                    ln.replace('_XXXX_', packages) + '\n'
                    for ln in get_config_data('ubuntu_os_snapd_bash'))
            os.chmod(ubuntu_os_snap_install_script, stat.S_IRWXU)
            #
            # update cloud-init with runcmd command
            if migrate_tools.update_cloudconfig_runcmd(
                    ubuntu_os_snap_install_script):
                _logger.debug('snap install script successfully added.')
                migrate_tools.result_msg(msg='snap packages install script '
                                         'successfully added.',
                                         result=False)
            else:
                _logger.debug('Failed to add snap install script.')
        except Exception as e:
            _logger.warning(
                'Failed to install one or more packages of %s:\n%s', packages,
                str(e))
            #
            # not considered as essential or fatal.
        return True
Ejemplo n.º 15
0
def reconfigure_interfaces(rootdir):
    """
    Parse the network interfaces file.

    Parameters
    ----------
    rootdir: str
        Full path of image root dir as loopback mounted.

    Returns
    -------
        list: list of nic.
        dict: the interfaces configuration.
    """
    _logger.debug('__ The network interfaces configuration.')
    int_data = dict()
    int_nics = list()
    root_path = rootdir + get_config_data('default_interfaces')
    net_ifcfg_config = root_path + '/interfaces'

    if os.path.isfile(net_ifcfg_config):
        int_data[get_config_data('default_interfaces')] = list()
        _logger.debug('%s file exists' % net_ifcfg_config)
        try:
            with open(net_ifcfg_config, 'r') as inf:
                for ln in inf:
                    int_data[get_config_data('default_interfaces')].append(ln)
                    if 'iface' in ln.split():
                        if ln.split()[1] != 'lo':
                            int_nics.append(ln.split()[1])
                    else:
                        _logger.debug('no iface in %s' % ln)
        except Exception as e:
            _logger.error('  Error occured while reading %s: %s' %
                          (net_ifcfg_config, str(e)))
        #
        # rewrite
        if len(int_nics) == 0:
            _logger.debug('No interface definitions found in %s' %
                          net_ifcfg_config)
        else:
            try:
                #
                # backup
                bck_root_path = system_tools.backup_dir(root_path)
                _logger.debug('Copied %s to %s' % (root_path, bck_root_path))
                #
                # remove dir
                shutil.rmtree(root_path + '/interfaces.d')
                #
                # recreate interfaces config
                with open(net_ifcfg_config, 'w') as fi:
                    fi.writelines(
                        ln.replace('_XXXX_', int_nics[0]) + '\n'
                        for ln in get_config_data('default_interfaces_config'))
                migrate_tools.result_msg(
                    msg='Network interfaces file rewritten.', result=False)
            except Exception as e:
                _logger.error('  Failed to write new interfaces configuration '
                              'file %s: %s' % (net_ifcfg_config, str(e)))
    else:
        _logger.debug('No network interfaces configuration.')
    return int_nics, int_data
Ejemplo n.º 16
0
def reconfigure_systemd_networkd(rootdir):
    """
    Parse the systemd network configuration.

    Parameters
    ----------
    rootdir: str
        Full path of image root dir as loopback mounted.

    Returns
    -------
        list: list of nic.
        dict: the interfaces configuration.
    """
    _logger.debug('__ The network systemd-networkd configuration.')
    sys_data = dict()
    sys_nics = list()
    nw_ignore = ['container-host0', 'container-ve', 'container-vz']

    for root_path in get_config_data('default_systemd'):
        networkd_root = rootdir + root_path
        if os.path.isdir(networkd_root):
            _logger.debug('systemd network directory exists.')
            systemd_files = glob(root_path + '/*.network')
            if len(systemd_files) > 0:
                for sf in sorted(systemd_files):
                    ignore = False
                    for ig in nw_ignore:
                        if ig in sf:
                            ignore = True
                            break
                    if not ignore:
                        systemtd_net_config = ConfigParser()
                        sys_data[sf] = dict()
                        try:
                            sv = systemtd_net_config.read(sf)
                            if 'Match' in systemtd_net_config.sections():
                                ifname = systemtd_net_config.get(
                                    'Match', 'Name')
                                sys_nics.append(ifname)
                            else:
                                _logger.debug('-- No Match section in %s' % sf)
                            #
                            for sec in systemtd_net_config.sections():
                                sys_data[sf][sec] = systemtd_net_config.items(
                                    sec)
                                _logger.debug('%s' % sys_data[sf][sec])
                        except Exception as e:
                            _logger.error('  Failed to parse %s: %s' %
                                          (sf, str(e)))
                        #
                        # rename - backup
                        bcknm = system_tools.exec_rename(sf)
                        if bool(bcknm):
                            _logger.debug(
                                'Network config file %s renamed to %s' %
                                (sf, bcknm))
                        else:
                            _logger.error('  Failed to rename %s' % sf)
                            raise OciMigrateException('Failed to rename %s ' %
                                                      sf)
            else:
                _logger.debug('No systemd-networkd configuration.')
        else:
            _logger.debug('%s does not exist.' %
                          get_config_data('default_systemd'))
    #
    # write new config
    if len(sys_nics) > 0:
        nicname = sorted(sys_nics)[0]
        with open(rootdir + get_config_data('default_systemd_file'),
                  'w') as sdf:
            sdf.writelines(
                ln.replace('_XXXX_', nicname) + '\n'
                for ln in get_config_data('default_systemd_config'))
        migrate_tools.result_msg(
            msg='systemd-networkd configuration rewritten.', result=True)
    else:
        _logger.debug('No systemd-networkd configuration.')
    return sorted(sys_nics), sys_data
Ejemplo n.º 17
0
    def a30_set_oci_region():
        """
        Add a job to cloud-init config file to complete the ociregion data
        at first boot.

        Returns
        -------
            bool: True on success, False otherwise.
        """

        def add_oci_region(regionscript):
            """
            Update the default user name in the cloud.cfg file.

            Parameters:
            ----------
                regionscript: str
                    full path of the bash script.

            Returns:
            -------
                bool: True on success, False otherwise.
            """
            _logger.debug('__ Add oci region.')
            try:
                cloudconfig = get_config_data('cloudconfig_file')
                _logger.debug('Updating cloud.cfg file %s, adding oci region '
                              'detection.' % cloudconfig)
            except Exception as e:
                _logger.error('Failed to find cloud config file '
                              'location: %s.' % str(e))
                return False

            if os.path.isfile(cloudconfig):
                with open(cloudconfig, 'r') as f:
                    cloudcfg = yaml.load(f, Loader=yaml.SafeLoader)
                region_definition = False
                if type(cloudcfg) is dict:
                    if 'runcmd' in list(cloudcfg.keys()):
                        #
                        # runcmd present in cloud config file
                        run_cmd = cloudcfg['runcmd']
                        for yaml_key in run_cmd:
                            if type(yaml_key) == 'list':
                                for yamlval in yaml_key:
                                    if regionscript in yamlval:
                                        _logger.debug('%s already in '
                                                      'cloud_init' % regionscript)
                                        region_definition = True
                                        break
                            else:
                                if regionscript in yaml_key:
                                    _logger.debug('%s already in '
                                                  'cloud_init' % regionscript)
                                    region_definition = True
                                    break
                        if not region_definition:
                            #
                            # the regionscript not yet defined in runcmd
                            run_cmd.append(regionscript)
                    else:
                        #
                        # runcmd not yet present in cloud config file
                        cloudcfg['runcmd'] = [regionscript]

                    with open(cloudconfig, 'w') as f:
                        yaml.dump(cloudcfg, f, width=50)
                        _logger.debug('Cloud configuration file %s successfully '
                                      'updated.' % cloudconfig)
                    return True
                else:
                    _logger.error('Invalid cloud config file.')
            else:
                _logger.error('Cloud config file %s does not exist.'
                              % cloudconfig)
                return False

        _logger.debug('__ Set OCI region.')
        #
        # get the script name
        try:
            oci_region_script = get_config_data('ol_os_oci_region_script')
            _logger.debug('Got oci-region script name: %s' % oci_region_script)
        except Exception as e:
            _logger.warning('Failed to collect the oci_region_script '
                            'path: %s' % str(e))
            return False
        #
        # write the oci region script code
        with open(oci_region_script, 'w') as fi:
            fi.writelines(ln + '\n'
                          for ln in get_config_data('ol_os_oci_region_bash'))
        os.chmod(oci_region_script, stat.S_IRWXU)
        #
        # update cloud-init with runcmd command
        if add_oci_region(oci_region_script):
            _logger.debug('oci region successfully added.')
            migrate_tools.result_msg(msg='Updated OCI region.', result=False)
            return True
        else:
            _logger.debug('Failed to update oci region.')
            return False
def main():
    """
    Upload an image from on-premise to an object storage in the Oracle Cloud Infrastructure.

    Returns
    -------
        int: 0 on success, raises exception on failure.
    """
    #
    # set locale
    lc_all_to_set = get_config_data('lc_all')
    os.environ['LC_ALL'] = "%s" % lc_all_to_set
    _logger.debug('Locale set to %s', lc_all_to_set)
    #
    # command line
    cmdline_args = parse_args()
    #
    # input image
    if cmdline_args.input_image:
        image_path = cmdline_args.input_image.name
        console_msg(msg='\n  Uploading %s at %s\n' % (os.path.basename(' '.join(sys.argv)), time.ctime()))
    else:
        raise OciMigrateException('Missing argument: input image path.')
    #
    # object storage
    bucket_name = cmdline_args.bucket_name
    #
    # output image
    if cmdline_args.output_name:
        output_name = cmdline_args.output_name
    else:
        output_name = os.path.splitext(os.path.basename(image_path))[0]
    #
    # yes
    migrate_data.yes_flag = cmdline_args.yes_flag
    #
    # verbose
    migrate_data.verbose_flag = cmdline_args.verbose_flag
    #
    # message
    console_msg(msg='Uploading %s to object storage %s in the Oracle Cloud '
                    'Infrastructure as %s.' % (image_path,
                                               bucket_name,
                                               output_name))
    #
    # collect data
    try:
        #
        # The object storage exist and data.
        object_storage_data = oci_cli_tools.bucket_exists(bucket_name)
        console_msg(msg='Object storage %s present.' % bucket_name)
        #
        # The object is present in object storage.
        if oci_cli_tools.object_exists(object_storage_data, output_name):
            raise OciMigrateException('Object %s already exists object '
                                      'storage %s.' % (output_name, bucket_name))
        _logger.debug('Object %s does not yet exists in object storage %s', output_name, bucket_name)
    except Exception as e:
        exit_with_msg('Unable to upload %s to %s: %s'
                      % (image_path, bucket_name, str(e)))
    #
    # Ask for confirmation to proceed.
    if not read_yn('\n  Agree to proceed uploading %s to %s as %s?'
                   % (image_path, bucket_name, output_name),
                   waitenter=True,
                   suppose_yes=migrate_data.yes_flag):
        exit_with_msg('\n  Exiting.')
    #
    # Uploading the image to the Oracle Cloud Infrastructure.
    _, nb_columns = terminal_dimension()
    try:
        upload_progress = ProgressBar(nb_columns, 0.2,
                                      progress_chars=['uploading %s' % output_name])
        #
        # Verify if object already exists.
        if oci_cli_tools.object_exists(object_storage_data, output_name):
            raise OciMigrateException('Object %s already exists object storage %s.' % (output_name, bucket_name))
        _logger.debug('Object %s does not yet exists in object storage %s', output_name, bucket_name)
        #
        # Upload the image.
        console_msg(msg='\n  Uploading %s, this might take a while....' % image_path)
        upload_progress.start()
        upload_result = oci_cli_tools.upload_image(image_path, bucket_name, output_name)
        _logger.debug('Upload result: %s', upload_result)
        console_msg(msg='  Finished....\n')
        upload_progress.stop()
    except Exception as e:
        _logger.error('  Error while uploading %s to %s: %s.', image_path, bucket_name, str(e))
        exit_with_msg('*** ERROR *** Error while uploading %s to %s: %s.' % (image_path, bucket_name, str(e)))
    finally:
        # if progress thread was started, needs to be terminated.
        if system_tools.is_thread_running(upload_progress):
            upload_progress.stop()
Ejemplo n.º 19
0
def main():
    """
    Import image from object storage into custom images repository.

    Returns
    -------
        int: 0 on success, raises exception on failure.
    """
    #
    # set locale
    lc_all_to_set = get_config_data('lc_all')
    os.environ['LC_ALL'] = "%s" % lc_all_to_set
    _logger.debug('Locale set to %s', lc_all_to_set)
    #
    # command line
    cmdline_args = parse_args()
    console_msg(msg='Importing %s from %s into %s as %s and setting '
                'launch_mode to %s.' %
                (cmdline_args.image_name, cmdline_args.bucket_name,
                 cmdline_args.bucket_name, cmdline_args.display_name,
                 cmdline_args.launch_mode))
    compartment = cmdline_args.compartment_name
    bucket = cmdline_args.bucket_name
    object_name = cmdline_args.image_name
    display_name = cmdline_args.display_name
    launch_mode = cmdline_args.launch_mode
    migrate_data.verbose_flag = cmdline_args.verbose_flag
    migrate_data.yes_flag = cmdline_args.yes_flag
    #
    # collect data
    try:
        #
        # oci configuration
        oci_config = migrate_tools.get_oci_config()
        _logger.debug('Found oci config file')
        #
        # compartment data for tenancy
        tenancy = oci_config['tenancy']
        _logger.debug('Tenancy: %s', tenancy)
        compartment_dict = oci_cli_tools.get_tenancy_data(tenancy)
        #
        # object storage namespace
        os_namespace = oci_cli_tools.get_os_namespace()
        console_msg(msg='Object storage namespace: %s' % os_namespace)
        #
        # compartment ocid
        compartment_id = oci_cli_tools.find_compartment_id(
            compartment, compartment_dict)
        #
        # object storage exist and data
        object_storage_data = oci_cli_tools.bucket_exists(bucket)
        console_msg(msg='Object storage %s present.' % bucket)
        #
        # object present in object storage
        if oci_cli_tools.object_exists(object_storage_data, object_name):
            _logger.debug('Object %s present in object_storage %s',
                          object_name, bucket)
        else:
            raise OciMigrateException(
                'Object %s does not exist in the  object '
                'storage %s.' % (object_name, bucket))
        #
        # display name present
        if oci_cli_tools.display_name_exists(display_name, compartment_id):
            raise OciMigrateException('Image with name %s already exists.' %
                                      display_name)
        _logger.debug('%s does not exist', display_name)
    except Exception as e:
        exit_with_msg('Error while importing %s data: %s' %
                      (object_name, str(e)))
    #
    # Ask for confirmation to proceed with upload.
    if not read_yn('\n  Import %s to %s as %s' %
                   (object_name, compartment, display_name),
                   waitenter=True,
                   suppose_yes=migrate_data.yes_flag):
        exit_with_msg('Exiting.\n')
    #
    # Start the import.
    try:
        _ = oci_cli_tools.import_image(object_name, display_name,
                                       compartment_id, os_namespace, bucket,
                                       launch_mode)
    except Exception as e:
        exit_with_msg('Failed to import %s: %s' % (object_name, str(e)))
    #
    # Follow up the import.
    finished = False
    _, nb_columns = terminal_dimension()
    import_progress = ProgressBar(
        nb_columns, 0.2, progress_chars=['importing %s' % display_name])
    import_progress.start()
    try:
        while not finished:
            if oci_cli_tools.get_lifecycle_state(display_name, compartment_id) \
                    == 'AVAILABLE':
                finished = True
    except Exception as e:
        _logger.error('Failed to follow up on the import of %s, giving up: %s',
                      display_name, str(e))

    if system_tools.is_thread_running(import_progress):
        import_progress.stop()
    console_msg(msg='Done')
    return 0