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()
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
Exemple #3
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
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

    Returns
    -------
Exemple #5
0
import sys

from oci_utils.migrate import ProgressBar
from oci_utils.migrate import console_msg
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 oci_cli_tools
from oci_utils.migrate import read_yn
from oci_utils.migrate import system_tools
from oci_utils.migrate import terminal_dimension
from oci_utils.migrate.exception import OciMigrateException
from oci_utils.migrate.migrate_tools import get_config_data as get_config_data

if sys.version_info.major < 3:
    exit_with_msg('Python version 3 is a requirement to run this utility.')

_logger = logging.getLogger('oci-utils.import_ci')


def parse_args():
    """
    Parse the command line arguments and return an object representing the
    command
    line as returned by the argparse's parse-args().
    arguments:
    -i|--image-name <image name>; mandatory.
    -b|--bucket-name <bucket name>; mandatory.
    -c|--compartment-name <compartment name>; mandatory.
    -l|--launch-mode [PARAVIRTUALIZED|EMULATED|NATIVE]; optional, the default
         is PARAVIRTUALIZED.