def check_cd_config(): """ This function checks for any extended 64K block in CD. If it is available it will extract the contents for the block. Loop mount the image for reading configuration parameters. """ inputiso = '/dev/sr0' outputtgz = '/tmp/cdconf.tgz' mode = os.stat(inputiso).st_mode if stat.S_ISBLK(mode): filesize = get_file_size(inputiso) skip = filesize / 2048 - 32 ironic_utils.dd(inputiso, outputtgz, 'bs=2k', 'skip=%d' % skip) # Check if tgz file is valid. try: utils.execute("/usr/bin/gzip", '-t', outputtgz) except processutils.ProcessExecutionError as err: if 'not in gzip format' in err.stderr: LOG.info('File is not gzip format skipping!!') sys.exit() LOG.info('Configuration file in gzip format proceeding for extraction') tar = tarfile.open(outputtgz) tar.extractall('/tmp/floppy') tar.close() dir_list = os.listdir('/tmp/floppy') for item in dir_list: if item.find('.img') != -1: os.mkdir('/tmp/floppy/mnt') utils.execute("mount", '-o', 'loop', '/tmp/floppy/%s' % item, '/tmp/floppy/mnt') time.sleep(1)
def destroy_disk_metadata(dev, node_uuid): """Destroy metadata structures on node's disk. Ensure that node's disk appears to be blank without zeroing the entire drive. To do this we will zero the first 18KiB to clear MBR / GPT data and the last 18KiB to clear GPT and other metadata like LVM, veritas, MDADM, DMRAID, etc. """ # NOTE(NobodyCam): This is needed to work around bug: # https://bugs.launchpad.net/ironic/+bug/1317647 LOG.debug("Start destroy disk metadata for node %(node)s.", {'node': node_uuid}) try: utils.dd('/dev/zero', dev, 'bs=512', 'count=36') except processutils.ProcessExecutionError as err: with excutils.save_and_reraise_exception(): LOG.error( _LE("Failed to erase beginning of disk for node " "%(node)s. Command: %(command)s. Error: %(error)s."), { 'node': node_uuid, 'command': err.cmd, 'error': err.stderr }) # now wipe the end of the disk. # get end of disk seek value try: block_sz = get_dev_block_size(dev) except processutils.ProcessExecutionError as err: with excutils.save_and_reraise_exception(): LOG.error( _LE("Failed to get disk block count for node %(node)s. " "Command: %(command)s. Error: %(error)s."), { 'node': node_uuid, 'command': err.cmd, 'error': err.stderr }) else: seek_value = block_sz - 36 try: utils.dd('/dev/zero', dev, 'bs=512', 'count=36', 'seek=%d' % seek_value) except processutils.ProcessExecutionError as err: with excutils.save_and_reraise_exception(): LOG.error( _LE("Failed to erase the end of the disk on node " "%(node)s. Command: %(command)s. " "Error: %(error)s."), { 'node': node_uuid, 'command': err.cmd, 'error': err.stderr }) LOG.info( _LI("Disk metadata on %(dev)s successfully destroyed for node " "%(node)s"), { 'dev': dev, 'node': node_uuid })
def dd(src, dst, conv_flags=None): """Execute dd from src to dst.""" if conv_flags: extra_args = ['conv=%s' % conv_flags] else: extra_args = [] utils.dd(src, dst, 'bs=%s' % CONF.disk_utils.dd_block_size, 'oflag=direct', *extra_args)
def destroy_disk_metadata(dev, node_uuid): """Destroy metadata structures on node's disk. Ensure that node's disk appears to be blank without zeroing the entire drive. To do this we will zero the first 18KiB to clear MBR / GPT data and the last 18KiB to clear GPT and other metadata like LVM, veritas, MDADM, DMRAID, etc. """ # NOTE(NobodyCam): This is needed to work around bug: # https://bugs.launchpad.net/ironic/+bug/1317647 LOG.debug("Start destroy disk metadata for node %(node)s.", {'node': node_uuid}) try: utils.dd('/dev/zero', dev, 'bs=512', 'count=36') except processutils.ProcessExecutionError as err: with excutils.save_and_reraise_exception(): LOG.error(_LE("Failed to erase beginning of disk for node " "%(node)s. Command: %(command)s. Error: %(error)s."), {'node': node_uuid, 'command': err.cmd, 'error': err.stderr}) # now wipe the end of the disk. # get end of disk seek value try: block_sz = get_dev_block_size(dev) except processutils.ProcessExecutionError as err: with excutils.save_and_reraise_exception(): LOG.error(_LE("Failed to get disk block count for node %(node)s. " "Command: %(command)s. Error: %(error)s."), {'node': node_uuid, 'command': err.cmd, 'error': err.stderr}) else: seek_value = block_sz - 36 try: utils.dd('/dev/zero', dev, 'bs=512', 'count=36', 'seek=%d' % seek_value) except processutils.ProcessExecutionError as err: with excutils.save_and_reraise_exception(): LOG.error(_LE("Failed to erase the end of the disk on node " "%(node)s. Command: %(command)s. " "Error: %(error)s."), {'node': node_uuid, 'command': err.cmd, 'error': err.stderr}) LOG.info(_LI("Disk metadata on %(dev)s successfully destroyed for node " "%(node)s"), {'dev': dev, 'node': node_uuid})
def _append_floppy_to_cd(bootable_iso_filename, floppy_image_filename): """ Quanta HW cannot attach 2 Virtual media at the moment. Preparing CD which has floppy content at the end of it as 64K block tar file. """ boot_iso_full_path = CONF.remote_image_share_root + bootable_iso_filename floppy_image_full_path = CONF.remote_image_share_root + floppy_image_filename tar_file_path = CONF.remote_image_share_root + floppy_image_filename + '.tar.gz' # Prepare a temporary Tar file tar = tarfile.open(tar_file_path, "w:gz") tar.add(floppy_image_full_path, arcname=os.path.basename(floppy_image_full_path)) tar.close() # Using dd append Tar to iso and remove Tar file ironic_utils.dd(tar_file_path, boot_iso_full_path, 'bs=64k', 'conv=notrunc,sync', 'oflag=append') os.remove(tar_file_path)
def dd(src, dst): """Execute dd from src to dst.""" utils.dd(src, dst, 'bs=%s' % CONF.disk_utils.dd_block_size, 'oflag=direct')
def create_vfat_image(output_file, files_info=None, parameters=None, parameters_file='parameters.txt', fs_size_kib=100): """Creates the fat fs image on the desired file. This method copies the given files to a root directory (optional), writes the parameters specified to the parameters file within the root directory (optional), and then creates a vfat image of the root directory. :param output_file: The path to the file where the fat fs image needs to be created. :param files_info: A dict containing absolute path of file to be copied -> relative path within the vfat image. For example:: { '/absolute/path/to/file' -> 'relative/path/within/root' ... } :param parameters: A dict containing key-value pairs of parameters. :param parameters_file: The filename for the parameters file. :param fs_size_kib: size of the vfat filesystem in KiB. :raises: ImageCreationFailed, if image creation failed while doing any of filesystem manipulation activities like creating dirs, mounting, creating filesystem, copying files, etc. """ try: ironic_utils.dd('/dev/zero', output_file, 'count=1', "bs=%dKiB" % fs_size_kib) except processutils.ProcessExecutionError as e: raise exception.ImageCreationFailed(image_type='vfat', error=e) with utils.tempdir() as tmpdir: try: # The label helps ramdisks to find the partition containing # the parameters (by using /dev/disk/by-label/ir-vfd-dev). # NOTE: FAT filesystem label can be up to 11 characters long. ironic_utils.mkfs('vfat', output_file, label="ir-vfd-dev") utils.mount(output_file, tmpdir, '-o', 'umask=0') except processutils.ProcessExecutionError as e: raise exception.ImageCreationFailed(image_type='vfat', error=e) try: if files_info: _create_root_fs(tmpdir, files_info) if parameters: parameters_file = os.path.join(tmpdir, parameters_file) params_list = [ '%(key)s=%(val)s' % { 'key': k, 'val': v } for k, v in parameters.items() ] file_contents = '\n'.join(params_list) utils.write_to_file(parameters_file, file_contents) except Exception as e: LOG.exception("vfat image creation failed. Error: %s", e) raise exception.ImageCreationFailed(image_type='vfat', error=e) finally: try: utils.umount(tmpdir) except processutils.ProcessExecutionError as e: raise exception.ImageCreationFailed(image_type='vfat', error=e)
def create_vfat_image(output_file, files_info=None, parameters=None, parameters_file='parameters.txt', fs_size_kib=100): """Creates the fat fs image on the desired file. This method copies the given files to a root directory (optional), writes the parameters specified to the parameters file within the root directory (optional), and then creates a vfat image of the root directory. :param output_file: The path to the file where the fat fs image needs to be created. :param files_info: A dict containing absolute path of file to be copied -> relative path within the vfat image. For example, { '/absolute/path/to/file' -> 'relative/path/within/root' ... } :param parameters: A dict containing key-value pairs of parameters. :param parameters_file: The filename for the parameters file. :param fs_size_kib: size of the vfat filesystem in KiB. :raises: ImageCreationFailed, if image creation failed while doing any of filesystem manipulation activities like creating dirs, mounting, creating filesystem, copying files, etc. """ try: ironic_utils.dd('/dev/zero', output_file, 'count=1', "bs=%dKiB" % fs_size_kib) except processutils.ProcessExecutionError as e: raise exception.ImageCreationFailed(image_type='vfat', error=e) with utils.tempdir() as tmpdir: try: # The label helps ramdisks to find the partition containing # the parameters (by using /dev/disk/by-label/ir-vfd-dev). # NOTE: FAT filesystem label can be up to 11 characters long. ironic_utils.mkfs('vfat', output_file, label="ir-vfd-dev") utils.mount(output_file, tmpdir, '-o', 'umask=0') except processutils.ProcessExecutionError as e: raise exception.ImageCreationFailed(image_type='vfat', error=e) try: if files_info: _create_root_fs(tmpdir, files_info) if parameters: parameters_file = os.path.join(tmpdir, parameters_file) params_list = ['%(key)s=%(val)s' % {'key': k, 'val': v} for k, v in parameters.items()] file_contents = '\n'.join(params_list) utils.write_to_file(parameters_file, file_contents) except Exception as e: LOG.exception(_LE("vfat image creation failed. Error: %s"), e) raise exception.ImageCreationFailed(image_type='vfat', error=e) finally: try: utils.umount(tmpdir) except processutils.ProcessExecutionError as e: raise exception.ImageCreationFailed(image_type='vfat', error=e)
def dd(src, dst): """Execute dd from src to dst.""" utils.dd(src, dst, 'bs=%s' % CONF.disk_utils.dd_block_size, 'oflag=direct', 'conv=sparse')