Beispiel #1
0
def get_config_data(key):
    """
    Get a configuration definition.

    Parameters:
    ----------
    key: str
        Key from the configuration data if not None, full configuration
        otherwise.

    Return:
       The configuration data.
    """
    _logger.debug('__ Get config data: %s' % key)
    try:
        with OciMigrateConfParam(migrate_data.oci_migrate_conf_file,
                                 key) as config:
            return config.get_values()
    except FileNotFoundError as fnf:
        _logger.debug('File %s not foud: %s, using data structure.' %
                      (migrate_data.oci_migrate_conf_file, str(fnf)))
        if key in migrate_data.oci_image_migrate_config:
            return migrate_data.oci_image_migrate_config[key]
        else:
            raise OciMigrateException('Failed to get data for %s: does '
                                      'not exist' % key)
    except Exception as e:
        raise OciMigrateException('Failed to get data for %s: %s' %
                                  (key, str(e)))
Beispiel #2
0
def run_call_cmd(command):
    """
    Execute an os command which does not return data.

    Parameters
    ----------
        command: list
            The os command and its arguments.

    Returns
    -------
        int: The return value.
    """
    _logger.debug('__ Executing %s' % command)
    assert (len(command) > 0), 'empty command list'
    try:
        return (subprocess.call(command,
                                stderr=subprocess.DEVNULL,
                                stdout=subprocess.DEVNULL))
    except OSError as oserr:
        raise OciMigrateException('OS error encountered while running %s: %s' %
                                  (command, str(oserr)))
    except subprocess.CalledProcessError as e:
        raise OciMigrateException('Error encountered while running %s: %s' %
                                  (command, str(e)))
Beispiel #3
0
def run_popen_cmd(command, valid_return=frozenset([0])):
    """
    Execute an os command and collect stdout and stderr.

    Parameters
    ----------
    command: list
        The os command and its arguments.
    valid_return: frozenset
        A set of valid return codes, default = [0]
    Returns
    -------
        dict: {'output': output,
               'error': error,
               'return_code: return_code}
        raises an exception on failure.
    """
    _logger.debug('__ Executing %s.', command)
    output_dict = dict()
    if exec_exists(command[0]) is not None:
        _logger.debug('running %s', command)
        try:
            ext_process = subprocess.Popen(command,
                                           stdout=subprocess.PIPE,
                                           stderr=subprocess.PIPE)
            output, error = ext_process.communicate()
            return_code = ext_process.returncode
            output_dict['output'] = output
            output_dict['error'] = error
            output_dict['return_code'] = return_code
            #if return_code != 0:
            #    if bool(error):
            #        _logger.debug('Error occurred while running %s: %s - %s',
            #                      command, return_code, error.decode('utf-8'), exc_info=True)
            #    raise OciMigrateException('Error encountered while running %s: %s - %s'
            #                              % (command, return_code, error.decode('utf-8')))
            if not bool(output):
                _logger.debug('%s did not return output.', command)
            if bool(error):
                # not necessarily fatal
                _logger.debug('%s returned message %s.', command,
                              error.decode('utf-8'))
            _logger.debug('%s returned code %s', command, str(return_code))
            if return_code not in valid_return:
                raise OciMigrateException(
                    'Error encountered while running %s: %s - %s' %
                    (command, return_code, error.decode('utf-8')))
            return output_dict
        except OSError as os_error:
            raise OciMigrateException(
                'OS error encountered while running %s:' %
                command) from os_error
        except Exception as e:
            raise OciMigrateException('Error encountered while running %s:' %
                                      command) from e
    else:
        _logger.critical('   %s not found.', command[0])
        raise OciMigrateException('%s does not exist' % command[0])
Beispiel #4
0
def enter_chroot(newroot):
    """
    Execute the chroot command.

    Parameters
    ----------
        newroot: str
            Full path of new root directory.

    Returns
    -------
        file descriptor, str, str: The file descriptor of the current root on
        success, path to restore, current working dir;
        raises an exception on failure.
    """
    _logger.debug('__ Entering chroot jail at %s.' % newroot)
    root2return = -1
    current_dir = ''
    try:
        #
        # current working directory
        current_dir = os.getcwd()
        #
        # change root
        root2return = os.open('/', os.O_RDONLY)
        os.chdir(newroot)
        os.chroot(newroot)
        _logger.debug('Changed root to %s.' % newroot)
    except Exception as e:
        _logger.error('  Failed to change root to %s: %s' % (newroot, str(e)))
        #
        # need to return environment.
        if root2return > 0:
            os.fchdir(root2return)
            os.chroot('.')
            os.close(root2return)
        raise OciMigrateException('Failed to change root to %s: %s' %
                                  (newroot, str(e)))
    try:
        #
        # adjust PATH to make sure.
        currentpath = os.environ['PATH']
        newpath = currentpath.replace('/bin', '')\
            .replace('/usr/bin', '')\
            .replace('/sbin', '')\
            .replace('/usr/sbin', '')\
            .replace('/usr/local/sbin', '')\
            .replace('::', ':') \
            + ':/root/bin:/bin:/usr/bin:/usr/sbin:/usr/local/sbin:/sbin'
        os.environ['PATH'] = newpath
        _logger.debug('Set path to %s' % newpath)
        return root2return, currentpath, current_dir
    except Exception as e:
        _logger.error('  Failed to set path to %s: %s' % (newpath, str(e)))
        raise OciMigrateException('Failed to set path to %s: %s' %
                                  (newpath, str(e)))
Beispiel #5
0
def mount_imgfn(imgname):
    """
    Link vm image with an nbd device.

    Parameters
    ----------
    imgname: str
        Full path of the image file.

    Returns
    -------
        str: Device name on success, raises an exception otherwise.
    """
    #
    # create nbd devices
    _logger.debug('__ Running mount image file %s.' % imgname)
    result_msg(msg='Load nbd')
    if not system_tools.create_nbd():
        raise OciMigrateException('Failed ot load nbd module')
    else:
        _logger.debug('nbd module loaded')
    #
    # find free nbd device
    result_msg(msg='Find free nbd device')
    devpath = system_tools.get_free_nbd()
    _logger.debug('Device %s is free.' % devpath)
    #
    # link img with first free nbd device
    result_msg(msg='Mount image %s' % imgname, result=True)
    _, nbcols = terminal_dimension()
    try:
        mountwait = ProgressBar(nbcols, 0.2, progress_chars=['mounting image'])
        mountwait.start()
        qemucmd = ['-c', devpath, imgname]
        pause_msg(qemucmd)
        qemunbd_ret = system_tools.exec_qemunbd(qemucmd)
        if qemunbd_ret == 0:
            time.sleep(5)
            _logger.debug('qemu-nbd %s succeeded' % qemucmd)
            return devpath
        else:
            _logger.critical('\n   Failed to create nbd devices: %d' %
                             qemunbd_ret)
            raise Exception('Failed to create nbd devices: %d' % qemunbd_ret)
    except Exception as e:
        _logger.critical('\n   Something wrong with creating nbd devices: %s' %
                         str(e))
        raise OciMigrateException('Unable to create nbd devices: %s' % str(e))
    finally:
        if system_tools.is_thread_running(mountwait):
            mountwait.stop()
Beispiel #6
0
    def __init__(self, filename):
        """
        Initialisation of the vmdk header analysis.

        Parameters
        ----------
        filename: str
            Full path of the vmdk image file.
        """
        super(VmdkHead, self).__init__(filename)
        _logger.debug('VMDK header size: %d bytes' % self.head_size)

        try:
            with open(self._fn, 'rb') as f:
                head_bin = f.read(self.head_size)
                _logger.debug('%s header successfully read' % self._fn)
        except Exception as e:
            _logger.critical('   Failed to read header of %s: %s' %
                             (self._fn, str(e)))
            raise OciMigrateException('Failed to read the header of %s: %s' %
                                      (self._fn, str(e)))

        vmdkheader = struct.unpack(VmdkHead.vmdkhead_fmt, head_bin)

        try:
            with open(self._fn, 'rb') as f:
                f.seek(512)
                head_descr = [
                    it for it in f.read(1024).decode('utf-8').splitlines()
                    if '=' in it
                ]
        except Exception as e:
            _logger.critical('   Failed to read description of %s: %s' %
                             (self._fn, str(e)))
            raise OciMigrateException(
                'Failed to read the description  of %s: %s' %
                (self._fn, str(e)))

        self.stat = os.stat(self._fn)
        self.img_tag = os.path.splitext(os.path.split(self._fn)[1])[0]
        self.vmdkhead_dict = dict(
            (name[2], vmdkheader[i])
            for i, name in enumerate(VmdkHead.header0_structure))
        self.vmdkdesc_dict = dict(
            [re.sub(r'"', '', kv).split('=') for kv in head_descr])
        self.img_header = dict()
        self.img_header['head'] = self.vmdkhead_dict
        self.img_header['desc'] = self.vmdkdesc_dict
        migrate_tools.result_msg(msg='Got image %s header' % filename,
                                 result=False)
Beispiel #7
0
def get_package_mgr_tool():
    """
    Find out which package to use for package manipulation (yum or dnf) and
    define the essential parameters.

    Returns
    -------
        dict: dictionary with method and command parameters.
    """
    #
    # look for package install tool.

    package_mgr_dict = dict()
    if bool(system_tools.exec_exists('dnf')):
        _logger.debug('Upgrade using dnf')
        package_mgr_dict['pkg_mgr'] = 'dnf'
        package_mgr_dict['package_available'] = ['--showduplicates', 'search']
        package_mgr_dict['package_remove'] = ['erase', '-y']
        package_mgr_dict['package_install'] = ['install', '-y']
    elif bool(system_tools.exec_exists('yum')):
        _logger.debug('Upgrade using yum')
        package_mgr_dict['pkg_mgr'] = 'yum'
        package_mgr_dict['package_available'] = ['--showduplicates', 'search']
        package_mgr_dict['package_remove'] = ['remove', '-y']
        package_mgr_dict['package_install'] = ['install', '-y']
    else:
        raise OciMigrateException('Failed to find upgrade tool')
    _logger.debug('Package install tool data:\n %s' % package_mgr_dict)
    return package_mgr_dict
Beispiel #8
0
def exec_vgscan(vgscan_args):
    """
    Scan the system for (new) volume groups.

    Parameters
    ----------
        vgscan_args: list
            list of strings, arguments for vgscan
    Returns
    -------
        bool: True on success, raises an exeception on failure.
    """
    cmd = ['vgscan'] + vgscan_args
    _logger.debug('__ Executing %s' % cmd)
    pause_msg(cmd)
    try:
        output = run_popen_cmd(cmd).decode('utf-8')
        _logger.debug('Volume groups scanned:\n%s' % str(output))
        return True
    except Exception as e:
        #
        # vgscan failed
        _logger.critical('   Failed to scan for volume groups: %s' % str(e))
        raise OciMigrateException('Failed to scan for volume groups: %s' %
                                  str(e))
Beispiel #9
0
def exec_lvscan(lvscan_args):
    """
    Scan the system for logical volumes.

    Parameters
    ----------
        lvscan_args: list
            list of strings, arguments for lvscan
    Returns
    -------
        list:  A list of strings, the output of lvscan --verbose on success,
               raises an exeception on failure.
    """
    cmd = ['lvscan'] + lvscan_args
    _logger.debug('__ Running: %s' % cmd)
    pause_msg(cmd)
    try:
        _logger.debug('command: %s' % cmd)
        output = run_popen_cmd(cmd).decode('utf-8')
        _logger.debug('Logical volumes scanned:\n%s' % str(output))
        return output.splitlines()
    except Exception as e:
        #
        # lvscan failed
        _logger.critical('   Failed to scan for logical volumes: %s' % str(e))
        raise OciMigrateException('Failed to scan for logical volume: %s' %
                                  str(e))
Beispiel #10
0
def exec_pvscan(pvscan_args, devname=None):
    """
    Update the lvm cache.

    Parameters
    ----------
        pvscan_args: list
            List of strings, arguments for pvscan
        devname: str
            Device name to scan.

    Returns
    -------
        bool: True on success, raises an exception on failure.
    """
    _logger.debug('__ Running pvscan %s' % pvscan_args)
    cmd = ['pvscan'] + pvscan_args
    if devname is not None:
        cmd.append(devname)
    pause_msg(cmd)
    try:
        _logger.debug('command: %s' % cmd)
        cmdret = run_call_cmd(cmd)
        _logger.debug('Physical volumes scanned on %s: %d' % (devname, cmdret))
        if cmdret != 0:
            _logger.error('  Physical volume scan failed.')
            raise Exception('Physical volume scan failed.')
        return True
    except Exception as e:
        #
        # pvscan failed
        _logger.critical('   Failed to scan %s for physical volumes: %s' %
                         (devname, str(e)))
        raise OciMigrateException('Failed to scan %s for physical '
                                  'volumes: %s' % (devname, str(e)))
Beispiel #11
0
def mount_pseudo(rootdir):
    """
    Remount proc, sys and dev.

    Parameters
    ----------
    rootdir: str
        The mountpoint of the root partition.

    Returns
    -------
        list: The list of new mountpoints on success, None otherwise.
    """
    pseudodict = {'proc': ['-t', 'proc', 'none', '%s/proc' % rootdir],
                  'dev': ['-o', 'bind', '/dev', '%s/dev' % rootdir],
                  'sys': ['-o', 'bind', '/sys', '%s/sys' % rootdir]}

    pseudomounts = []
    _logger.debug('__ Mounting: %s', pseudodict)
    for dirs, cmd_par in list(pseudodict.items()):
        cmd = ['mount'] + cmd_par
        _logger.debug('Mounting %s', dirs)
        pause_msg(cmd, pause_flag='_OCI_MOUNT')
        try:
            _logger.debug('Command: %s', cmd)
            cmdret = run_call_cmd(cmd)
            _logger.debug('%s : %d', cmd, cmdret)
            if cmdret != 0:
                _logger.error('  Failed to %s', cmd)
                raise Exception('%s Failed: %d' % (cmd, cmdret))
            pseudomounts.append(cmd_par[3])
        except Exception as e:
            _logger.critical('   Failed to %s: %s', cmd, str(e))
            raise OciMigrateException('Failed to %s:' % cmd) from e
    return pseudomounts
Beispiel #12
0
def restore_nameserver():
    """
    Restore nameserver configuration.

    Returns
    -------
    bool: True on success, False otherwise.
    """
    _logger.debug('__ Restore nameserver data.')
    # global resolv_conf_path
    resolvpath = '/etc/resolv.conf'
    try:
        #
        # save used one
        if os.path.isfile(resolvpath):
            if not bool(exec_rename(resolvpath, resolvpath + '_temp_' + migrate_data.current_time)):
                _logger.debug('Failed to rename %s to %s, no harm done.',
                              resolvpath, resolvpath + '_temp_' + migrate_data.current_time)
        else:
            _logger.debug('No %s found.', resolvpath)
        #
        # restore original one
        if os.path.isfile(migrate_data.resolv_conf_path):
            if bool(exec_rename(migrate_data.resolv_conf_path, resolvpath)):
                _logger.debug('Successfully restored %s', resolvpath)
            else:
                _logger.debug('Failed to restore %s.', resolvpath)
                raise OciMigrateException('Failed to restore nameserver config.')
        else:
            _logger.debug('No %s found.', migrate_data.resolv_conf_path)
        return True
    except Exception as e:
        error_msg('Continuing but might cause issues installing cloud-init: %s' % str(e))
        return False
Beispiel #13
0
def read_from_url(url):
    """
    Read from an url

    Parameters
    ----------
    url: str
        The url.

    Returns
    -------
        obj: the contents of the url on success, raises an exception otherwise.
    """
    _logger.debug('__ Read from url %s.', url)
    #
    # to keep the encodings import in place
    _ = dir(encodings.idna)
    try:
        url_ref = requests.get(url)
        if url_ref.status_code != 200:
            raise Exception('url get status: %s while looking for %s' %
                            (str(url_ref.status_code), url))
        url_contents = url_ref.content
        url_ref.close()
        return url_contents
    except Exception as e:
        _logger.warning('Failed to read from %s: %s', url, str(e))
        raise OciMigrateException('Failed to read from %s: %s' % (url, str(e)))
Beispiel #14
0
def leave_chroot(root2return, dir2return):
    """
    Leave a chroot environment and return to another one.

    Parameters
    ----------
    root2return: file descriptor
        The file descriptor of the root to return to.
    dir2return: str
        The original working dir to return to.

    Returns
    -------
        bool: True on success, raises exception on failure.
    """
    _logger.debug('__ Leaving chroot jail.')
    try:
        #
        # leave chroot
        os.fchdir(root2return)
        os.chroot('.')
        os.close(root2return)
        _logger.debug('Left change root environment.')
        #
        # return to working directory
        os.chdir(dir2return)
        return True
    except Exception as e:
        _logger.error('  Failed to return from chroot: %s' % str(e))
        OciMigrateException('Failed to return from chroot: %s' % str(e))
Beispiel #15
0
def upload_image(imgname, bucket_name, ociname):
    """
    Upload the validated and updated image imgname to the OCI object storage
    bucket_name as ociname.

    Parameters
    ----------
    imgname: str
        The on-premise custom image.
    bucket_name: str
        The OCI object storage name.
    ociname:
        The OCI image name.

    Returns
    -------
        bool: True on success, raises an exception otherwise.
    """
    cmd = ['oci', 'os', 'object', 'put',
           '--bucket-name', bucket_name,
           '--file', imgname,
           '--name', ociname,
           '--part-size', '100',
           '--parallel-upload-count', '6']
    _logger.debug('__ Running %s', cmd)
    pause_msg(cmd)
    try:
        upload_result = system_tools.run_popen_cmd(cmd)['output'].decode('utf-8')
        _logger.debug('Successfully uploaded %s to %s as %s: %s.', imgname, bucket_name, ociname, upload_result)
        return True
    except Exception as e:
        _logger.critical('   Failed to upload %s to object storage %s as %s: %s.',
                         imgname, bucket_name, ociname, str(e))
        raise OciMigrateException('Failed to upload %s to object storage %s as %s:'
                                  % (imgname, bucket_name, ociname)) from e
Beispiel #16
0
def get_lifecycle_state(display_name, compartment_id):
    """
    Collect the lifecycle state of on object in a compartment.

    Parameters
    ----------
    display_name: str
        The object name.
    compartment_id: str
        The compartment ocid.

    Returns
    -------
        str: the lifecycle state.
    """
    _logger.debug('__ Retrieving the lifecycle state of %s', display_name)
    cmd = ['oci', 'compute', 'image', 'list',
           '--compartment-id', '%s' % compartment_id,
           '--display-name', '%s' % display_name]
    try:
        object_list = json.loads(system_tools.run_popen_cmd(cmd)['output'].decode('utf-8'))
        for object_x in object_list['data']:
            if object_x['display-name'] == display_name:
                return object_x['lifecycle-state']

            _logger.debug('object %s not found.', display_name)
            return None
    except Exception as e:
        raise OciMigrateException('Failed to collect the compute image list:') from e
Beispiel #17
0
    def __init__(self, filename):
        """
        Initialisation of the qcow2 header analysis.

        Parameters
        ----------
        filename: str
            Full path of the qcow2 image file.
        """
        _logger.debug('qcow2 header size: %d bytes', self.head_size)
        super().__init__(filename)
        head_size = struct.calcsize(Qcow2Head.qcowhead_fmt)

        try:
            with open(self._fn, 'rb') as f:
                head_bin = f.read(head_size)
                _logger.debug('%s header successfully read', self._fn)
        except Exception as e:
            _logger.critical('   Failed to read header of %s: %s', self._fn,
                             str(e))
            raise OciMigrateException('Failed to read the header of %s' %
                                      self._fn) from e

        qcow2header = struct.unpack(Qcow2Head.qcowhead_fmt, head_bin)

        self.stat = os.stat(self._fn)
        self.img_tag = os.path.splitext(os.path.split(self._fn)[1])[0]
        self.qcowhead_dict = dict(
            (name[2], qcow2header[i])
            for i, name in enumerate(Qcow2Head.header2_structure))
        self.img_header = dict()
        self.img_header['head'] = self.qcowhead_dict
        result_msg(msg='Got image %s header' % filename, result=False)
Beispiel #18
0
def exec_search(file_name, rootdir='/', dirnames=False):
    """
    Find the filename in the rootdir tree.

    Parameters
    ----------
    file_name: str
        The filename to look for.
    rootdir: str
        The directory to start from, default is root.
    dirnames: bool
        If True, also consider directory names.

    Returns
    -------
        str: The full path of the filename if found, None otherwise.
    """
    _logger.debug('__ Looking for %s in %s', file_name, rootdir)
    result_msg(msg='Looking for %s in %s, might take a while.' % (file_name, rootdir))
    try:
        for path_name, directories, files in os.walk(rootdir):
            # _logger.debug('%s %s %s', path_name, directories, files)
            if file_name in files:
                _logger.debug('Found %s', os.path.join(rootdir, path_name, file_name))
                return os.path.join(rootdir, path_name, file_name)
            if dirnames and file_name in directories:
                _logger.debug('Found %s as directory.', os.path.join(rootdir, path_name, file_name))
                return os.path.join(rootdir, path_name, file_name)
    except Exception as e:
        _logger.error('  Error while looking for %s: %s', file_name, str(e))
        raise OciMigrateException('Error while looking for %s:' % file_name) from e
    return None
Beispiel #19
0
def read_from_url(url):
    """
    Read from an url

    Parameters
    ----------
    url: str
        The url.

    Returns
    -------
        obj: the contents of the url on success, raises an exception otherwise.
    """
    _logger.debug('__ Read from url %s.', url)
    #
    # to keep the encodings import in place
    _ = dir(encodings.idna)
    try:
        url_request = Request(url=url, headers={'Authorization': 'Bearer Oracle'})
        with urlopen(url_request) as url_ref:
            if url_ref.status != 200:
                raise Exception('url get status: %s while looking for %s' % (str(url_ref.status), url))
            url_contents = url_ref.read()
        return url_contents
    except Exception as e:
        _logger.warning('Failed to read from %s: %s', url, str(e))
        raise OciMigrateException('Failed to read from %s' % url) from e
Beispiel #20
0
 def b10_is_cloud_init_enabled():
     """
     Verify if cloud-init package is enabled after install.
     Returns
     -------
        bool: True on success, False otherwise.
     """
     _logger.debug('__ Is cloud-init enabled.')
     cmd = ['systemctl', 'list-unit-files']
     enabled = False
     try:
         _logger.debug('command: %s', cmd)
         output = system_tools.run_popen_cmd(cmd)['output'].decode(
             'utf-8').splitlines()
         for service in output:
             svc = service.split() if len(service) > 1 else ['a', 'b']
             if 'cloud-init' in svc[0]:
                 _logger.debug('Found service cloud-init: %s', svc)
                 if svc[-1] == 'enabled':
                     _logger.debug('Service cloud-init is enabled.')
                     enabled = True
                     break
         return enabled
     except Exception as e:
         _logger.warning('   Failed to execute systemctl: %s', str(e))
         raise OciMigrateException('\nFailed to execute systemctl: ') from e
Beispiel #21
0
def bucket_exists(bucket_name):
    """
    Verify if bucket_name exits.

    Parameters
    ----------
    bucket_name: str
        The bucket_name.

    Returns
    -------
        dict: The bucket on success, raise an exception otherwise
    """
    cmd = [
        'oci', 'os', 'object', 'list', '--all', '--bucket-name', bucket_name
    ]
    _logger.debug('__ Running %s.', cmd)
    pause_msg(cmd)
    try:
        bucket_result = json.loads(
            system_tools.run_popen_cmd(cmd)['output'].decode('utf-8'))
        _logger.debug('Result: \n%s', bucket_result)
        return bucket_result
    except Exception as e:
        _logger.debug(
            'Bucket %s does not exists or the authorisation is missing: %s.',
            bucket_name, str(e))
        raise OciMigrateException(
            'Bucket %s does not exists or the authorisation is missing:' %
            bucket_name) from e
Beispiel #22
0
def find_compartment_id(compartment, compartment_dict):
    """
    Find the compartment ocid for compartment in the compartment dictinary.

    Parameters
    ----------
    compartment: str
        The compartment name.
    compartment_dict: dict
        The dictionary containing data for all? compartments in this tenancy.

    Returns
    -------
        str: the ocid of the compartment on success, raises an exception
             on failure.
    """
    _logger.debug('__ Looking for the ocid of compartment %s', compartment)
    for _, v in list(compartment_dict.items()):
        for x in v:
            if x['name'] == compartment:
                compartment_data = x
                console_msg(msg='Compartment: %s' % compartment_data['name'])
                compartment_id = compartment_data['id']
                return compartment_id
    raise OciMigrateException('Failed to find the ocid for %s' % compartment)
def collect_image_data(img_object):
    """
    Verify the prerequisites of the image file with respect to the migration
    to the Oracle Cloud Infrastructure.

    Parameters
    ----------
    img_object: Qcow2Head, VmdkHead, TemplateTypeHead..  object
        The image object.

    Returns
    -------
        dict:
            The image data.
    """
    _logger.debug('__ Collect the image data.')
    try:
        res, img_info = img_object.image_data()
    except Exception as e:
        _logger.critical('   Unable to collect or invalid image data: %s'
                         % str(e), exc_info=True)
        raise OciMigrateException('Unable to collect or invalid image data: %s'
                                  % str(e))
    # need to return the img_info object in the end...
    return res, img_info
Beispiel #24
0
def mount_partition(devname, mountpoint=None):
    """
    Create the mountpoint /mnt/<last part of device specification> and mount a
    partition on on this mountpoint.

    Parameters
    ----------
    devname: str
        The full path of the device.
    mountpoint: str
        The mountpoint, will be generated if not provided.

    Returns
    -------
        str: The mounted partition on Success, None otherwise.
    """
    _logger.debug('__ Mount partition %s.', devname)
    #
    # create mountpoint /mnt/<devname> if not specified.
    if mountpoint is None:
        mntpoint = migrate_data.loopback_root + '/' + devname.rsplit('/')[-1]
        _logger.debug('Loopback mountpoint: %s', mntpoint)
        try:
            if system_tools.exec_mkdir(mntpoint):
                _logger.debug('Mountpoint: %s created.', mntpoint)
        except Exception as e:
            _logger.critical('   Failed to create mountpoint %s: %s', mntpoint, str(e))
            raise OciMigrateException('Failed to create mountpoint %s:' % mntpoint) from e
    else:
        mntpoint = mountpoint
    #
    # actual mount
    cmd = ['mount', devname, mntpoint]
    pause_msg(cmd, pause_flag='_OCI_MOUNT')
    _, nbcols = terminal_dimension()
    try:
        mountpart = ProgressBar(nbcols, 0.2,
                                progress_chars=['mount %s' % devname])
        mountpart.start()
        _logger.debug('command: %s', cmd)
        cmdret = system_tools.run_call_cmd(cmd)
        if cmdret == 0:
            _logger.debug('%s mounted on %s.', devname, mntpoint)
            return mntpoint

        raise Exception('Mount %s failed: %d' % (devname, cmdret))
    except Exception as e:
        #
        # mount failed, need to remove mountpoint.
        _logger.critical('   Failed to mount %s, missing driver, filesystem corruption...: %s', devname, str(e))
        if mountpoint is None:
            if system_tools.exec_rmdir(mntpoint):
                _logger.debug('%s removed', mntpoint)
            else:
                _logger.critical('   Failed to remove mountpoint %s', mntpoint)
    finally:
        if system_tools.is_thread_running(mountpart):
            mountpart.stop()

    return None
Beispiel #25
0
def get_oci_config(section='DEFAULT'):
    """
    Read the oci configuration file.

    Parameters
    ----------
    section: str
        The section from the oci configuration file. DEFAULT is the default.
        (todo: add command line option to use other user/sections)

    Returns
    -------
        dict: the contents of the configuration file as a dictionary.
    """
    _logger.debug('__ Reading the %s configuration file.' %
                  get_config_data('ociconfigfile'))
    oci_config_file = get_config_data('ociconfigfile')
    _logger.debug('oci config file path: %s' % oci_config_file)
    if oci_config_file.startswith('~/'):
        oci_config_file = os.path.expanduser('~') + oci_config_file[1:]
        _logger.debug('oci config file expected at %s' % oci_config_file)
    oci_cli_configer = ConfigParser()
    try:
        rf = oci_cli_configer.read(oci_config_file)
        sectiondata = dict(oci_cli_configer.items(section))
        _logger.debug('OCI configuration: %s' % sectiondata)
        return sectiondata
    except Exception as e:
        _logger.error('  Failed to read OCI configuration %s: %s.' %
                      (get_config_data('ociconfigfile'), str(e)))
        raise OciMigrateException('Failed to read OCI configuration %s: %s.' %
                                  (get_config_data('ociconfigfile'), str(e)))
Beispiel #26
0
    def image_data(self):
        """
        Collect data about contents of the image file.

        Returns
        -------
            bool: True on success, False otherwise;
            dict: The image data.
        """
        _logger.debug('Image data: %s' % self._fn)
        #
        # initialise the dictionary for the image data
        self._img_info['img_name'] = self._fn
        self._img_info['img_type'] = 'VMDK'
        self._img_info['img_header'] = self.img_header
        self._img_info['img_size'] = self.image_size()

        #
        # mount the image using the nbd
        try:
            result = self.handle_image()
        except Exception as e:
            _logger.critical('   Error %s' % str(e))
            raise OciMigrateException(str(e))
        return result, self._img_info
Beispiel #27
0
def exec_rename(some_name, to_name=None):
    """
    Renames a file, symbolic link or directory to path/bck_filename_current_time.

    Parameters
    ----------
    some_name: str
        Full path of the original file.
    to_name: str
        Full path of the destination file, if specified, using default otherwise.

    Returns
    -------
        str: the path of the renamed file on success, None otherwise.
    """
    if not bool(to_name):
        to_name = generate_backup_name(some_name)
    _logger.debug('__ Rename %s to %s' % (some_name, to_name))
    #
    try:
        #
        # delete to_ if already exists
        #
        # if file, symlink or directory
        if os.path.exists(to_name):
            _logger.debug('%s already exists' % to_name)
            if os.path.isfile(to_name):
                os.remove(to_name)
            elif os.path.isdir(to_name):
                os.rmdir(to_name)
            elif os.path.islink(to_name):
                if os.unlink(to_name):
                    _logger.debug('Removed symbolic link %s' % to_name)
                else:
                    _logger.error('   Failed to remove symbolic link %s' %
                                  to_name)
            else:
                _logger.error('   Failed to remove %s.' % to_name)
        else:
            _logger.debug('%s does not exists' % to_name)
        #
        # rename
        if os.path.exists(some_name) or os.path.islink(some_name):
            _logger.debug('%s exists and is a file or symbolic link.' %
                          some_name)
            os.rename(some_name, to_name)
            _logger.debug('Renamed %s to %s.' % (some_name, to_name))
            return to_name
        else:
            _logger.debug('   %s does not exists' % some_name)

    except Exception as e:
        _logger.error('   Failed to rename %s to %s: %s' %
                      (some_name, to_name, str(e)))
        raise OciMigrateException('Failed to rename %s to %s: %s' %
                                  (some_name, to_name, str(e)))
    return None
Beispiel #28
0
    def __init__(self, filename):
        """
        Initialisation of the templatetype header analysis.

        Parameters
        ----------
        filename: str
            Full path of the template_type image file.
        """
        super(TemplateTypeHead, self).__init__(filename)
        _logger.debug('templatetype header size: %d bytes' % self.head_size)

        try:
            with open(self._fn, 'rb') as f:
                head_bin = f.read(self.head_size)
                _logger.debug('%s header successfully read' % self._fn)
        except Exception as e:
            _logger.critical('   Failed to read header of %s: %s'
                             % (self._fn, str(e)))
            raise OciMigrateException('Failed to read the header of %s: %s'
                                      % (self._fn, str(e)))

        templatetypeheader = struct.unpack(TemplateTypeHead.templatetypehead_fmt, head_bin)

        self.stat = os.stat(self._fn)
        self.img_tag = os.path.splitext(os.path.split(self._fn)[1])[0]
        self.templatehead_dict = dict((name[2], templatetypeheader[i])
                                  for i, name
                                  in enumerate(TemplateTypeHead.header2_structure))
        self.img_header = dict()
        self.img_header['head'] = self.templatehead_dict
        migrate_tools.result_msg(msg='Got image %s header' % filename,
                                 result=False)
        #
        # mount the image using the nbd
        try:
            self.devicename = self.mount_img()
            _logger.debug('Image data %s' % self.devicename)
            migrate_tools.result_msg(msg='Mounted %s' % self.devicename,
                                     result=False)
            deviceinfo = self.handle_image()
        except Exception as e:
            _logger.critical('   Error %s' % str(e))
            raise OciMigrateException(str(e))
Beispiel #29
0
def run_popen_cmd(command):
    """
    Execute an os command and collect stdout and stderr.

    Parameters
    ----------
    command: list
        The os command and its arguments.

    Returns
    -------
        <type>: The output of the command on success, raises an exception on
        failure.
    """
    _logger.debug('__ Executing %s.' % command)
    if exec_exists(command[0]) is not None:
        _logger.debug('running %s' % command)
        try:
            ext_process = subprocess.Popen(command,
                                           stdout=subprocess.PIPE,
                                           stderr=subprocess.PIPE)
            output, error = ext_process.communicate()
            retcode = ext_process.returncode
            if retcode != 0:
                if error:
                    _logger.debug('Error occured while running %s: %s - %s' %
                                  (command, retcode, error.decode('utf-8')),
                                  exc_info=True)
                raise OciMigrateException(
                    'Error encountered while running %s: '
                    '%s - %s' % (command, retcode, error.decode('utf-8')))
            # _logger.debug('output from %s: %s' % (command, output))
            if output:
                return output
        except OSError as oserr:
            raise OciMigrateException('OS error encountered while '
                                      'running %s: %s' % (command, str(oserr)))
        except Exception as e:
            raise OciMigrateException(
                'Error encountered while running %s: %s' % (command, str(e)))
    else:
        _logger.critical('   %s not found.' % command[0])
        raise OciMigrateException('%s does not exist' % command[0])
Beispiel #30
0
def unmount_imgfn(devname):
    """
    Unlink a device.

    Parameters
    ----------
    devname: str
        The device name

    Returns
    -------
        bool: True on succes, raise an exception otherwise.
    """
    _logger.debug('__ Unmount %s' % devname)
    try:
        #
        # release device
        qemucmd = ['-d', devname]
        pause_msg(qemucmd)
        qemunbd_ret = system_tools.exec_qemunbd(qemucmd)
        if qemunbd_ret == 0:
            _logger.debug('qemu-nbd %s succeeded: %d' % (qemucmd, qemunbd_ret))
        else:
            raise Exception('%s returned %d' % (qemucmd, qemunbd_ret))
        #
        # clear lvm cache, if necessary.
        if system_tools.exec_pvscan(['--cache']):
            _logger.debug('lvm cache updated')
        else:
            _logger.error('  Failed to clear LVM cache.')
            raise OciMigrateException('Failed to clear LVM cache.')
        #
        # remove nbd module
        if not system_tools.rm_nbd():
            raise OciMigrateException('Failed to remove nbd module.')
        else:
            _logger.debug('Successfully removed nbd module.')
    except Exception as e:
        _logger.critical('   Something wrong with removing nbd devices: %s' %
                         str(e))
        raise OciMigrateException('\nSomething wrong with removing nbd '
                                  'devices: %s' % str(e))
    return True