Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    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(_LI('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(_LI('NBD mount error: %s'), self.error)

            # Cleanup
            _out, err = utils.trycmd('qemu-nbd',
                                     '-d',
                                     device,
                                     run_as_root=True)
            if err:
                LOG.warning(
                    _LW('Detaching from erroneous nbd device returned '
                        'error: %s'), err)
            return False

        self.error = ''
        self.linked = True
        return True
Exemplo n.º 6
0
 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
Exemplo n.º 7
0
    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(_LI('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(_LI('NBD mount error: %s'), self.error)

            # Cleanup
            _out, err = utils.trycmd('qemu-nbd', '-d', device,
                                     run_as_root=True)
            if err:
                LOG.warning(_LW('Detaching from erroneous nbd device returned '
                                'error: %s'), err)
            return False

        self.error = ''
        self.linked = True
        return True
Exemplo n.º 8
0
    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
Exemplo n.º 9
0
    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(_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
Exemplo n.º 10
0
 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_images=%(imgs)s at path: '
                           '%(path)s'), {'imgs': CONF.preallocate_images,
                                         'path': self.path})
     return can_fallocate
Exemplo n.º 11
0
    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
Exemplo n.º 12
0
    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
Exemplo n.º 13
0
 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_images=%(imgs)s at path: '
                     '%(path)s'), {
                         'imgs': CONF.preallocate_images,
                         'path': self.path
                     })
     return can_fallocate
Exemplo n.º 14
0
    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
Exemplo n.º 15
0
 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