def _inner_get_dev(self): device = self._allocate_nbd() if not device: return False # NOTE(mikal): qemu-nbd will return an error if the device file is # already in use. LOG.debug(_('Get nbd device %(dev)s for %(imgfile)s'), {'dev': device, 'imgfile': self.image}) _out, err = utils.trycmd('qemu-nbd', '-c', device, self.image, run_as_root=True) if err: self.error = _('qemu-nbd error: %s') % err return False # NOTE(vish): this forks into another process, so give it a chance # to set up before continuing pidfile = "/sys/block/%s/pid" % os.path.basename(device) for _i in range(CONF.timeout_nbd): if os.path.exists(pidfile): self.device = device break time.sleep(1) else: _out, err = utils.trycmd('qemu-nbd', '-d', device, run_as_root=True) if err: LOG.warn(_('Detaching from erroneous nbd device returned ' 'error: %s'), err) self.error = _('nbd device %s did not show up') % device return False self.error = '' self.linked = True return True
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 _inner_get_dev(self): device = self._allocate_nbd() if not device: return False # NOTE(mikal): qemu-nbd will return an error if the device file is # already in use. LOG.debug(_("Get nbd device %(dev)s for %(imgfile)s"), {"dev": device, "imgfile": self.image}) _out, err = utils.trycmd("qemu-nbd", "-c", device, self.image, run_as_root=True) if err: self.error = _("qemu-nbd error: %s") % err LOG.info(_("NBD mount error: %s"), self.error) return False # NOTE(vish): this forks into another process, so give it a chance # to set up before continuing pidfile = "/sys/block/%s/pid" % os.path.basename(device) for _i in range(CONF.timeout_nbd): if os.path.exists(pidfile): self.device = device break time.sleep(1) else: self.error = _("nbd device %s did not show up") % device LOG.info(_("NBD mount error: %s"), self.error) # Cleanup _out, err = utils.trycmd("qemu-nbd", "-d", device, run_as_root=True) if err: LOG.warn(_("Detaching from erroneous nbd device returned " "error: %s"), err) return False self.error = "" self.linked = True return True
def _setup_selinux_for_keys(fs): """Get selinux guests to ensure correct context on injected keys.""" se_cfg = _join_and_check_path_within_fs(fs, 'etc', 'selinux') se_cfg, _err = utils.trycmd('readlink', '-e', se_cfg, run_as_root=True) if not se_cfg: return rclocal = _join_and_check_path_within_fs(fs, 'etc', 'rc.local') # Support systemd based systems rc_d = _join_and_check_path_within_fs(fs, 'etc', 'rc.d') rclocal_e, _err = utils.trycmd('readlink', '-e', rclocal, run_as_root=True) rc_d_e, _err = utils.trycmd('readlink', '-e', rc_d, run_as_root=True) if not rclocal_e and rc_d_e: rclocal = os.path.join(rc_d, 'rc.local') # Note some systems end rc.local with "exit 0" # and so to append there you'd need something like: # utils.execute('sed', '-i', '${/^exit 0$/d}' rclocal, run_as_root=True) restorecon = [ '#!/bin/sh\n', '# Added by Nova to ensure injected ssh keys have the right context\n', 'restorecon -RF /root/.ssh/ 2>/dev/null || :\n', ] rclocal_rel = os.path.relpath(rclocal, fs) _inject_file_into_fs(fs, rclocal_rel, ''.join(restorecon), append=True) utils.execute('chmod', 'a+x', rclocal, run_as_root=True)
def _make_vfat(self, path): # NOTE(mikal): This is a little horrible, but I couldn't find an # equivalent to genisoimage for vfat filesystems. vfat images are # always 64mb. with open(path, "w") as f: f.truncate(64 * 1024 * 1024) virtutils.mkfs("vfat", path, label="config-2") mounted = False try: mountdir = tempfile.mkdtemp(dir=FLAGS.config_drive_tempdir, prefix="cd_mnt_") _out, err = utils.trycmd("mount", "-o", "loop", path, mountdir, run_as_root=True) if err: raise exception.ConfigDriveMountFailed(operation="mount", error=err) mounted = True _out, err = utils.trycmd("chown", "%s.%s" % (os.getuid(), os.getgid()), mountdir, run_as_root=True) if err: raise exception.ConfigDriveMountFailed(operation="chown", error=err) # NOTE(mikal): I can't just use shutils.copytree here, because the # destination directory already exists. This is annoying. for ent in os.listdir(self.tempdir): shutil.copytree(os.path.join(self.tempdir, ent), os.path.join(mountdir, ent)) finally: if mounted: utils.execute("umount", mountdir, run_as_root=True) shutil.rmtree(mountdir)
def test_create_configdrive_vfat(self): 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() as c: c._add_file('this/is/a/path/hello', 'This is some content') (fd, imagefile) = tempfile.mkstemp(prefix='cd_vfat_') os.close(fd) c._make_vfat(imagefile) # Check cleanup self.assertFalse(os.path.exists(c.tempdir)) # 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: utils.delete_if_exists(imagefile)
def mnt_dev(self): try: partition = int(self.partition or 0) except ValueError: self.error = _('unsupported partition: %s') % self.partition return False args = ('guestmount', '--rw', '-a', self.image) if partition == -1: args += ('-i', ) # find the OS partition elif partition: args += ('-m', '/dev/sda%d' % partition) else: # We don't resort to -i for this case yet, # as some older versions of libguestfs # have problems identifying ttylinux images for example args += ('-m', '/dev/sda') args += (self.mount_dir, ) # root access should not required for guestfs (if the user # has permissions to fusermount (by being part of the fuse # group for example)). Also note the image and mount_dir # have appropriate creditials at this point for read/write # mounting by the nova user. However currently there are # subsequent access issues by both the nova and root users # if the nova user mounts the image, as detailed here: # https://bugzilla.redhat.com/show_bug.cgi?id=765814 _out, err = utils.trycmd(*args, discard_warnings=True, run_as_root=True) if err: self.error = _('Failed to mount filesystem: %s') % err # Be defensive and ensure this is unmounted, # as I'm not sure guestmount will never have # mounted when it returns EXIT_FAILURE. # This is required if discard_warnings=False above utils.trycmd('fusermount', '-u', self.mount_dir, run_as_root=True) return False # More defensiveness as there are edge cases where # guestmount can return success while not mounting try: if not os.listdir(self.mount_dir): # Assume we've just got the original empty temp dir err = _('unknown guestmount error') self.error = _('Failed to mount filesystem: %s') % err return False except OSError: # This is the usual path and means root has # probably mounted fine pass self.mounted = True return True
def mnt_dev(self): try: partition = int(self.partition or 0) except ValueError: self.error = _('unsupported partition: %s') % self.partition return False args = ('guestmount', '--rw', '-a', self.image) if partition == -1: args += ('-i',) # find the OS partition elif partition: args += ('-m', '/dev/sda%d' % partition) else: # We don't resort to -i for this case yet, # as some older versions of libguestfs # have problems identifying ttylinux images for example args += ('-m', '/dev/sda') args += (self.mount_dir,) # root access should not required for guestfs (if the user # has permissions to fusermount (by being part of the fuse # group for example)). Also note the image and mount_dir # have appropriate creditials at this point for read/write # mounting by the nova user. However currently there are # subsequent access issues by both the nova and root users # if the nova user mounts the image, as detailed here: # https://bugzilla.redhat.com/show_bug.cgi?id=765814 _out, err = utils.trycmd(*args, discard_warnings=True, run_as_root=True) if err: self.error = _('Failed to mount filesystem: %s') % err # Be defensive and ensure this is unmounted, # as I'm not sure guestmount will never have # mounted when it returns EXIT_FAILURE. # This is required if discard_warnings=False above utils.trycmd('fusermount', '-u', self.mount_dir, run_as_root=True) return False # More defensiveness as there are edge cases where # guestmount can return success while not mounting try: if not os.listdir(self.mount_dir): # Assume we've just got the original empty temp dir err = _('unknown guestmount error') self.error = _('Failed to mount filesystem: %s') % err return False except OSError: # This is the usual path and means root has # probably mounted fine pass self.mounted = True return True
def has_file(self, path): LOG.debug("Has file path=%s", path) canonpath = self._canonical_path(path) exists, _err = utils.trycmd('readlink', '-e', canonpath, run_as_root=True) return exists
def map_dev(self): """Map partitions of the device to the file system namespace.""" assert(os.path.exists(self.device)) if self.partition == -1: self.error = _('partition search unsupported with %s') % self.mode elif self.partition: map_path = '/dev/mapper/%sp%s' % (os.path.basename(self.device), self.partition) assert(not os.path.exists(map_path)) # Note kpartx can output warnings to stderr and succeed # Also it can output failures to stderr and "succeed" # So we just go on the existence of the mapped device _out, err = utils.trycmd('kpartx', '-a', self.device, run_as_root=True, discard_warnings=True) # Note kpartx does nothing when presented with a raw image, # so given we only use it when we expect a partitioned image, fail if not os.path.exists(map_path): if not err: err = _('partition %s not found') % self.partition self.error = _('Failed to map partitions: %s') % err else: self.mapped_device = map_path self.mapped = True else: self.mapped_device = self.device self.mapped = True return self.mapped
def _make_vfat(self, path): # 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') mounted = False try: mountdir = tempfile.mkdtemp(dir=CONF.config_drive_tempdir, prefix='cd_mnt_') _out, 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(self.tempdir): shutil.copytree(os.path.join(self.tempdir, ent), os.path.join(mountdir, ent)) finally: if mounted: utils.execute('umount', mountdir, run_as_root=True) shutil.rmtree(mountdir)
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 _make_vfat(self, path): # NOTE(mikal): This is a little horrible, but I couldn't find an # equivalent to genisoimage for vfat filesystems. with open(path, 'w') as f: f.truncate(CONFIGDRIVESIZE_BYTES) utils.mkfs('vfat', path, label='config-2') mounted = False try: mountdir = tempfile.mkdtemp(dir=CONF.config_drive_tempdir, prefix='cd_mnt_') _out, 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(self.tempdir): shutil.copytree(os.path.join(self.tempdir, ent), os.path.join(mountdir, ent)) finally: if mounted: utils.execute('umount', mountdir, run_as_root=True) shutil.rmtree(mountdir)
def get_dev(self): device = self._allocate_nbd() if not device: return False LOG.debug( _("Get nbd device %(dev)s for %(imgfile)s") % { 'dev': device, 'imgfile': self.image }) _out, err = utils.trycmd('qemu-nbd', '-c', device, self.image, run_as_root=True) if err: self.error = _('qemu-nbd error: %s') % err self._free_nbd(device) return False # NOTE(vish): this forks into another process, so give it a chance # to set up before continuing for _i in range(CONF.timeout_nbd): if os.path.exists("/sys/block/%s/pid" % os.path.basename(device)): self.device = device break time.sleep(1) else: self.error = _('nbd device %s did not show up') % device self._free_nbd(device) return False self.linked = True return True
def get_dev(self): device = self._allocate_nbd() if not device: return False _out, err = utils.trycmd('qemu-nbd', '-c', device, self.image, run_as_root=True) if err: self.error = _('qemu-nbd error: %s') % err self._free_nbd(device) return False # NOTE(vish): this forks into another process, so give it a chance # to set up before continuing for _i in range(CONF.timeout_nbd): if os.path.exists("/sys/block/%s/pid" % os.path.basename(device)): self.device = device break time.sleep(1) else: self.error = _('nbd device %s did not show up') % device self._free_nbd(device) return False self.linked = True return True
def has_file(self, path): LOG.debug(_("Has file path=%s"), path) canonpath = self._canonical_path(path) exists, _err = utils.trycmd('readlink', '-e', canonpath, run_as_root=True) return exists
def map_dev(self): """Map partitions of the device to the file system namespace.""" assert (os.path.exists(self.device)) if self.partition == -1: self.error = _('partition search unsupported with %s') % self.mode elif self.partition: map_path = '/dev/mapper/%sp%s' % (os.path.basename( self.device), self.partition) assert (not os.path.exists(map_path)) # Note kpartx can output warnings to stderr and succeed # Also it can output failures to stderr and "succeed" # So we just go on the existence of the mapped device _out, err = utils.trycmd('kpartx', '-a', self.device, run_as_root=True, discard_warnings=True) # Note kpartx does nothing when presented with a raw image, # so given we only use it when we expect a partitioned image, fail if not os.path.exists(map_path): if not err: err = _('partition %s not found') % self.partition self.error = _('Failed to map partitions: %s') % err else: self.mapped_device = map_path self.mapped = True else: self.mapped_device = self.device self.mapped = True return self.mapped
def map_dev(self): """Map partitions of the device to the file system namespace.""" assert (os.path.exists(self.device)) if self.partition: map_path = '/dev/mapper/%sp%s' % (self.device.split('/')[-1], self.partition) assert (not os.path.exists(map_path)) # Note kpartx can output warnings to stderr and succeed # Also it can output failures to stderr and "succeed" # So we just go on the existence of the mapped device _out, err = utils.trycmd('kpartx', '-a', self.device, run_as_root=True, discard_warnings=True) # Note kpartx does nothing when presented with a raw image, # so given we only use it when we expect a partitioned image, fail if not os.path.exists(map_path): if not err: err = _('no partitions found') self.error = _('Failed to map partitions: %s') % err else: self.mapped_device = map_path self.mapped = True else: self.mapped_device = self.device self.mapped = True # This is an orthogonal operation # which only needs to be done once if self.disable_auto_fsck and self.mapped: self.disable_auto_fsck = False # attempt to set ext[234] so that it doesn't auto-fsck _out, err = utils.trycmd('tune2fs', '-c', 0, '-i', 0, self.mapped_device, run_as_root=True) if err: LOG.info(_('Failed to disable fs check: %s') % err) return self.mapped
def _inner_get_dev(self): device = self._allocate_nbd() if not device: return False # NOTE(mikal): qemu-nbd will return an error if the device file is # already in use. LOG.debug(_('Get nbd device %(dev)s for %(imgfile)s'), { 'dev': device, 'imgfile': self.image }) _out, err = utils.trycmd('qemu-nbd', '-c', device, self.image, run_as_root=True) if err: self.error = _('qemu-nbd error: %s') % err LOG.info(_('NBD mount error: %s'), self.error) return False # NOTE(vish): this forks into another process, so give it a chance # to set up before continuing pidfile = "/sys/block/%s/pid" % os.path.basename(device) for _i in range(CONF.timeout_nbd): if os.path.exists(pidfile): self.device = device break time.sleep(1) else: self.error = _('nbd device %s did not show up') % device LOG.info(_('NBD mount error: %s'), self.error) # Cleanup _out, err = utils.trycmd('qemu-nbd', '-d', device, run_as_root=True) if err: LOG.warn( _('Detaching from erroneous nbd device returned ' 'error: %s'), err) return False self.error = '' self.linked = True return True
def _expect_parted_calls(self): self.mox.StubOutWithMock(utils, "execute") self.mox.StubOutWithMock(utils, "trycmd") self.mox.StubOutWithMock(vm_utils, "destroy_vdi") self.mox.StubOutWithMock(vm_utils.os.path, "exists") if self.session.is_local_connection: utils.execute('parted', '--script', '/dev/fakedev', 'mklabel', 'msdos', check_exit_code=False, run_as_root=True) utils.execute('parted', '--script', '/dev/fakedev', 'mkpart', 'primary', '0', '10', check_exit_code=False, run_as_root=True) vm_utils.os.path.exists('/dev/mapper/fakedev1').AndReturn(True) utils.trycmd('kpartx', '-a', '/dev/fakedev', discard_warnings=True, run_as_root=True) else: utils.execute('parted', '--script', '/dev/fakedev', 'mklabel', 'msdos', check_exit_code=True, run_as_root=True) utils.execute('parted', '--script', '/dev/fakedev', 'mkpart', 'primary', '0', '10', check_exit_code=True, run_as_root=True)
def mnt_dev(self): """Mount the device into the file system.""" _out, err = utils.trycmd("mount", self.mapped_device, self.mount_dir, run_as_root=True) if err: self.error = _("Failed to mount filesystem: %s") % err return False self.mounted = True return True
def get_dev(self): out, err = utils.trycmd('losetup', '--find', '--show', self.image, run_as_root=True) if err: self.error = _('Could not attach image to loopback: %s') % err return False self.device = out.strip() self.linked = True return True
def mnt_dev(self): """Mount the device into the file system.""" LOG.debug(_("Mount %(dev)s on %(dir)s") % {"dev": self.mapped_device, "dir": self.mount_dir}) _out, err = utils.trycmd("mount", self.mapped_device, self.mount_dir, run_as_root=True) if err: self.error = _("Failed to mount filesystem: %s") % err return False self.mounted = True return True
def test_create_configdrive_vfat(self): imagefile = None try: self.mox.StubOutWithMock(virtutils, 'mkfs') self.mox.StubOutWithMock(utils, 'execute') self.mox.StubOutWithMock(utils, 'trycmd') virtutils.mkfs('vfat', mox.IgnoreArg(), label='config-2').AndReturn(None) utils.trycmd('mount', '-o', 'loop', mox.IgnoreArg(), mox.IgnoreArg(), run_as_root=True).AndReturn((None, None)) utils.trycmd('chown', 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() c = configdrive.ConfigDriveBuilder() c._add_file('this/is/a/path/hello', 'This is some content') (fd, imagefile) = tempfile.mkstemp(prefix='cd_vfat_') os.close(fd) c._make_vfat(imagefile) c.cleanup() # Check cleanup self.assertFalse(os.path.exists(c.tempdir)) # 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: utils.delete_if_exists(imagefile)
def map_dev(self): """Map partitions of the device to the file system namespace.""" assert (os.path.exists(self.device)) LOG.debug("Map dev %s", self.device) automapped_path = '/dev/%sp%s' % (os.path.basename( self.device), self.partition) if self.partition == -1: self.error = _('partition search unsupported with %s') % self.mode elif self.partition and not os.path.exists(automapped_path): map_path = '/dev/mapper/%sp%s' % (os.path.basename( self.device), self.partition) assert (not os.path.exists(map_path)) # Note kpartx can output warnings to stderr and succeed # Also it can output failures to stderr and "succeed" # So we just go on the existence of the mapped device _out, err = utils.trycmd('kpartx', '-a', self.device, run_as_root=True, discard_warnings=True) @loopingcall.RetryDecorator(max_retry_count=MAX_FILE_CHECKS - 1, max_sleep_time=FILE_CHECK_INTERVAL, exceptions=IOError) def recheck_path(map_path): if not os.path.exists(map_path): raise IOError() # Note kpartx does nothing when presented with a raw image, # so given we only use it when we expect a partitioned image, fail try: recheck_path(map_path) self.mapped_device = map_path self.mapped = True except IOError: if not err: err = _('partition %s not found') % self.partition self.error = _('Failed to map partitions: %s') % err elif self.partition and os.path.exists(automapped_path): # Note auto mapping can be enabled with the 'max_part' option # to the nbd or loop kernel modules. Beware of possible races # in the partition scanning for _loop_ devices though # (details in bug 1024586), which are currently uncatered for. self.mapped_device = automapped_path self.mapped = True self.automapped = True else: self.mapped_device = self.device self.mapped = True return self.mapped
def mnt_dev(self): """Mount the device into the file system.""" _out, err = utils.trycmd('mount', self.mapped_device, self.mount_dir, run_as_root=True) if err: self.error = _('Failed to mount filesystem: %s') % err return False self.mounted = True return True
def mnt_dev(self): """Mount the device into the file system.""" LOG.debug(_("Mount %(dev)s on %(dir)s") % {'dev': self.mapped_device, 'dir': self.mount_dir}) _out, err = utils.trycmd('mount', self.mapped_device, self.mount_dir, run_as_root=True) if err: self.error = _('Failed to mount filesystem: %s') % err return False self.mounted = True return True
def mnt_dev(self): """Mount the device into the file system.""" LOG.debug("Mount %(dev)s on %(dir)s", {'dev': self.mapped_device, 'dir': self.mount_dir}) _out, err = utils.trycmd('mount', self.mapped_device, self.mount_dir, discard_warnings=True, run_as_root=True) if err: self.error = _('Failed to mount filesystem: %s') % err LOG.debug(self.error) return False self.mounted = True return True
def map_dev(self): """Map partitions of the device to the file system namespace.""" assert(os.path.exists(self.device)) if self.partition: map_path = '/dev/mapper/%sp%s' % (self.device.split('/')[-1], self.partition) assert(not os.path.exists(map_path)) # Note kpartx can output warnings to stderr and succeed # Also it can output failures to stderr and "succeed" # So we just go on the existence of the mapped device _out, err = utils.trycmd('kpartx', '-a', self.device, run_as_root=True, discard_warnings=True) # Note kpartx does nothing when presented with a raw image, # so given we only use it when we expect a partitioned image, fail if not os.path.exists(map_path): if not err: err = _('no partitions found') self.error = _('Failed to map partitions: %s') % err else: self.mapped_device = map_path self.mapped = True else: self.mapped_device = self.device self.mapped = True # This is an orthogonal operation # which only needs to be done once if self.disable_auto_fsck and self.mapped: self.disable_auto_fsck = False # attempt to set ext[234] so that it doesn't auto-fsck _out, err = utils.trycmd('tune2fs', '-c', 0, '-i', 0, self.mapped_device, run_as_root=True) if err: LOG.info(_('Failed to disable fs check: %s') % err) return self.mapped
def _can_fallocate(self): """Check once per class, whether fallocate(1) is available, and that the instances directory supports fallocate(2). """ can_fallocate = getattr(self.__class__, "can_fallocate", None) if can_fallocate is None: _out, err = utils.trycmd("fallocate", "-n", "-l", "1", self.path + ".fallocate_test") fileutils.delete_if_exists(self.path + ".fallocate_test") can_fallocate = not err self.__class__.can_fallocate = can_fallocate if not can_fallocate: LOG.error(_LE("Unable to preallocate image at path: " "%(path)s"), {"path": self.path}) return can_fallocate
def _inner_get_dev(self): out, err = utils.trycmd("losetup", "--find", "--show", self.image, run_as_root=True) if err: self.error = _("Could not attach image to loopback: %s") % err LOG.info(_("Loop mount error: %s"), self.error) self.linked = False self.device = None return False self.device = out.strip() LOG.debug(_("Got loop device %s"), self.device) self.linked = True return True
def map_dev(self): """Map partitions of the device to the file system namespace.""" assert(os.path.exists(self.device)) LOG.debug("Map dev %s", self.device) automapped_path = '/dev/%sp%s' % (os.path.basename(self.device), self.partition) if self.partition == -1: self.error = _('partition search unsupported with %s') % self.mode elif self.partition and not os.path.exists(automapped_path): map_path = '/dev/mapper/%sp%s' % (os.path.basename(self.device), self.partition) assert(not os.path.exists(map_path)) # Note kpartx can output warnings to stderr and succeed # Also it can output failures to stderr and "succeed" # So we just go on the existence of the mapped device _out, err = utils.trycmd('kpartx', '-a', self.device, run_as_root=True, discard_warnings=True) @loopingcall.RetryDecorator( max_retry_count=MAX_FILE_CHECKS - 1, max_sleep_time=FILE_CHECK_INTERVAL, exceptions=IOError) def recheck_path(map_path): if not os.path.exists(map_path): raise IOError() # Note kpartx does nothing when presented with a raw image, # so given we only use it when we expect a partitioned image, fail try: recheck_path(map_path) self.mapped_device = map_path self.mapped = True except IOError: if not err: err = _('partition %s not found') % self.partition self.error = _('Failed to map partitions: %s') % err elif self.partition and os.path.exists(automapped_path): # Note auto mapping can be enabled with the 'max_part' option # to the nbd or loop kernel modules. Beware of possible races # in the partition scanning for _loop_ devices though # (details in bug 1024586), which are currently uncatered for. self.mapped_device = automapped_path self.mapped = True self.automapped = True else: self.mapped_device = self.device self.mapped = True return self.mapped
def _inner_get_dev(self): out, err = utils.trycmd('losetup', '--find', '--show', self.image, run_as_root=True) if err: self.error = _('Could not attach image to loopback: %s') % err LOG.info(_('Loop mount error: %s'), self.error) self.linked = False self.device = None return False self.device = out.strip() LOG.debug(_("Got loop device %s"), self.device) self.linked = True return True
def _make_ext4_ploop(self, path, tmpdir): """ploop is a disk loopback block device, that is used in Parallels(OpenVZ) containers. It is similar to Linux loop device but prevents double caching of data in memory and supports snapshots and some other efficiency benefits. Adding ploop is a natural way to add disk device to VZ containers. Ploop device has its own image format. It contains specific partition table with one ext4 partition. """ os.mkdir(path) utils.execute('ploop', 'init', '-s', CONFIGDRIVESIZE_BYTES, '-t', 'ext4', path + '/disk.config.hds', attempts=1, run_as_root=True) with utils.tempdir() as mountdir: mounted = False try: _, err = utils.trycmd('ploop', 'mount', '-m', mountdir, '-t', 'ext4', path + '/DiskDescriptor.xml', run_as_root=True) if os.path.exists(mountdir): utils.execute('chown', '-R', '%(u)d:%(g)d' % { 'u': os.getuid(), 'g': os.getgid() }, mountdir, run_as_root=True) mounted = True for ent in os.listdir(tmpdir): shutil.copytree(os.path.join(tmpdir, ent), os.path.join(mountdir, ent)) finally: if mounted: utils.execute('ploop', 'umount', path + '/disk.config.hds', run_as_root=True)
def _can_fallocate(self): """Check once per class, whether fallocate(1) is available, and that the instances directory supports fallocate(2). """ can_fallocate = getattr(self.__class__, 'can_fallocate', None) if can_fallocate is None: test_path = self.path + '.fallocate_test' _out, err = utils.trycmd('fallocate', '-l', '1', test_path) fileutils.delete_if_exists(test_path) can_fallocate = not err self.__class__.can_fallocate = can_fallocate if not can_fallocate: LOG.warning('Unable to preallocate image at path: %(path)s', {'path': self.path}) return can_fallocate
def _can_fallocate(self): """Check once per class, whether fallocate(1) is available, and that the instances directory supports fallocate(2). """ can_fallocate = getattr(self.__class__, 'can_fallocate', None) if can_fallocate is None: _out, err = utils.trycmd('fallocate', '-n', '-l', '1', self.path + '.fallocate_test') fileutils.delete_if_exists(self.path + '.fallocate_test') can_fallocate = not err self.__class__.can_fallocate = can_fallocate if not can_fallocate: LOG.error('Unable to preallocate_images=%s at path: %s' % (CONF.preallocate_images, self.path)) return can_fallocate
def _can_fallocate(self): """Check once per class, whether fallocate(1) is available, and that the instances directory supports fallocate(2). """ can_fallocate = getattr(self.__class__, 'can_fallocate', None) if can_fallocate is None: test_path = self.path + '.fallocate_test' _out, err = utils.trycmd('fallocate', '-l', '1', test_path) fileutils.delete_if_exists(test_path) can_fallocate = not err self.__class__.can_fallocate = can_fallocate if not can_fallocate: LOG.warning(_LW('Unable to preallocate image at path: ' '%(path)s'), {'path': self.path}) return can_fallocate
def _can_fallocate(self): """Check once per class, whether fallocate(1) is available, and that the instances directory supports fallocate(2). """ can_fallocate = getattr(self.__class__, 'can_fallocate', None) if can_fallocate is None: _out, err = utils.trycmd('fallocate', '-n', '-l', '1', self.path + '.fallocate_test') utils.delete_if_exists(self.path + '.fallocate_test') can_fallocate = not err self.__class__.can_fallocate = can_fallocate if not can_fallocate: LOG.error('Unable to preallocate_images=%s at path: %s' % (CONF.preallocate_images, self.path)) return can_fallocate
def _inner_get_dev(self): out, err = utils.trycmd('losetup', '--find', '--show', self.image.path, run_as_root=True) if err: self.error = _('Could not attach image to loopback: %s') % err LOG.info(_LI('Loop mount error: %s'), self.error) self.linked = False self.device = None return False self.device = out.strip() LOG.debug("Got loop device %s", self.device) self.linked = True return True
def _make_ext4_ploop(self, path, tmpdir): """ploop is a disk loopback block device, that is used in Parallels(OpenVZ) containers. It is similiar to Linux loop device but prevents double caching of data in memory and supports snapshots and some other effeciency benefits. Adding ploop is a natural way to add disk device to VZ containers. Ploop device has its own image format. It contains specific partition table with one ext4 partition. """ os.mkdir(path) utils.execute('ploop', 'init', '-s', CONFIGDRIVESIZE_BYTES, '-t', 'ext4', path + '/disk.config.hds', attempts=1, run_as_root=True) with utils.tempdir() as mountdir: mounted = False try: _, err = utils.trycmd( 'ploop', 'mount', '-m', mountdir, '-t', 'ext4', path + '/DiskDescriptor.xml', run_as_root=True) if os.path.exists(mountdir): utils.execute('chown', '-R', '%(u)d:%(g)d' % {'u': os.getuid(), 'g': os.getgid()}, mountdir, run_as_root=True) mounted = True for ent in os.listdir(tmpdir): shutil.copytree(os.path.join(tmpdir, ent), os.path.join(mountdir, ent)) finally: if mounted: utils.execute('ploop', 'umount', path + '/disk.config.hds', run_as_root=True)
def map_dev(self): """Map partitions of the device to the file system namespace.""" assert os.path.exists(self.device) LOG.debug("Map dev %s", self.device) automapped_path = "/dev/%sp%s" % (os.path.basename(self.device), self.partition) if self.partition == -1: self.error = _("partition search unsupported with %s") % self.mode elif self.partition and not os.path.exists(automapped_path): map_path = "/dev/mapper/%sp%s" % (os.path.basename(self.device), self.partition) assert not os.path.exists(map_path) # Note kpartx can output warnings to stderr and succeed # Also it can output failures to stderr and "succeed" # So we just go on the existence of the mapped device _out, err = utils.trycmd("kpartx", "-a", self.device, run_as_root=True, discard_warnings=True) # Note kpartx does nothing when presented with a raw image, # so given we only use it when we expect a partitioned image, fail if not os.path.exists(map_path): if not err: err = _("partition %s not found") % self.partition self.error = _("Failed to map partitions: %s") % err else: self.mapped_device = map_path self.mapped = True elif self.partition and os.path.exists(automapped_path): # Note auto mapping can be enabled with the 'max_part' option # to the nbd or loop kernel modules. Beware of possible races # in the partition scanning for _loop_ devices though # (details in bug 1024586), which are currently uncatered for. self.mapped_device = automapped_path self.mapped = True self.automapped = True else: self.mapped_device = self.device self.mapped = True return self.mapped
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): src = os.path.join(tmpdir, ent) if os.path.isfile(src): shutil.copy(src, mountdir) else: shutil.copytree(src, os.path.join(mountdir, ent)) finally: if mounted: utils.execute('umount', mountdir, run_as_root=True)
from ceilometer import utils as ceilometer_utils from cinder import utils as cinder_utils from neutron.agent.linux import utils as neutron_utils from nova import utils as nova_utils # Ceilometer ceilometer_utils.execute('gcc --version') ceilometer_utils.execute('gcc --version', run_as_root=False) ceilometer_utils.execute('gcc --version', run_as_root=True) # Cinder cinder_utils.execute('gcc --version') cinder_utils.execute('gcc --version', run_as_root=False) cinder_utils.execute('gcc --version', run_as_root=True) # Neutron neutron_utils.execute('gcc --version') neutron_utils.execute('gcc --version', run_as_root=False) neutron_utils.execute('gcc --version', run_as_root=True) # Nova nova_utils.execute('gcc --version') nova_utils.execute('gcc --version', run_as_root=False) nova_utils.execute('gcc --version', run_as_root=True) nova_utils.trycmd('gcc --version') nova_utils.trycmd('gcc --version', run_as_root=True)