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
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))
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
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)
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)
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
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
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
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
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
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
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
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
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
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
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
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()
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