nova 中的guestfs

guestfs 是使用libguestfs 库中的一个模块,提供修改虚拟机镜像配置的功能,它不要把虚拟机的
镜像文件挂载到本地,而是提供了一个shell接口,可以编辑镜像文件。
在nova中的实现了一个VFSGuestFS的类来操作guestfs提供的接口
class VFSGuestFS(vfs.VFS):

    """This class implements a VFS module that uses the libguestfs APIs
    to access the disk image. The disk image is never mapped into
    the host filesystem, thus avoiding any potential for symlink
    attacks from the guest filesystem.
    """
    def __init__(self, image, partition=None):
        """Create a new local VFS instance

        :param image: instance of nova.virt.image.model.Image
        :param partition: the partition number of access
        """

        super(VFSGuestFS, self).__init__(image, partition)

        global guestfs
        if guestfs is None:
            try:
                guestfs = importutils.import_module('guestfs')
            except Exception as e:
                raise exception.NovaException(
                    _("libguestfs is not installed (%s)") % e)

        self.handle = None
        self.mount = False
这点从VFSGuestFS 的__init__函数中可以看到其是通过importutils.import_module 来导入host 已经安装好的第三方guestfs 模块
这里导入guestfs后要使用guestfs还必须得到guestfs的handle后续对guestfs的操作都是通过这个handle进行的。
可以通过调用setup函数得到handle
def setup(self, mount=True):
        LOG.debug("Setting up appliance for %(image)s",
                  {'image': self.image})
        try:
		#这里就得到guestfs的handle的
            self.handle = tpool.Proxy(
                guestfs.GuestFS(python_return_dict=False,
                                close_on_exit=False))
        except TypeError as e:
            if ('close_on_exit' in six.text_type(e) or
                'python_return_dict' in six.text_type(e)):
                # NOTE(russellb) In case we're not using a version of
                # libguestfs new enough to support parameters close_on_exit
                # and python_return_dict which were added in libguestfs 1.20.
                self.handle = tpool.Proxy(guestfs.GuestFS())
            else:
                raise

        if CONF.guestfs.debug:
            self.configure_debug()

        try:
            if forceTCG:
                self.handle.set_backend_settings("force_tcg")
        except AttributeError as ex:
            # set_backend_settings method doesn't exist in older
            # libguestfs versions, so nothing we can do but ignore
            LOG.warning("Unable to force TCG mode, "
                        "libguestfs too old? %s", ex)
            pass

        try:
		#根据image 不同的类型对add_drive_opts调用不同的接口
            if isinstance(self.image, imgmodel.LocalImage):
                self.handle.add_drive_opts(self.image.path,
                                           format=self.image.format)
            elif isinstance(self.image, imgmodel.RBDImage):
                self.handle.add_drive_opts("%s/%s" % (self.image.pool,
                                                      self.image.name),
                                           protocol="rbd",
                                           format=imgmodel.FORMAT_RAW,
                                           server=self.image.servers,
                                           username=self.image.user,
                                           secret=self.image.password)
            else:
                raise exception.UnsupportedImageModel(
                    self.image.__class__.__name__)
			#启动一个已经创建好的guest
            self.handle.launch()
			#实际使用过程中这里的mount 会为true
            if mount:
                self.setup_os()
                self.handle.aug_init("/", 0)
                self.mount = True
        except RuntimeError as e:
            # explicitly teardown instead of implicit close()
            # to prevent orphaned VMs in cases when an implicit
            # close() is not enough
            self.teardown()
            raise exception.NovaException(
                _("Error mounting %(image)s with libguestfs (%(e)s)") %
                {'image': self.image, 'e': e})
        except Exception:
            # explicitly teardown instead of implicit close()
            # to prevent orphaned VMs in cases when an implicit
            # close() is not enough
            self.teardown()
            raise

    def launch(self, pause=False):
        """Starts a created guest.

        :param pause: Indicates whether to start and pause the guest
        """
        flags = pause and libvirt.VIR_DOMAIN_START_PAUSED or 0
        try:
		#启动一个已经创建好的guest
            return self._domain.createWithFlags(flags)
        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.error('Error launching a defined domain '
                          'with XML: %s',
                          self._encoded_xml, errors='ignore')
#虽然使用guestfs的时候不用mount到host中,看是目前libvirt中还是mount到本地处理,所以setup 函数中的mount形参取
的是默认值为true
    def setup_os(self):
        if self.partition == -1:
            self.setup_os_inspect()
        else:
            self.setup_os_static()
#假定partition 已经制定,

    def setup_os_static(self):
        LOG.debug("Mount guest OS image %(image)s partition %(part)s",
                  {'image': self.image, 'part': str(self.partition)})

        if self.partition:
            self.handle.mount_options("", "/dev/sda%d" % self.partition, "/")
        else:
            self.handle.mount_options("", "/dev/sda", "/")
原来这里默认mount到sda了,既然已经mount了,就可以直接对image进行操作,例如前一篇博文将injection ,就是对
image进行改写.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值