Example #1
0
    def test_exec_ipmitool(self):
        pw_file = "/tmp/password_file"

        self.mox.StubOutWithMock(ipmi, "_make_password_file")
        self.mox.StubOutWithMock(utils, "execute")
        self.mox.StubOutWithMock(bm_utils, "unlink_without_raise")
        ipmi._make_password_file(self.ipmi.password).AndReturn(pw_file)
        args = [
            "ipmitool",
            "-I",
            "lanplus",
            "-H",
            self.ipmi.address,
            "-U",
            self.ipmi.user,
            "-f",
            pw_file,
            "A",
            "B",
            "C",
        ]
        utils.execute(*args, attempts=3).AndReturn(("", ""))
        bm_utils.unlink_without_raise(pw_file).AndReturn(None)
        self.mox.ReplayAll()

        self.ipmi._exec_ipmitool("A B C")
        self.mox.VerifyAll()
Example #2
0
    def _make_iso9660(self, path, tmpdir):
        publisher = "%(product)s %(version)s" % {
            "product": version.product_string(),
            "version": version.version_string_with_package(),
        }

        utils.execute(
            CONF.mkisofs_cmd,
            "-o",
            path,
            "-ldots",
            "-allow-lowercase",
            "-allow-multidot",
            "-l",
            "-publisher",
            publisher,
            "-quiet",
            "-J",
            "-r",
            "-V",
            "config-2",
            tmpdir,
            attempts=1,
            run_as_root=False,
        )
Example #3
0
def clear_logical_volume(path):
    """Obfuscate the logical volume.

    :param path: logical volume path
    """
    # TODO(p-draigbrady): We currently overwrite with zeros
    # but we may want to make this configurable in future
    # for more or less security conscious setups.

    vol_size = logical_volume_size(path)
    bs = 1024 * 1024
    direct_flags = ("oflag=direct",)
    remaining_bytes = vol_size

    # The loop caters for versions of dd that
    # don't support the iflag=count_bytes option.
    while remaining_bytes:
        zero_blocks = remaining_bytes / bs
        seek_blocks = (vol_size - remaining_bytes) / bs
        zero_cmd = (
            "dd",
            "bs=%s" % bs,
            "if=/dev/zero",
            "of=%s" % path,
            "seek=%s" % seek_blocks,
            "count=%s" % zero_blocks,
        )
        zero_cmd += direct_flags
        if zero_blocks:
            utils.execute(*zero_cmd, run_as_root=True)
        remaining_bytes %= bs
        bs /= 1024  # Limit to 3 iterations
        direct_flags = ()  # Only use O_DIRECT with initial block size
Example #4
0
    def deactivate_bootloader(self, context, node, instance):
        """Delete Tilera bootloader images and config."""
        try:
            db.bm_node_update(
                context,
                node["id"],
                {"deploy_key": None, "image_path": None, "pxe_config_path": None, "root_mb": 0, "swap_mb": 0},
            )
        except exception.NodeNotFound:
            pass

        tilera_nfs_path = get_tilera_nfs_path(node["id"])

        if os.path.ismount(tilera_nfs_path):
            utils.execute("rpc.mountd", run_as_root=True)
            utils.execute("umount", "-f", tilera_nfs_path, run_as_root=True)

        try:
            image_info = get_tftp_image_info(instance)
        except exception.NovaException:
            pass
        else:
            for label in image_info.keys():
                (uuid, path) = image_info[label]
                bm_utils.unlink_without_raise(path)

        try:
            self._collect_mac_addresses(context, node)
        except db_exc.DBError:
            pass

        if os.path.exists(os.path.join(CONF.baremetal.tftp_root, instance["uuid"])):
            bm_utils.rmtree_without_raise(os.path.join(CONF.baremetal.tftp_root, instance["uuid"]))
Example #5
0
    def _synchronize_object(src, host, dst, on_execute, on_completion):
        """Creates a file or empty directory on a remote host.

        :param src: Empty directory used for rsync purposes
        :param host: Remote host
        :param dst: Destination path
        :param on_execute: Callback method to store pid of process in cache
        :param on_completion: Callback method to remove pid of process from
                              cache
        """

        # For creating path on the remote host rsync --relative path must
        # be used. With a modern rsync on the sending side (beginning with
        # 2.6.7), you can insert a dot and a slash into the source path,
        # like this:
        #   rsync -avR /foo/./bar/baz.c remote:/tmp/
        # That would create /tmp/bar/baz.c on the remote machine.
        # (Note that the dot must be followed by a slash, so "/foo/."
        # would not be abbreviated.)
        relative_tmp_file_path = os.path.join(src, "./", os.path.normpath(dst).strip(os.path.sep))

        # Do relative rsync local directory with remote root directory
        utils.execute(
            "rsync",
            "--archive",
            "--relative",
            "--no-implied-dirs",
            relative_tmp_file_path,
            "%s:%s" % (host, os.path.sep),
            on_execute=on_execute,
            on_completion=on_completion,
        )
Example #6
0
File: api.py Project: slagle/nova
def is_image_partitionless(image, use_cow=False):
    """Check whether we can resize contained file system."""
    LOG.debug(
        _("Checking if we can resize filesystem inside %(image)s. " "CoW=%(use_cow)s"),
        {"image": image, "use_cow": use_cow},
    )

    # Check the image is unpartitioned
    if use_cow:
        try:
            fs = vfs.VFS.instance_for_image(image, "qcow2", None)
            fs.setup()
            fs.teardown()
        except exception.NovaException as e:
            LOG.debug(
                _("Unable to mount image %(image)s with " "error %(error)s. Cannot resize."),
                {"image": image, "error": e},
            )
            return False
    else:
        # For raw, we can directly inspect the file system
        try:
            utils.execute("e2label", image)
        except processutils.ProcessExecutionError as e:
            LOG.debug(
                _("Unable to determine label for image %(image)s with " "error %(errror)s. Cannot resize."),
                {"image": image, "error": e},
            )
            return False

    return True
Example #7
0
    def plug_vhostuser_fp(self, instance, vif):
        """Create a fp netdevice interface with a vhostuser socket"""
        dev = self.get_vif_devname(vif)
        if linux_net.device_exists(dev):
            return

        ovs_plug = vif["details"].get(network_model.VIF_DETAILS_VHOSTUSER_OVS_PLUG, False)
        sockmode_qemu, sockpath = self._get_vhostuser_settings(vif)
        sockmode_port = "client" if sockmode_qemu == "server" else "server"

        try:
            linux_net.create_fp_dev(dev, sockpath, sockmode_port)

            if ovs_plug:
                if vif.is_hybrid_plug_enabled():
                    self.plug_ovs_hybrid(instance, vif)
                    utils.execute("brctl", "addif", self.get_br_name(vif["id"]), dev, run_as_root=True)
                else:
                    iface_id = self.get_ovs_interfaceid(vif)
                    mtu = vif["network"].get_meta("mtu")
                    linux_net.create_ovs_vif_port(
                        self.get_bridge_name(vif), dev, iface_id, vif["address"], instance.uuid, mtu
                    )
        except processutils.ProcessExecutionError:
            LOG.exception(_LE("Failed while plugging vif"), instance=instance)
Example #8
0
def chown(path, owner):
    """Change ownership of file or directory

    :param path: File or directory whose ownership to change
    :param owner: Desired new owner (given as uid or username)
    """
    utils.execute("chown", owner, path, run_as_root=True)
Example #9
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)
Example #10
0
def _create_iscsi_export_tgtadm(path, tid, iqn):
    utils.execute(
        "tgtadm",
        "--lld",
        "iscsi",
        "--mode",
        "target",
        "--op",
        "new",
        "--tid",
        tid,
        "--targetname",
        iqn,
        run_as_root=True,
    )
    utils.execute(
        "tgtadm",
        "--lld",
        "iscsi",
        "--mode",
        "logicalunit",
        "--op",
        "new",
        "--tid",
        tid,
        "--lun",
        "1",
        "--backing-store",
        path,
        run_as_root=True,
    )
Example #11
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)
Example #12
0
    def test_extend_qcow_success(self):
        imgfile = tempfile.NamedTemporaryFile()
        self.addCleanup(imgfile.close)
        imgsize = 10
        device = "/dev/sdh"
        image = imgmodel.LocalFileImage(imgfile, imgmodel.FORMAT_QCOW2)

        self.flags(resize_fs_using_block_device=True)
        mounter = FakeMount.instance_for_format(image, None, None)
        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(image).AndReturn(True)
        mount.Mount.instance_for_format(image, None, None).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(image, imgsize)
Example #13
0
File: api.py Project: markmc/nova
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_partitionless(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)
Example #14
0
File: api.py Project: markmc/nova
def resize2fs(image, check_exit_code=False, run_as_root=False):
    try:
        utils.execute("e2fsck", "-fp", image, check_exit_code=[0, 1, 2], run_as_root=run_as_root)
    except processutils.ProcessExecutionError as exc:
        LOG.debug("Checking the file system with e2fsck has failed, " "the resize will be aborted. (%s)", exc)
    else:
        utils.execute("resize2fs", image, check_exit_code=check_exit_code, run_as_root=run_as_root)
Example #15
0
 def _close_volume(self, **kwargs):
     """Closes the device (effectively removes the dm-crypt mapping)."""
     LOG.debug("closing encrypted volume %s", self.dev_path)
     # cryptsetup returns 4 when attempting to destroy a non-active
     # dm-crypt device. We are going to ignore this error code to make
     # nova deleting that instance successfully.
     utils.execute("cryptsetup", "remove", self.dev_name, run_as_root=True, check_exit_code=[0, 4])
Example #16
0
    def test_disk_type(self):
        # Seems like lvm detection
        # if its in /dev ??
        for p in ["/dev/b", "/dev/blah/blah"]:
            d_type = libvirt_utils.get_disk_type(p)
            self.assertEqual("lvm", d_type)

        # Try rbd detection
        d_type = libvirt_utils.get_disk_type("rbd:pool/instance")
        self.assertEqual("rbd", d_type)

        # Try the other types
        template_output = """image: %(path)s
file format: %(format)s
virtual size: 64M (67108864 bytes)
cluster_size: 65536
disk size: 96K
"""
        path = "/myhome/disk.config"
        for f in ["raw", "qcow2"]:
            output = template_output % ({"format": f, "path": path})
            self.mox.StubOutWithMock(os.path, "exists")
            self.mox.StubOutWithMock(utils, "execute")
            os.path.exists(path).AndReturn(True)
            utils.execute("env", "LC_ALL=C", "LANG=C", "qemu-img", "info", path).AndReturn((output, ""))
            self.mox.ReplayAll()
            d_type = libvirt_utils.get_disk_type(path)
            self.assertEqual(f, d_type)
            self.mox.UnsetStubs()
Example #17
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,
        )
Example #18
0
    def test_disk_size(self):
        path = "/myhome/disk.config"
        template_output = """image: %(path)s
file format: raw
virtual size: %(v_size)s (%(vsize_b)s bytes)
cluster_size: 65536
disk size: 96K
"""
        for i in range(0, 128):
            bytes = i * 65336
            kbytes = bytes / 1024
            mbytes = kbytes / 1024
            output = template_output % ({"v_size": "%sM" % (mbytes), "vsize_b": i, "path": path})
            self.mox.StubOutWithMock(os.path, "exists")
            self.mox.StubOutWithMock(utils, "execute")
            os.path.exists(path).AndReturn(True)
            utils.execute("env", "LC_ALL=C", "LANG=C", "qemu-img", "info", path).AndReturn((output, ""))
            self.mox.ReplayAll()
            d_size = libvirt_utils.get_disk_size(path)
            self.assertEqual(i, d_size)
            self.mox.UnsetStubs()
            output = template_output % ({"v_size": "%sK" % (kbytes), "vsize_b": i, "path": path})
            self.mox.StubOutWithMock(os.path, "exists")
            self.mox.StubOutWithMock(utils, "execute")
            os.path.exists(path).AndReturn(True)
            utils.execute("env", "LC_ALL=C", "LANG=C", "qemu-img", "info", path).AndReturn((output, ""))
            self.mox.ReplayAll()
            d_size = libvirt_utils.get_disk_size(path)
            self.assertEqual(i, d_size)
            self.mox.UnsetStubs()
Example #19
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)
Example #20
0
    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:
                fileutils.delete_if_exists(imagefile)
Example #21
0
    def activate_bootloader(self, context, node, instance):
        """Configure Tilera boot loader for an instance

        Kernel and ramdisk images are downloaded by cache_tftp_images,
        and stored in /tftpboot/{uuid}/

        This method writes the instances config file, and then creates
        symlinks for each MAC address in the instance.

        By default, the complete layout looks like this:

        /tftpboot/
            ./{uuid}/
                 kernel
            ./fs_node_id/
        """
        (root_mb, swap_mb) = get_partition_sizes(instance)
        tilera_nfs_path = get_tilera_nfs_path(node["id"])
        image_file_path = get_image_file_path(instance)

        deployment_key = bm_utils.random_alnum(32)
        db.bm_node_update(
            context,
            node["id"],
            {
                "deploy_key": deployment_key,
                "image_path": image_file_path,
                "pxe_config_path": tilera_nfs_path,
                "root_mb": root_mb,
                "swap_mb": swap_mb,
            },
        )

        if os.path.exists(image_file_path) and os.path.exists(tilera_nfs_path):
            utils.execute("mount", "-o", "loop", image_file_path, tilera_nfs_path, run_as_root=True)
Example #22
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)
Example #23
0
 def unmap_dev(self):
     """Remove partitions of the device from the file system namespace."""
     if not self.mapped:
         return
     if self.partition:
         utils.execute("kpartx", "-d", self.device, run_as_root=True)
     self.mapped = False
Example #24
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(_("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())
Example #25
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)
Example #26
0
File: vif.py Project: jake-liu/nova
    def plug_ovs_hybrid(self, instance, vif):
        """Plug using hybrid strategy

        Create a per-VIF linux bridge, then link that bridge to the OVS
        integration bridge via a veth device, setting up the other end
        of the veth device just like a normal OVS port.  Then boot the
        VIF on the linux bridge using standard libvirt mechanisms.
        """
        super(LibvirtGenericVIFDriver, self).plug(instance, vif)

        iface_id = self.get_ovs_interfaceid(vif)
        br_name = self.get_br_name(vif["id"])
        v1_name, v2_name = self.get_veth_pair_names(vif["id"])

        if not linux_net.device_exists(br_name):
            utils.execute("brctl", "addbr", br_name, run_as_root=True)
            utils.execute("brctl", "setfd", br_name, 0, run_as_root=True)
            utils.execute("brctl", "stp", br_name, "off", run_as_root=True)

        if not linux_net.device_exists(v2_name):
            linux_net._create_veth_pair(v1_name, v2_name)
            utils.execute("ip", "link", "set", br_name, "up", run_as_root=True)
            utils.execute("brctl", "addif", br_name, v1_name, run_as_root=True)
            linux_net.create_ovs_vif_port(
                self.get_bridge_name(vif), v2_name, iface_id, vif["address"], instance["uuid"]
            )
Example #27
0
 def __volume_not_present(cls, volume):
     try:
         utils.execute("lvdisplay", volume, run_as_root=True)
     except Exception:
         # If the volume isn't present
         return True
     return False
Example #28
0
def _unlink_device(device, nbd):
    """Unlink image from device using loopback or nbd"""
    if nbd:
        utils.execute("qemu-nbd", "-d", device, run_as_root=True)
        _free_device(device)
    else:
        utils.execute("losetup", "--detach", device, run_as_root=True)
Example #29
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)
Example #30
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()
        # 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,
        )