예제 #1
0
    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)
예제 #2
0
    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)
예제 #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)
예제 #4
0
    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)
예제 #5
0
파일: api.py 프로젝트: hsluoyz/patron
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)
예제 #6
0
    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)
예제 #7
0
파일: test_api.py 프로젝트: hsluoyz/patron
    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)
예제 #8
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)
예제 #9
0
파일: api.py 프로젝트: 2Exception/patron
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'))
예제 #10
0
파일: api.py 프로젝트: 2Exception/patron
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)
예제 #11
0
파일: luks.py 프로젝트: 2Exception/patron
    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)
예제 #12
0
    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)
예제 #13
0
파일: crypto.py 프로젝트: hsluoyz/patron
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())
예제 #14
0
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)
예제 #15
0
    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,
        )
예제 #16
0
    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)
예제 #17
0
파일: luks.py 프로젝트: hsluoyz/patron
    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)
예제 #18
0
파일: s3.py 프로젝트: hsluoyz/patron
    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})
예제 #19
0
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())
예제 #20
0
    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)
예제 #21
0
파일: luks.py 프로젝트: 2Exception/patron
    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)
예제 #22
0
파일: nbd.py 프로젝트: hsluoyz/patron
 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
예제 #23
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)
예제 #24
0
파일: crypto.py 프로젝트: hsluoyz/patron
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)
예제 #25
0
    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)
예제 #26
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)
예제 #27
0
파일: s3.py 프로젝트: 2Exception/patron
    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
                  })
예제 #28
0
파일: nbd.py 프로젝트: 2Exception/patron
 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
예제 #29
0
 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)
예제 #30
0
파일: localfs.py 프로젝트: hsluoyz/patron
    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)
예제 #31
0
 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
예제 #32
0
    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)
예제 #33
0
파일: api.py 프로젝트: hsluoyz/patron
 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
예제 #34
0
파일: nbd.py 프로젝트: hsluoyz/patron
 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)
예제 #35
0
파일: luks.py 프로젝트: 2Exception/patron
 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)
예제 #36
0
파일: crypto.py 프로젝트: hsluoyz/patron
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)
예제 #37
0
 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
예제 #38
0
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)
예제 #39
0
 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)
예제 #40
0
파일: api.py 프로젝트: hsluoyz/patron
 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
예제 #41
0
 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)
예제 #42
0
파일: luks.py 프로젝트: hsluoyz/patron
    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)
예제 #43
0
파일: nbd.py 프로젝트: 2Exception/patron
 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)
예제 #44
0
 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)
예제 #45
0
 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)
예제 #46
0
파일: quobyte.py 프로젝트: hsluoyz/patron
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)
예제 #47
0
 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)
예제 #48
0
 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)
예제 #49
0
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)
예제 #50
0
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)
예제 #51
0
파일: test_api.py 프로젝트: hsluoyz/patron
    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)
예제 #52
0
파일: loop.py 프로젝트: 2Exception/patron
    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
예제 #53
0
    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)
예제 #54
0
파일: vif.py 프로젝트: hsluoyz/patron
 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)
예제 #55
0
파일: vif.py 프로젝트: hsluoyz/patron
    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)
예제 #56
0
파일: vif.py 프로젝트: hsluoyz/patron
    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)
예제 #57
0
파일: vif.py 프로젝트: hsluoyz/patron
    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)
예제 #58
0
파일: vif.py 프로젝트: hsluoyz/patron
 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)