def cache(self, fetch_func, filename, size=None, *args, **kwargs): """Creates image from template. Ensures that template and image not already exists. Ensures that base directory exists. Synchronizes on template fetching. :fetch_func: Function that creates the base image Should accept `target` argument. :filename: Name of the file in the image directory :size: Size of created image in bytes (optional) """ @utils.synchronized(filename, external=True, lock_path=self.lock_path) def fetch_func_sync(target, *args, **kwargs): # The image may have been fetched while a subsequent # call was waiting to obtain the lock. if not os.path.exists(target): fetch_func(target=target, *args, **kwargs) base_dir = os.path.join(CONF.instances_path, CONF.image_cache_subdirectory_name) if not os.path.exists(base_dir): fileutils.ensure_tree(base_dir) base = os.path.join(base_dir, filename) if not self.check_image_exists() or not os.path.exists(base): self.create_image(fetch_func_sync, base, size, *args, **kwargs) if (size and self.preallocate and self._can_fallocate() and os.access(self.path, os.W_OK)): utils.execute('fallocate', '-n', '-l', size, self.path)
def test_create_configdrive_iso(self): CONF.set_override('config_drive_format', 'iso9660') imagefile = None try: self.mox.StubOutWithMock(utils, 'execute') utils.execute('genisoimage', '-o', mox.IgnoreArg(), '-ldots', '-allow-lowercase', '-allow-multidot', '-l', '-publisher', mox.IgnoreArg(), '-quiet', '-J', '-r', '-V', 'config-2', mox.IgnoreArg(), attempts=1, run_as_root=False).AndReturn(None) self.mox.ReplayAll() with configdrive.ConfigDriveBuilder(FakeInstanceMD()) as c: (fd, imagefile) = tempfile.mkstemp(prefix='cd_iso_') os.close(fd) c.make_drive(imagefile) finally: if imagefile: fileutils.delete_if_exists(imagefile)
def _make_vfat(self, path, tmpdir): # NOTE(mikal): This is a little horrible, but I couldn't find an # equivalent to genisoimage for vfat filesystems. with open(path, 'wb') as f: f.truncate(CONFIGDRIVESIZE_BYTES) utils.mkfs('vfat', path, label='config-2') with utils.tempdir() as mountdir: mounted = False try: _, err = utils.trycmd('mount', '-o', 'loop,uid=%d,gid=%d' % (os.getuid(), os.getgid()), path, mountdir, run_as_root=True) if err: raise exception.ConfigDriveMountFailed(operation='mount', error=err) mounted = True # NOTE(mikal): I can't just use shutils.copytree here, # because the destination directory already # exists. This is annoying. for ent in os.listdir(tmpdir): shutil.copytree(os.path.join(tmpdir, ent), os.path.join(mountdir, ent)) finally: if mounted: utils.execute('umount', mountdir, run_as_root=True)
def unplug_iovisor(self, instance, vif): """Unplug using PLUMgrid IO Visor Driver Delete network device and to their respective connection to the Virtual Domain in PLUMgrid Platform. """ iface_id = vif['id'] dev = self.get_vif_devname(vif) try: utils.execute('ifc_ctl', 'gateway', 'ifdown', dev, 'access_vm', vif['network']['label'] + "_" + iface_id, vif['address'], run_as_root=True) utils.execute('ifc_ctl', 'gateway', 'del_port', dev, run_as_root=True) linux_net.delete_net_dev(dev) except processutils.ProcessExecutionError: LOG.exception(_LE("Failed while unplugging vif"), instance=instance)
def extend(image, size, use_cow=False): """Increase image to size.""" if not can_resize_image(image, size): return utils.execute('qemu-img', 'resize', image, size) # if we can't access the filesystem, we can't do anything more if not is_image_extendable(image, use_cow): return def safe_resize2fs(dev, run_as_root=False, finally_call=lambda: None): try: resize2fs(dev, run_as_root=run_as_root, check_exit_code=[0]) except processutils.ProcessExecutionError as exc: LOG.debug("Resizing the file system with resize2fs " "has failed with error: %s", exc) finally: finally_call() # NOTE(vish): attempts to resize filesystem if use_cow: if CONF.resize_fs_using_block_device: # in case of non-raw disks we can't just resize the image, but # rather the mounted device instead mounter = mount.Mount.instance_for_format( image, None, None, 'qcow2') if mounter.get_dev(): safe_resize2fs(mounter.device, run_as_root=True, finally_call=mounter.unget_dev) else: safe_resize2fs(image)
def plug_iovisor(self, instance, vif): """Plug using PLUMgrid IO Visor Driver Connect a network device to their respective Virtual Domain in PLUMgrid Platform. """ dev = self.get_vif_devname(vif) iface_id = vif['id'] linux_net.create_tap_dev(dev) net_id = vif['network']['id'] tenant_id = instance.project_id try: utils.execute('ifc_ctl', 'gateway', 'add_port', dev, run_as_root=True) utils.execute('ifc_ctl', 'gateway', 'ifup', dev, 'access_vm', vif['network']['label'] + "_" + iface_id, vif['address'], 'pgtag2=%s' % net_id, 'pgtag1=%s' % tenant_id, run_as_root=True) except processutils.ProcessExecutionError: LOG.exception(_LE("Failed while plugging vif"), instance=instance)
def test_extend_qcow_success(self): imgfile = tempfile.NamedTemporaryFile() imgsize = 10 device = "/dev/sdh" use_cow = True self.flags(resize_fs_using_block_device=True) mounter = FakeMount.instance_for_format( imgfile, None, None, 'qcow2') mounter.device = device self.mox.StubOutWithMock(api, 'can_resize_image') self.mox.StubOutWithMock(utils, 'execute') self.mox.StubOutWithMock(api, 'is_image_extendable') self.mox.StubOutWithMock(mounter, 'get_dev') self.mox.StubOutWithMock(mounter, 'unget_dev') self.mox.StubOutWithMock(api, 'resize2fs') self.mox.StubOutWithMock(mount.Mount, 'instance_for_format', use_mock_anything=True) api.can_resize_image(imgfile, imgsize).AndReturn(True) utils.execute('qemu-img', 'resize', imgfile, imgsize) api.is_image_extendable(imgfile, use_cow).AndReturn(True) mount.Mount.instance_for_format( imgfile, None, None, 'qcow2').AndReturn(mounter) mounter.get_dev().AndReturn(True) api.resize2fs(mounter.device, run_as_root=True, check_exit_code=[0]) mounter.unget_dev() self.mox.ReplayAll() api.extend(imgfile, imgsize, use_cow=use_cow)
def test_create_configdrive_vfat(self): CONF.set_override('config_drive_format', 'vfat') imagefile = None try: self.mox.StubOutWithMock(utils, 'mkfs') self.mox.StubOutWithMock(utils, 'execute') self.mox.StubOutWithMock(utils, 'trycmd') utils.mkfs('vfat', mox.IgnoreArg(), label='config-2').AndReturn(None) utils.trycmd('mount', '-o', mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg(), run_as_root=True).AndReturn((None, None)) utils.execute('umount', mox.IgnoreArg(), run_as_root=True).AndReturn(None) self.mox.ReplayAll() with configdrive.ConfigDriveBuilder(FakeInstanceMD()) as c: (fd, imagefile) = tempfile.mkstemp(prefix='cd_vfat_') os.close(fd) c.make_drive(imagefile) # NOTE(mikal): we can't check for a VFAT output here because the # filesystem creation stuff has been mocked out because it # requires root permissions finally: if imagefile: fileutils.delete_if_exists(imagefile)
def teardown_container(container_dir, container_root_device=None): """Teardown the container rootfs mounting once it is spawned. It will umount the container that is mounted, and delete any linked devices. """ try: img = _DiskImage(image=None, mount_dir=container_dir) img.teardown() # Make sure container_root_device is released when teardown container. if container_root_device: if 'loop' in container_root_device: LOG.debug("Release loop device %s", container_root_device) utils.execute('losetup', '--detach', container_root_device, run_as_root=True, attempts=3) else: LOG.debug('Release nbd device %s', container_root_device) utils.execute('qemu-nbd', '-d', container_root_device, run_as_root=True) except Exception: LOG.exception(_LE('Failed to teardown container filesystem'))
def extend(image, size, use_cow=False): """Increase image to size.""" if not can_resize_image(image, size): return utils.execute('qemu-img', 'resize', image, size) # if we can't access the filesystem, we can't do anything more if not is_image_extendable(image, use_cow): return def safe_resize2fs(dev, run_as_root=False, finally_call=lambda: None): try: resize2fs(dev, run_as_root=run_as_root, check_exit_code=[0]) except processutils.ProcessExecutionError as exc: LOG.debug( "Resizing the file system with resize2fs " "has failed with error: %s", exc) finally: finally_call() # NOTE(vish): attempts to resize filesystem if use_cow: if CONF.resize_fs_using_block_device: # in case of non-raw disks we can't just resize the image, but # rather the mounted device instead mounter = mount.Mount.instance_for_format(image, None, None, 'qcow2') if mounter.get_dev(): safe_resize2fs(mounter.device, run_as_root=True, finally_call=mounter.unget_dev) else: safe_resize2fs(image)
def attach_volume(self, context, **kwargs): """Shadows the device and passes an unencrypted version to the instance. Transparent disk encryption is achieved by mounting the volume via dm-crypt and passing the resulting device to the instance. The instance is unaware of the underlying encryption due to modifying the original symbolic link to refer to the device mounted by dm-crypt. """ key = self._get_key(context).get_encoded() # LUKS uses a passphrase rather than a raw key -- convert to string passphrase = ''.join(hex(x).replace('0x', '') for x in key) try: self._open_volume(passphrase, **kwargs) except processutils.ProcessExecutionError as e: if e.exit_code == 1 and not is_luks(self.dev_path): # the device has never been formatted; format it and try again LOG.info( _LI("%s is not a valid LUKS device;" " formatting device for first use"), self.dev_path) self._format_volume(passphrase, **kwargs) self._open_volume(passphrase, **kwargs) else: raise # modify the original symbolic link to refer to the decrypted device utils.execute('ln', '--symbolic', '--force', '/dev/mapper/%s' % self.dev_name, self.symlink_path, run_as_root=True, check_exit_code=True)
def _setup_spawn_config_drive_mocks(self, use_cdrom): instance_metadata.InstanceMetadata(mox.IgnoreArg(), content=mox.IsA(list), extra_md=mox.IsA(dict)) m = fake.PathUtils.get_instance_dir(mox.IsA(str)) m.AndReturn(self._test_instance_dir) cdb = self._mox.CreateMockAnything() m = configdrive.ConfigDriveBuilder(instance_md=mox.IgnoreArg()) m.AndReturn(cdb) # __enter__ and __exit__ are required by "with" cdb.__enter__().AndReturn(cdb) cdb.make_drive(mox.IsA(str)) cdb.__exit__(None, None, None).AndReturn(None) if not use_cdrom: utils.execute(CONF.hyperv.qemu_img_cmd, 'convert', '-f', 'raw', '-O', 'vpc', mox.IsA(str), mox.IsA(str), attempts=1) fake.PathUtils.remove(mox.IsA(str)) m = vmutils.VMUtils.attach_ide_drive(mox.IsA(str), mox.IsA(str), mox.IsA(int), mox.IsA(int), mox.IsA(str)) m.WithSideEffects(self._add_disk)
def _sign_csr(csr_text, ca_folder): with utils.tempdir() as tmpdir: inbound = os.path.join(tmpdir, 'inbound.csr') outbound = os.path.join(tmpdir, 'outbound.csr') try: with open(inbound, 'w') as csrfile: csrfile.write(csr_text) except IOError: with excutils.save_and_reraise_exception(): LOG.exception(_LE('Failed to write inbound.csr')) LOG.debug('Flags path: %s', ca_folder) start = os.getcwd() # Change working dir to CA fileutils.ensure_tree(ca_folder) os.chdir(ca_folder) utils.execute('openssl', 'ca', '-batch', '-out', outbound, '-config', './openssl.cnf', '-infiles', inbound) out, _err = utils.execute('openssl', 'x509', '-in', outbound, '-serial', '-noout') serial = string.strip(out.rpartition('=')[2]) os.chdir(start) with open(outbound, 'r') as crtfile: return (serial, crtfile.read())
def generate_winrm_x509_cert(user_id, project_id, bits=2048): """Generate a cert for passwordless auth for user in project.""" subject = '/CN=%s-%s' % (project_id, user_id) upn = '%s@localhost' % user_id with utils.tempdir() as tmpdir: keyfile = os.path.abspath(os.path.join(tmpdir, 'temp.key')) conffile = os.path.abspath(os.path.join(tmpdir, 'temp.conf')) _create_x509_openssl_config(conffile, upn) (certificate, _err) = utils.execute('openssl', 'req', '-x509', '-nodes', '-days', '3650', '-config', conffile, '-newkey', 'rsa:%s' % bits, '-outform', 'PEM', '-keyout', keyfile, '-subj', subject, '-extensions', 'v3_req_client') (out, _err) = utils.execute('openssl', 'pkcs12', '-export', '-inkey', keyfile, '-password', 'pass:'******'base64') fingerprint = generate_x509_fingerprint(certificate) return (private_key, certificate, fingerprint)
def attach_volume(self, context, **kwargs): """Shadows the device and passes an unencrypted version to the instance. Transparent disk encryption is achieved by mounting the volume via dm-crypt and passing the resulting device to the instance. The instance is unaware of the underlying encryption due to modifying the original symbolic link to refer to the device mounted by dm-crypt. """ key = self._get_key(context).get_encoded() passphrase = self._get_passphrase(key) self._open_volume(passphrase, **kwargs) # modify the original symbolic link to refer to the decrypted device utils.execute( "ln", "--symbolic", "--force", "/dev/mapper/%s" % self.dev_name, self.symlink_path, run_as_root=True, check_exit_code=True, )
def test_extend_qcow_success(self): imgfile = tempfile.NamedTemporaryFile() imgsize = 10 device = "/dev/sdh" use_cow = True self.flags(resize_fs_using_block_device=True) mounter = FakeMount.instance_for_format(imgfile, None, None, 'qcow2') mounter.device = device self.mox.StubOutWithMock(api, 'can_resize_image') self.mox.StubOutWithMock(utils, 'execute') self.mox.StubOutWithMock(api, 'is_image_extendable') self.mox.StubOutWithMock(mounter, 'get_dev') self.mox.StubOutWithMock(mounter, 'unget_dev') self.mox.StubOutWithMock(api, 'resize2fs') self.mox.StubOutWithMock(mount.Mount, 'instance_for_format', use_mock_anything=True) api.can_resize_image(imgfile, imgsize).AndReturn(True) utils.execute('qemu-img', 'resize', imgfile, imgsize) api.is_image_extendable(imgfile, use_cow).AndReturn(True) mount.Mount.instance_for_format(imgfile, None, None, 'qcow2').AndReturn(mounter) mounter.get_dev().AndReturn(True) api.resize2fs(mounter.device, run_as_root=True, check_exit_code=[0]) mounter.unget_dev() self.mox.ReplayAll() api.extend(imgfile, imgsize, use_cow=use_cow)
def attach_volume(self, context, **kwargs): """Shadows the device and passes an unencrypted version to the instance. Transparent disk encryption is achieved by mounting the volume via dm-crypt and passing the resulting device to the instance. The instance is unaware of the underlying encryption due to modifying the original symbolic link to refer to the device mounted by dm-crypt. """ key = self._get_key(context).get_encoded() # LUKS uses a passphrase rather than a raw key -- convert to string passphrase = ''.join(hex(x).replace('0x', '') for x in key) try: self._open_volume(passphrase, **kwargs) except processutils.ProcessExecutionError as e: if e.exit_code == 1 and not is_luks(self.dev_path): # the device has never been formatted; format it and try again LOG.info(_LI("%s is not a valid LUKS device;" " formatting device for first use"), self.dev_path) self._format_volume(passphrase, **kwargs) self._open_volume(passphrase, **kwargs) else: raise # modify the original symbolic link to refer to the decrypted device utils.execute('ln', '--symbolic', '--force', '/dev/mapper/%s' % self.dev_name, self.symlink_path, run_as_root=True, check_exit_code=True)
def _decrypt_image(self, context, encrypted_filename, encrypted_key, encrypted_iv, decrypted_filename): elevated = context.elevated() try: key = self.cert_rpcapi.decrypt_text(elevated, project_id=context.project_id, text=base64.b64encode(encrypted_key)) except Exception as exc: msg = _('Failed to decrypt private key: %s') % exc raise exception.PatronException(msg) try: iv = self.cert_rpcapi.decrypt_text(elevated, project_id=context.project_id, text=base64.b64encode(encrypted_iv)) except Exception as exc: raise exception.PatronException(_('Failed to decrypt initialization ' 'vector: %s') % exc) try: utils.execute('openssl', 'enc', '-d', '-aes-128-cbc', '-in', '%s' % (encrypted_filename,), '-K', '%s' % (key,), '-iv', '%s' % (iv,), '-out', '%s' % (decrypted_filename,)) except processutils.ProcessExecutionError as exc: raise exception.PatronException(_('Failed to decrypt image file ' '%(image_file)s: %(err)s') % {'image_file': encrypted_filename, 'err': exc.stdout})
def _format_volume(self, passphrase, **kwargs): """Creates a LUKS header on the volume. :param passphrase: the passphrase used to access the volume """ LOG.debug("formatting encrypted volume %s", self.dev_path) # NOTE(joel-coffman): cryptsetup will strip trailing newlines from # input specified on stdin unless --key-file=- is specified. cmd = ["cryptsetup", "--batch-mode", "luksFormat", "--key-file=-"] cipher = kwargs.get("cipher", None) if cipher is not None: cmd.extend(["--cipher", cipher]) key_size = kwargs.get("key_size", None) if key_size is not None: cmd.extend(["--key-size", key_size]) cmd.extend([self.dev_path]) utils.execute(*cmd, process_input=passphrase, check_exit_code=True, run_as_root=True)
def unget_dev(self): if not self.linked: return LOG.debug('Release nbd device %s', self.device) utils.execute('qemu-nbd', '-d', self.device, run_as_root=True) self.linked = False self.device = None
def generate_winrm_x509_cert(user_id, project_id, bits=2048): """Generate a cert for passwordless auth for user in project.""" subject = '/CN=%s-%s' % (project_id, user_id) upn = '%s@localhost' % user_id with utils.tempdir() as tmpdir: keyfile = os.path.abspath(os.path.join(tmpdir, 'temp.key')) conffile = os.path.abspath(os.path.join(tmpdir, 'temp.conf')) _create_x509_openssl_config(conffile, upn) (certificate, _err) = utils.execute( 'openssl', 'req', '-x509', '-nodes', '-days', '3650', '-config', conffile, '-newkey', 'rsa:%s' % bits, '-outform', 'PEM', '-keyout', keyfile, '-subj', subject, '-extensions', 'v3_req_client') (out, _err) = utils.execute('openssl', 'pkcs12', '-export', '-inkey', keyfile, '-password', 'pass:'******'base64') fingerprint = generate_x509_fingerprint(certificate) return (private_key, certificate, fingerprint)
def _make_vfat(self, path, tmpdir): # NOTE(mikal): This is a little horrible, but I couldn't find an # equivalent to genisoimage for vfat filesystems. with open(path, 'wb') as f: f.truncate(CONFIGDRIVESIZE_BYTES) utils.mkfs('vfat', path, label='config-2') with utils.tempdir() as mountdir: mounted = False try: _, err = utils.trycmd( 'mount', '-o', 'loop,uid=%d,gid=%d' % (os.getuid(), os.getgid()), path, mountdir, run_as_root=True) if err: raise exception.ConfigDriveMountFailed(operation='mount', error=err) mounted = True # NOTE(mikal): I can't just use shutils.copytree here, # because the destination directory already # exists. This is annoying. for ent in os.listdir(tmpdir): shutil.copytree(os.path.join(tmpdir, ent), os.path.join(mountdir, ent)) finally: if mounted: utils.execute('umount', mountdir, run_as_root=True)
def _decrypt_image(self, context, encrypted_filename, encrypted_key, encrypted_iv, decrypted_filename): elevated = context.elevated() try: key = self.cert_rpcapi.decrypt_text( elevated, project_id=context.project_id, text=base64.b64encode(encrypted_key)) except Exception as exc: msg = _('Failed to decrypt private key: %s') % exc raise exception.PatronException(msg) try: iv = self.cert_rpcapi.decrypt_text( elevated, project_id=context.project_id, text=base64.b64encode(encrypted_iv)) except Exception as exc: raise exception.PatronException( _('Failed to decrypt initialization ' 'vector: %s') % exc) try: utils.execute('openssl', 'enc', '-d', '-aes-128-cbc', '-in', '%s' % (encrypted_filename, ), '-K', '%s' % (key, ), '-iv', '%s' % (iv, ), '-out', '%s' % (decrypted_filename, )) except processutils.ProcessExecutionError as exc: raise exception.PatronException( _('Failed to decrypt image file ' '%(image_file)s: %(err)s') % { 'image_file': encrypted_filename, 'err': exc.stdout })
def set_permissions(self, path, mode): LOG.debug("Set permissions path=%(path)s mode=%(mode)o", { 'path': path, 'mode': mode }) canonpath = self._canonical_path(path) utils.execute('chmod', "%o" % mode, canonpath, run_as_root=True)
def replace_file(self, path, content): LOG.debug("Replace file path=%s", path) canonpath = self._canonical_path(path) args = [canonpath] kwargs = dict(process_input=content, run_as_root=True) utils.execute("tee", *args, **kwargs)
def unmnt_dev(self): """Unmount the device from the file system.""" if not self.mounted: return self.flush_dev() LOG.debug("Umount %s", self.mapped_device) utils.execute('umount', self.mapped_device, run_as_root=True) self.mounted = False
def replace_file(self, path, content): LOG.debug("Replace file path=%s", path) canonpath = self._canonical_path(path) args = [canonpath] kwargs = dict(process_input=content, run_as_root=True) utils.execute('tee', *args, **kwargs)
def flush_dev(self): """flush NBD block device buffer.""" # Perform an explicit BLKFLSBUF to support older qemu-nbd(s). # Without this flush, when a nbd device gets re-used the # qemu-nbd intermittently hangs. if self.device: utils.execute('blockdev', '--flushbufs', self.device, run_as_root=True)
def _close_volume(self, **kwargs): """Closes the device (effectively removes the dm-crypt mapping).""" LOG.debug("closing encrypted volume %s", self.dev_path) utils.execute('cryptsetup', 'luksClose', self.dev_name, run_as_root=True, check_exit_code=True, attempts=3)
def _ensure_project_folder(project_id): if not os.path.exists(ca_path(project_id)): geninter_sh_path = os.path.abspath( os.path.join(os.path.dirname(__file__), 'CA', 'geninter.sh')) start = os.getcwd() os.chdir(ca_folder()) utils.execute('sh', geninter_sh_path, project_id, _project_cert_subject(project_id)) os.chdir(start)
def unmap_dev(self): """Remove partitions of the device from the file system namespace.""" if not self.mapped: return LOG.debug("Unmap dev %s", self.device) if self.partition and not self.automapped: utils.execute('kpartx', '-d', self.device, run_as_root=True) self.mapped = False self.automapped = False
def create_ploop_image(base, target, size): image_path = os.path.join(target, "root.hds") libvirt_utils.copy_image(base, image_path) utils.execute('ploop', 'restore-descriptor', '-f', self.pcs_format, target, image_path) if size: dd_path = os.path.join(self.path, "DiskDescriptor.xml") utils.execute('ploop', 'grow', '-s', '%dK' % (size >> 10), dd_path, run_as_root=True)
def test_get_missing_iscsi_initiator(self): self.mox.StubOutWithMock(utils, 'execute') file_path = '/etc/iscsi/initiatorname.iscsi' utils.execute('cat', file_path, run_as_root=True).AndRaise( exception.FileNotFound(file_path=file_path)) # Start test self.mox.ReplayAll() result = volumeutils.get_iscsi_initiator() self.assertEqual('', result)
def _open_volume(self, passphrase, **kwargs): """Opens the LUKS partition on the volume using the specified passphrase. :param passphrase: the passphrase used to access the volume """ LOG.debug("opening encrypted volume %s", self.dev_path) utils.execute('cryptsetup', 'luksOpen', '--key-file=-', self.dev_path, self.dev_name, process_input=passphrase, run_as_root=True, check_exit_code=True)
def test_get_missing_iscsi_initiator(self): self.mox.StubOutWithMock(utils, 'execute') file_path = '/etc/iscsi/initiatorname.iscsi' utils.execute('cat', file_path, run_as_root=True).AndRaise( exception.FileNotFound(file_path=file_path) ) # Start test self.mox.ReplayAll() result = volumeutils.get_iscsi_initiator() self.assertEqual('', result)
def test_get_iscsi_initiator(self): self.mox.StubOutWithMock(utils, 'execute') initiator = 'fake.initiator.iqn' rval = ("junk\nInitiatorName=%s\njunk\n" % initiator, None) utils.execute('cat', '/etc/iscsi/initiatorname.iscsi', run_as_root=True).AndReturn(rval) # Start test self.mox.ReplayAll() result = volumeutils.get_iscsi_initiator() self.assertEqual(initiator, result)
def umount_volume(mnt_base): """Wraps execute calls for unmouting a Quobyte volume""" try: utils.execute('umount.quobyte', mnt_base) except processutils.ProcessExecutionError as exc: if 'Device or resource busy' in exc.message: LOG.error(_LE("The Quobyte volume at %s is still in use."), mnt_base) else: LOG.exception(_LE("Couldn't unmount the Quobyte Volume at %s"), mnt_base)
def _xvp_start(self): if self._xvp_check_running(): return LOG.debug('Starting xvp') try: utils.execute('xvp', '-p', CONF.console_xvp_pid, '-c', CONF.console_xvp_conf, '-l', CONF.console_xvp_log) except processutils.ProcessExecutionError as err: LOG.error(_LE('Error starting xvp: %s'), err)
def mount_volume(volume, mnt_base, configfile=None): """Wraps execute calls for mounting a Quobyte volume""" fileutils.ensure_tree(mnt_base) command = ['mount.quobyte', volume, mnt_base] if configfile: command.extend(['-c', configfile]) LOG.debug('Mounting volume %s at mount point %s ...', volume, mnt_base) # Run mount command but do not fail on already mounted exit code utils.execute(*command, check_exit_code=[0, 4]) LOG.info(_LI('Mounted volume: %s'), volume)
def test_resize2fs_e2fsck_fails(self): imgfile = tempfile.NamedTemporaryFile() self.mox.StubOutWithMock(utils, 'execute') utils.execute('e2fsck', '-fp', imgfile, check_exit_code=[0, 1, 2], run_as_root=False).AndRaise( processutils.ProcessExecutionError("fs error")) self.mox.ReplayAll() api.resize2fs(imgfile)
def unget_dev(self): if not self.linked: return # NOTE(mikal): On some kernels, losetup -d will intermittently fail, # thus leaking a loop device unless the losetup --detach is retried: # https://lkml.org/lkml/2012/9/28/62 LOG.debug("Release loop device %s", self.device) utils.execute('losetup', '--detach', self.device, run_as_root=True, attempts=3) self.linked = False self.device = None
def unplug_mlnx_direct(self, instance, vif): vnic_mac = vif['address'] fabric = vif.get_physical_network() if not fabric: raise exception.NetworkMissingPhysicalNetwork( network_uuid=vif['network']['id']) try: utils.execute('ebrctl', 'del-port', fabric, vnic_mac, run_as_root=True) except processutils.ProcessExecutionError: LOG.exception(_LE("Failed while unplugging vif"), instance=instance)
def unplug_vrouter(self, instance, vif): """Unplug Contrail's network port Unbind the vif from a Contrail virtual port. """ dev = self.get_vif_devname(vif) cmd_args = ("--oper=delete --uuid=%s" % (vif['id'])) try: utils.execute('vrouter-port-control', cmd_args, run_as_root=True) linux_net.delete_net_dev(dev) except processutils.ProcessExecutionError: LOG.exception( _LE("Failed while unplugging vif"), instance=instance)
def plug_midonet(self, instance, vif): """Plug into MidoNet's network port Bind the vif to a MidoNet virtual port. """ dev = self.get_vif_devname(vif) port_id = vif['id'] try: linux_net.create_tap_dev(dev) utils.execute('mm-ctl', '--bind-port', port_id, dev, run_as_root=True) except processutils.ProcessExecutionError: LOG.exception(_LE("Failed while plugging vif"), instance=instance)
def unplug_midonet(self, instance, vif): """Unplug from MidoNet network port Unbind the vif from a MidoNet virtual port. """ dev = self.get_vif_devname(vif) port_id = vif['id'] try: utils.execute('mm-ctl', '--unbind-port', port_id, run_as_root=True) linux_net.delete_net_dev(dev) except processutils.ProcessExecutionError: LOG.exception(_LE("Failed while unplugging vif"), instance=instance)
def plug_mlnx_direct(self, instance, vif): vnic_mac = vif['address'] device_id = instance.uuid fabric = vif.get_physical_network() if not fabric: raise exception.NetworkMissingPhysicalNetwork( network_uuid=vif['network']['id']) dev_name = self.get_vif_devname_with_prefix(vif, DEV_PREFIX_ETH) try: utils.execute('ebrctl', 'add-port', vnic_mac, device_id, fabric, network_model.VIF_TYPE_MLNX_DIRECT, dev_name, run_as_root=True) except processutils.ProcessExecutionError: LOG.exception(_LE("Failed while plugging vif"), instance=instance)