Пример #1
0
    def _populate_snapshot_list(self, select_name=None):
        cursnaps = []
        for i in self._get_selected_snapshots():
            cursnaps.append(i.get_name())

        model = self.widget("snapshot-list").get_model()
        model.clear()

        try:
            snapshots = self.vm.list_snapshots()
        except Exception as e:
            logging.exception(e)
            self._set_error_page(
                _("Error refreshing snapshot list: %s") % str(e))
            return

        has_external = False
        has_internal = False
        for snap in snapshots:
            desc = snap.get_xmlobj().description
            name = snap.get_name()
            state = snap.run_status()
            if snap.is_external():
                has_external = True
                sortname = "3%s" % name
                external = " (%s)" % _("External")
            else:
                has_internal = True
                external = ""
                sortname = "1%s" % name

            label = "%s\n<span size='small'>%s: %s%s</span>" % (
                (util.xml_escape(name), _("VM State"), util.xml_escape(state),
                 external))
            model.append([
                name, label, desc,
                snap.run_status_icon_name(), sortname,
                snap.is_current()
            ])

        if has_internal and has_external:
            model.append([None, None, None, None, "2", False])

        def check_selection(treemodel, path, it, snaps):
            if select_name:
                if treemodel[it][0] == select_name:
                    selection.select_path(path)
            elif treemodel[it][0] in snaps:
                selection.select_path(path)

        selection = self.widget("snapshot-list").get_selection()
        model = self.widget("snapshot-list").get_model()
        selection.unselect_all()
        model.foreach(check_selection, cursnaps)

        self._initial_populate = True
Пример #2
0
    def _populate_snapshot_list(self, select_name=None):
        cursnaps = []
        for i in self._get_selected_snapshots():
            cursnaps.append(i.get_name())

        model = self.widget("snapshot-list").get_model()
        model.clear()

        try:
            snapshots = self.vm.list_snapshots()
        except Exception as e:
            logging.exception(e)
            self._set_error_page(_("Error refreshing snapshot list: %s") %
                                str(e))
            return

        has_external = False
        has_internal = False
        for snap in snapshots:
            desc = snap.get_xmlobj().description
            name = snap.get_name()
            state = snap.run_status()
            if snap.is_external():
                has_external = True
                sortname = "3%s" % name
                external = " (%s)" % _("External")
            else:
                has_internal = True
                external = ""
                sortname = "1%s" % name

            label = "%s\n<span size='small'>%s: %s%s</span>" % (
                (util.xml_escape(name), _("VM State"),
                 util.xml_escape(state), external))
            model.append([name, label, desc, snap.run_status_icon_name(),
                          sortname, snap.is_current()])

        if has_internal and has_external:
            model.append([None, None, None, None, "2", False])


        def check_selection(treemodel, path, it, snaps):
            if select_name:
                if treemodel[it][0] == select_name:
                    selection.select_path(path)
            elif treemodel[it][0] in snaps:
                selection.select_path(path)

        selection = self.widget("snapshot-list").get_selection()
        model = self.widget("snapshot-list").get_model()
        selection.unselect_all()
        model.foreach(check_selection, cursnaps)

        self._initial_populate = True
Пример #3
0
    def _get_osblob_helper(self, guest, isinstall, bootconfig):
        conn = guest.conn
        arch = self.arch
        machine = self.machine
        hvtype = self.type
        loader = self.loader
        os_type = self.os_type
        init = self.init or self._get_default_init(guest)

        hvxen = (hvtype == "xen")

        if not loader and self.is_hvm() and hvxen:
            loader = "/usr/lib/xen/boot/hvmloader"

        # Use older libvirt 'linux' value for back compat
        if os_type == "xen" and hvxen:
            os_type = "linux"

        if (not isinstall and
            self.is_xenpv() and
            not self.bootconfig.kernel):
            return "<bootloader>%s</bootloader>" % _pygrub_path(conn)

        osblob = "<os>"

        typexml = "    <type"
        if arch:
            typexml += " arch='%s'" % arch
        if machine:
            typexml += " machine='%s'" % machine
        typexml += ">%s</type>" % os_type

        osblob = util.xml_append(osblob, typexml)

        if init:
            osblob = util.xml_append(osblob,
                                      "    <init>%s</init>" %
                                      util.xml_escape(init))
        if loader:
            osblob = util.xml_append(osblob,
                                      "    <loader>%s</loader>" %
                                      util.xml_escape(loader))

        if not self.is_container():
            osblob = util.xml_append(osblob, bootconfig.get_xml_config())
        osblob = util.xml_append(osblob, "  </os>")

        return osblob
Пример #4
0
    def reset_state(self):
        title_str = ("<span size='large' color='white'>%s '%s'</span>" %
                     (_("Migrate"), util.xml_escape(self.vm.get_name())))
        self.widget("header-label").set_markup(title_str)

        self.widget("migrate-cancel").grab_focus()

        name = self.vm.get_name()
        srchost = self.conn.get_hostname()

        self.widget("migrate-label-name").set_text(name)
        self.widget("migrate-label-src").set_text(srchost)

        self.widget("migrate-set-interface").set_active(False)
        self.widget("migrate-set-rate").set_active(False)
        self.widget("migrate-set-port").set_active(False)
        self.widget("migrate-set-maxdowntime").set_active(False)
        self.widget("migrate-max-downtime").set_value(30)

        self.widget("migrate-rate").set_value(0)
        self.widget("migrate-secure").set_active(False)
        self.widget("migrate-unsafe").set_active(False)

        downtime_box = self.widget("migrate-maxdowntime-box")
        support_downtime = self.vm.support_downtime()
        downtime_tooltip = ""
        if not support_downtime:
            downtime_tooltip = _("Libvirt version does not support setting "
                                 "downtime.")
        downtime_box.set_sensitive(support_downtime)
        downtime_box.set_tooltip_text(downtime_tooltip)

        if self.conn.is_xen():
            # Default xen port is 8002
            self.widget("migrate-port").set_value(8002)
        else:
            # QEMU migrate port range is 49152+64
            self.widget("migrate-port").set_value(49152)

        secure_box = self.widget("migrate-secure-box")
        support_secure = hasattr(libvirt, "VIR_MIGRATE_TUNNELLED")
        secure_tooltip = ""
        if not support_secure:
            secure_tooltip = _("Libvirt version does not support tunnelled "
                               "migration.")

        secure_box.set_sensitive(support_secure)
        secure_box.set_tooltip_text(secure_tooltip)

        unsafe_box = self.widget("migrate-unsafe-box")
        support_unsafe = hasattr(libvirt, "VIR_MIGRATE_UNSAFE")
        unsafe_tooltip = ""
        if not support_unsafe:
            unsafe_tooltip = _("Libvirt version does not support unsafe "
                               "migration.")

        unsafe_box.set_sensitive(support_unsafe)
        unsafe_box.set_tooltip_text(unsafe_tooltip)

        self.rebuild_dest_rows()
Пример #5
0
    def _build_row(self, conn, vm):
        if conn:
            name = conn.get_pretty_desc()
            markup = self._build_conn_markup(conn, name)
            status = ("<span size='smaller'>%s</span>" %
                      conn.get_state_text())
            status_icon = None
            hint = self._build_conn_hint(conn)
            color = self._build_conn_color(conn)
            os_icon = None
        else:
            name = vm.get_name_or_title()
            status = vm.run_status()
            markup = self._build_vm_markup(name, status)
            status_icon = vm.run_status_icon_name()
            hint = vm.get_description()
            color = None
            os_icon = _get_inspection_icon_pixbuf(vm, 16, 16)

        row = []
        row.insert(ROW_HANDLE, conn or vm)
        row.insert(ROW_SORT_KEY, name)
        row.insert(ROW_MARKUP, markup)
        row.insert(ROW_STATUS_ICON, status_icon)
        row.insert(ROW_HINT, util.xml_escape(hint))
        row.insert(ROW_IS_CONN, bool(conn))
        row.insert(ROW_IS_CONN_CONNECTED,
                   bool(conn) and not conn.is_disconnected())
        row.insert(ROW_IS_VM, bool(vm))
        row.insert(ROW_IS_VM_RUNNING, bool(vm) and vm.is_active())
        row.insert(ROW_COLOR, color)
        row.insert(ROW_INSPECTION_OS_ICON, os_icon)

        return row
Пример #6
0
    def vm_changed(self, vm):
        row = self.rows.get(self.vm_row_key(vm), None)
        if row is None:
            return

        try:
            if vm == self.current_vm():
                self.update_current_selection()

            name = vm.get_name_or_title()
            status = vm.run_status()

            row[ROW_SORT_KEY] = name
            row[ROW_STATUS_ICON] = vm.run_status_icon_name()
            row[ROW_IS_VM_RUNNING] = vm.is_active()
            row[ROW_MARKUP] = self._build_vm_markup(name, status)

            desc = vm.get_description()
            if not uiutil.can_set_row_none:
                desc = desc or ""
            row[ROW_HINT] = util.xml_escape(desc)
        except libvirt.libvirtError, e:
            if util.exception_is_libvirt_error(e, "VIR_ERR_NO_DOMAIN"):
                return
            raise
Пример #7
0
    def vm_changed(self, vm):
        row = self.rows.get(self.vm_row_key(vm), None)
        if row is None:
            return

        try:
            if vm == self.current_vm():
                self.update_current_selection()

            name = vm.get_name_or_title()
            status = vm.run_status()

            row[ROW_SORT_KEY] = name
            row[ROW_STATUS_ICON] = vm.run_status_icon_name()
            row[ROW_IS_VM_RUNNING] = vm.is_active()
            row[ROW_MARKUP] = self._build_vm_markup(name, status)

            desc = vm.get_description()
            row[ROW_HINT] = util.xml_escape(desc)
        except libvirt.libvirtError as e:
            if util.exception_is_libvirt_error(e, "VIR_ERR_NO_DOMAIN"):
                return
            raise

        self.vm_row_updated(vm)
Пример #8
0
    def _build_conn_menuitem(self, conn):
        menu_item = Gtk.MenuItem.new_with_label(conn.get_pretty_desc())
        if conn.is_active():
            label = menu_item.get_child()
            markup = "<b>%s</b>" % util.xml_escape(conn.get_pretty_desc())
            label.set_markup(markup)

        menu = Gtk.Menu()
        vms = conn.list_vms()
        vms.sort(key=lambda v: v.get_name_or_title())

        for vm in vms:
            menu.add(self._build_vm_menuitem(vm))
        if not vms:
            vmitem = Gtk.MenuItem.new_with_label(_("No virtual machines"))
            vmitem.set_sensitive(False)
            menu.add(vmitem)

        menu.add(Gtk.SeparatorMenuItem())
        if conn.is_active():
            citem = Gtk.ImageMenuItem.new_from_stock(
                    Gtk.STOCK_DISCONNECT, None)
            citem.connect("activate", _conn_disconnect_cb, conn.get_uri())
        else:
            citem = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_CONNECT, None)
            citem.connect("activate", _conn_connect_cb, conn.get_uri())
        menu.add(citem)

        menu_item.set_submenu(menu)
        return menu_item
Пример #9
0
    def _set_xml(self, xmlbuilder, setval, root_node=None):
        """
        Actually set the passed value in the XML document
        """
        if root_node is None:
            root_node = xmlbuilder._xmlstate.xml_node
            ctx = xmlbuilder._xmlstate.xml_ctx
        else:
            ctx = _make_xml_context(root_node)

        xpath = self._make_xpath(xmlbuilder)
        node = _get_xpath_node(xmlbuilder._xmlstate.xml_ctx, xpath)
        clearlist = self._build_clear_list(xmlbuilder, node)

        node_map = []
        if clearlist:
            node_map += _tuplify_lists(clearlist, None,
                                       [n.nodePath() for n in clearlist])
        node_map += [(node, setval, xpath)]

        for node, val, use_xpath in node_map:
            if val is None or val is False:
                _remove_xpath_node(ctx, use_xpath)
                continue

            if not node:
                node = _build_xpath_node(root_node, use_xpath)

            if val is True:
                # Boolean property, creating the node is enough
                continue
            node.setContent(util.xml_escape(str(val)))
Пример #10
0
    def reset_state(self):
        title_str = ("<span size='large' color='white'>%s '%s'</span>" %
                     (_("Migrate"), util.xml_escape(self.vm.get_name())))
        self.widget("header-label").set_markup(title_str)

        self.widget("migrate-cancel").grab_focus()

        name = self.vm.get_name()
        srchost = self.conn.get_hostname()

        self.widget("migrate-label-name").set_text(name)
        self.widget("migrate-label-src").set_text(srchost)

        self.widget("migrate-set-interface").set_active(False)
        self.widget("migrate-set-rate").set_active(False)
        self.widget("migrate-set-port").set_active(False)
        self.widget("migrate-set-maxdowntime").set_active(False)
        self.widget("migrate-max-downtime").set_value(30)

        self.widget("migrate-rate").set_value(0)
        self.widget("migrate-secure").set_active(False)
        self.widget("migrate-unsafe").set_active(False)

        downtime_box = self.widget("migrate-maxdowntime-box")
        support_downtime = self.vm.support_downtime()
        downtime_tooltip = ""
        if not support_downtime:
            downtime_tooltip = _("Libvirt version does not support setting "
                                 "downtime.")
        downtime_box.set_sensitive(support_downtime)
        downtime_box.set_tooltip_text(downtime_tooltip)

        if self.conn.is_xen():
            # Default xen port is 8002
            self.widget("migrate-port").set_value(8002)
        else:
            # QEMU migrate port range is 49152+64
            self.widget("migrate-port").set_value(49152)

        secure_box = self.widget("migrate-secure-box")
        support_secure = hasattr(libvirt, "VIR_MIGRATE_TUNNELLED")
        secure_tooltip = ""
        if not support_secure:
            secure_tooltip = _("Libvirt version does not support tunnelled "
                               "migration.")

        secure_box.set_sensitive(support_secure)
        secure_box.set_tooltip_text(secure_tooltip)

        unsafe_box = self.widget("migrate-unsafe-box")
        support_unsafe = hasattr(libvirt, "VIR_MIGRATE_UNSAFE")
        unsafe_tooltip = ""
        if not support_unsafe:
            unsafe_tooltip = _("Libvirt version does not support unsafe "
                               "migration.")

        unsafe_box.set_sensitive(support_unsafe)
        unsafe_box.set_tooltip_text(unsafe_tooltip)

        self.rebuild_dest_rows()
Пример #11
0
    def _reset_state(self):
        title_str = ("<span size='large' color='white'>%s '%s'</span>" %
                     (_("Migrate"), util.xml_escape(self.vm.get_name())))
        self.widget("header-label").set_markup(title_str)

        self.widget("migrate-advanced-expander").set_expanded(False)

        self.widget("migrate-cancel").grab_focus()

        self.widget("config-box").set_visible(True)

        hostname = self.conn.libvirt_gethostname()
        srctext = "%s (%s)" % (hostname, self.conn.get_pretty_desc())
        self.widget("migrate-label-name").set_text(self.vm.get_name_or_title())
        self.widget("migrate-label-src").set_text(srctext)
        self.widget("migrate-label-src").set_tooltip_text(self.conn.get_uri())

        self.widget("migrate-set-address").set_active(True)
        self.widget("migrate-set-address").emit("toggled")
        self.widget("migrate-set-port").set_active(True)

        self.widget("migrate-mode").set_active(0)
        self.widget("migrate-unsafe").set_active(False)
        self.widget("migrate-temporary").set_active(False)

        if self.conn.is_xen():
            # Default xen port is 8002
            self.widget("migrate-port").set_value(8002)
        else:
            # QEMU migrate port range is 49152+64
            self.widget("migrate-port").set_value(49152)

        self._populate_destconn()
Пример #12
0
    def _reset_state(self):
        title_str = ("<span size='large' color='white'>%s '%s'</span>" %
                     (_("Migrate"), util.xml_escape(self.vm.get_name())))
        self.widget("header-label").set_markup(title_str)

        self.widget("migrate-advanced-expander").set_expanded(False)

        self.widget("migrate-cancel").grab_focus()

        self.widget("config-box").set_visible(True)

        hostname = self.conn.libvirt_gethostname()
        srctext = "%s (%s)" % (hostname, self.conn.get_pretty_desc())
        self.widget("migrate-label-name").set_text(self.vm.get_name_or_title())
        self.widget("migrate-label-src").set_text(srctext)
        self.widget("migrate-label-src").set_tooltip_text(self.conn.get_uri())

        self.widget("migrate-set-address").set_active(True)
        self.widget("migrate-set-address").emit("toggled")
        self.widget("migrate-set-port").set_active(True)

        self.widget("migrate-mode").set_active(0)
        self.widget("migrate-unsafe").set_active(False)
        self.widget("migrate-temporary").set_active(False)

        if self.conn.is_xen():
            # Default xen port is 8002
            self.widget("migrate-port").set_value(8002)
        else:
            # QEMU migrate port range is 49152+64
            self.widget("migrate-port").set_value(49152)

        self._populate_destconn()
Пример #13
0
    def _set_snapshot_state(self, snap=None):
        self.widget("snapshot-notebook").set_current_page(0)

        name = snap and snap.get_name() or ""
        desc = snap and snap.xml.description or ""
        state = snap and snap.xml.state or "shutoff"
        timestamp = ""
        if snap:
            timestamp = str(datetime.datetime.fromtimestamp(
                snap.xml.creationTime))

        current = ""
        if snap and snap.is_current():
            current = " (current)"
        title = ""
        if name:
            title = "<b>Snapshot '%s'%s:</b>" % (util.xml_escape(name),
                                                 current)

        self.widget("snapshot-title").set_markup(title)
        self.widget("snapshot-timestamp").set_text(timestamp)
        self.widget("snapshot-description").get_buffer().set_text(desc)

        self.widget("snapshot-status-text").set_text(state)
        self.widget("snapshot-status-icon").set_from_icon_name(
                            _snapshot_state_icon_name(state),
                            Gtk.IconSize.MENU)

        self.widget("snapshot-add").set_sensitive(True)
        self.widget("snapshot-delete").set_sensitive(bool(snap))
        self.widget("snapshot-start").set_sensitive(bool(snap))
        self.widget("snapshot-apply").set_sensitive(False)
Пример #14
0
    def _char_file_xml(self):
        """
        Provide source xml for devs that require only a path (dev, pipe)
        """
        file_xml = ""
        mode_xml = ""
        if self.source_path:
            file_xml = " path='%s'" % xml_escape(self.source_path)
        else:
            raise ValueError(_("A source path is required for character "
                               "device type '%s'" % self.char_type))

        if self.supports_property("source_mode") and self.source_mode:
            mode_xml = " mode='%s'" % xml_escape(self.source_mode)

        xml = "      <source%s%s/>\n" % (mode_xml, file_xml)
        return xml
Пример #15
0
    def _get_osblob_helper(self, guest, isinstall, bootconfig):
        conn = guest.conn
        arch = self.arch
        machine = self.machine
        hvtype = self.type
        loader = self.loader
        os_type = self.os_type
        init = self.init or self._get_default_init(guest)

        hvxen = (hvtype == "xen")

        if not loader and self.is_hvm() and hvxen:
            loader = "/usr/lib/xen/boot/hvmloader"

        # Use older libvirt 'linux' value for back compat
        if os_type == "xen" and hvxen:
            os_type = "linux"

        if (not isinstall and self.is_xenpv() and not self.bootconfig.kernel):
            return "<bootloader>%s</bootloader>" % _pygrub_path(conn)

        osblob = "<os>"

        typexml = "    <type"
        if arch:
            typexml += " arch='%s'" % arch
        if machine:
            typexml += " machine='%s'" % machine
        typexml += ">%s</type>" % os_type

        osblob = util.xml_append(osblob, typexml)

        if init:
            osblob = util.xml_append(
                osblob, "    <init>%s</init>" % util.xml_escape(init))
        if loader:
            osblob = util.xml_append(
                osblob, "    <loader>%s</loader>" % util.xml_escape(loader))

        if not self.is_container():
            osblob = util.xml_append(osblob, bootconfig.get_xml_config())
        osblob = util.xml_append(osblob, "  </os>")

        return osblob
Пример #16
0
    def _build_conn_markup(self, conn, name):
        name = util.xml_escape(name)
        text = name
        if conn.state == conn.STATE_DISCONNECTED:
            text += " - " + _("Not Connected")
        elif conn.state == conn.STATE_CONNECTING:
            text += " - " + _("Connecting...")

        markup = "<span size='smaller'>%s</span>" % text
        return markup
Пример #17
0
    def _build_conn_markup(self, conn, name):
        name = util.xml_escape(name)
        text = name
        if conn.is_disconnected():
            text += " - " + _("Not Connected")
        elif conn.is_connecting():
            text += " - " + _("Connecting...")

        markup = "<span size='smaller'>%s</span>" % text
        return markup
Пример #18
0
    def _set_snapshot_state(self, snap=None):
        self.widget("snapshot-notebook").set_current_page(0)

        xmlobj = snap and snap.get_xmlobj() or None
        name = snap and xmlobj.name or ""
        desc = snap and xmlobj.description or ""
        state = snap and snap.run_status() or ""
        icon = snap and snap.run_status_icon_name() or None
        is_external = snap and snap.is_external() or False
        is_current = snap and snap.is_current() or False

        timestamp = ""
        if snap:
            timestamp = str(datetime.datetime.fromtimestamp(
                xmlobj.creationTime))

        title = ""
        if name:
            title = "<b>Snapshot '%s':</b>" % util.xml_escape(name)

        uiutil.set_grid_row_visible(
            self.widget("snapshot-is-current"), is_current)
        self.widget("snapshot-title").set_markup(title)
        self.widget("snapshot-timestamp").set_text(timestamp)
        self.widget("snapshot-description").get_buffer().set_text(desc)

        self.widget("snapshot-status-text").set_text(state)
        if icon:
            self.widget("snapshot-status-icon").set_from_icon_name(
                icon, Gtk.IconSize.BUTTON)

        uiutil.set_grid_row_visible(self.widget("snapshot-mode"),
                                       is_external)
        if is_external:
            is_mem = xmlobj.memory_type == "external"
            is_disk = [d.snapshot == "external" for d in xmlobj.disks]
            if is_mem and is_disk:
                mode = _("External disk and memory")
            elif is_mem:
                mode = _("External memory only")
            else:
                mode = _("External disk only")
            self.widget("snapshot-mode").set_text(mode)

        sn = self._read_screenshot_file(name)
        self.widget("snapshot-screenshot").set_visible(bool(sn))
        self.widget("snapshot-screenshot-label").set_visible(not bool(sn))
        if sn:
            self.widget("snapshot-screenshot").set_from_pixbuf(sn)

        self.widget("snapshot-add").set_sensitive(True)
        self.widget("snapshot-delete").set_sensitive(bool(snap))
        self.widget("snapshot-start").set_sensitive(bool(snap))
        self.widget("snapshot-apply").set_sensitive(False)
        self._unapplied_changes = False
Пример #19
0
    def _set_snapshot_state(self, snap=None):
        self.widget("snapshot-notebook").set_current_page(0)

        xmlobj = snap and snap.get_xmlobj() or None
        name = snap and xmlobj.name or ""
        desc = snap and xmlobj.description or ""
        state = snap and snap.run_status() or ""
        icon = snap and snap.run_status_icon_name() or None
        is_external = snap and snap.is_external() or False
        is_current = snap and snap.is_current() or False

        timestamp = ""
        if snap:
            timestamp = str(datetime.datetime.fromtimestamp(
                xmlobj.creationTime))

        title = ""
        if name:
            title = "<b>Snapshot '%s':</b>" % util.xml_escape(name)

        uiutil.set_grid_row_visible(
            self.widget("snapshot-is-current"), is_current)
        self.widget("snapshot-title").set_markup(title)
        self.widget("snapshot-timestamp").set_text(timestamp)
        self.widget("snapshot-description").get_buffer().set_text(desc)

        self.widget("snapshot-status-text").set_text(state)
        if icon:
            self.widget("snapshot-status-icon").set_from_icon_name(
                icon, Gtk.IconSize.BUTTON)

        uiutil.set_grid_row_visible(self.widget("snapshot-mode"),
                                       is_external)
        if is_external:
            is_mem = xmlobj.memory_type == "external"
            is_disk = [d.snapshot == "external" for d in xmlobj.disks]
            if is_mem and is_disk:
                mode = _("External disk and memory")
            elif is_mem:
                mode = _("External memory only")
            else:
                mode = _("External disk only")
            self.widget("snapshot-mode").set_text(mode)

        sn = self._read_screenshot_file(name)
        self.widget("snapshot-screenshot").set_visible(bool(sn))
        self.widget("snapshot-screenshot-label").set_visible(not bool(sn))
        if sn:
            self.widget("snapshot-screenshot").set_from_pixbuf(sn)

        self.widget("snapshot-add").set_sensitive(True)
        self.widget("snapshot-delete").set_sensitive(bool(snap))
        self.widget("snapshot-start").set_sensitive(bool(snap))
        self.widget("snapshot-apply").set_sensitive(False)
        self._unapplied_changes = False
Пример #20
0
    def _get_xml_config(self):
        xml = ""

        if self.kernel:
            xml = util.xml_append(xml, "    <kernel>%s</kernel>" %
                                   util.xml_escape(self.kernel))
            if self.initrd:
                xml = util.xml_append(xml, "    <initrd>%s</initrd>" %
                                       util.xml_escape(self.initrd))
            if self.kernel_args:
                xml = util.xml_append(xml, "    <cmdline>%s</cmdline>" %
                                       util.xml_escape(self.kernel_args))

        else:
            for dev in self.bootorder:
                xml = util.xml_append(xml, "    <boot dev='%s'/>" % dev)

            if self.enable_bootmenu in [True, False]:
                val = self.enable_bootmenu and "yes" or "no"
                xml = util.xml_append(xml,
                                       "    <bootmenu enable='%s'/>" % val)

        return xml
Пример #21
0
    def _get_xml_config(self):
        xml = ""

        if self.kernel:
            xml = util.xml_append(
                xml, "    <kernel>%s</kernel>" % util.xml_escape(self.kernel))
            if self.initrd:
                xml = util.xml_append(
                    xml,
                    "    <initrd>%s</initrd>" % util.xml_escape(self.initrd))
            if self.kernel_args:
                xml = util.xml_append(
                    xml, "    <cmdline>%s</cmdline>" %
                    util.xml_escape(self.kernel_args))

        else:
            for dev in self.bootorder:
                xml = util.xml_append(xml, "    <boot dev='%s'/>" % dev)

            if self.enable_bootmenu in [True, False]:
                val = self.enable_bootmenu and "yes" or "no"
                xml = util.xml_append(xml, "    <bootmenu enable='%s'/>" % val)

        return xml
Пример #22
0
    def new_setter(self, val, *args, **kwargs):
        # Do this regardless, for validation purposes
        fset(self, val, *args, **kwargs)

        if not self._xml_node:
            return

        # Convert from API value to XML value
        val = fget(self)
        if set_converter:
            val = set_converter(self, val)
        elif default_converter and val == "default":
            val = default_converter(self)

        nodexpath = xpath
        if xml_set_xpath:
            nodexpath = xml_set_xpath(self)

        if nodexpath is None:
            return

        nodes = util.listify(_get_xpath_node(self._xml_ctx,
                                              nodexpath, is_multi))

        xpath_list = nodexpath
        if xml_set_list:
            xpath_list = xml_set_list(self)

        node_map = _tuplify_lists(nodes, val, xpath_list)
        for node, val, usexpath in node_map:
            if node:
                usexpath = node.nodePath()

            if val not in [None, False]:
                if not node:
                    node = _build_xpath_node(self._xml_node, usexpath)

                if val is True:
                    # Boolean property, creating the node is enough
                    pass
                else:
                    node.setContent(util.xml_escape(str(val)))
            else:
                _remove_xpath_node(self._xml_node, usexpath)
Пример #23
0
    def new_setter(self, val, *args, **kwargs):
        # Do this regardless, for validation purposes
        fset(self, val, *args, **kwargs)

        if not self._xml_node:
            return

        # Convert from API value to XML value
        val = fget(self)
        if set_converter:
            val = set_converter(self, val)
        elif default_converter and val == "default":
            val = default_converter(self)

        nodexpath = xpath
        if xml_set_xpath:
            nodexpath = xml_set_xpath(self)

        if nodexpath is None:
            return

        nodes = util.listify(
            _get_xpath_node(self._xml_ctx, nodexpath, is_multi))

        xpath_list = nodexpath
        if xml_set_list:
            xpath_list = xml_set_list(self)

        node_map = _tuplify_lists(nodes, val, xpath_list)
        for node, val, usexpath in node_map:
            if node:
                usexpath = node.nodePath()

            if val not in [None, False]:
                if not node:
                    node = _build_xpath_node(self._xml_node, usexpath)

                if val is True:
                    # Boolean property, creating the node is enough
                    pass
                else:
                    node.setContent(util.xml_escape(str(val)))
            else:
                _remove_xpath_node(self._xml_node, usexpath)
Пример #24
0
    def reset_state(self):
        # Set VM name in title'
        title_str = ("<span size='large' color='white'>%s '%s'</span>" %
                     (_("Delete"), util.xml_escape(self.vm.get_name())))
        self.widget("header-label").set_markup(title_str)

        self.widget("delete-cancel").grab_focus()

        # Show warning message if VM is running
        vm_active = self.vm.is_active()
        uiutil.set_grid_row_visible(
            self.widget("delete-warn-running-vm-box"), vm_active)

        # Disable storage removal by default
        self.widget("delete-remove-storage").set_active(True)
        self.widget("delete-remove-storage").toggled()

        populate_storage_list(self.widget("delete-storage-list"),
                              self.vm, self.conn)
Пример #25
0
    def reset_state(self):
        # Set VM name in title'
        title_str = ("<span size='large' color='white'>%s '%s'</span>" %
                     (_("Delete"), util.xml_escape(self.vm.get_name())))
        self.widget("header-label").set_markup(title_str)

        self.widget("delete-cancel").grab_focus()

        # Show warning message if VM is running
        vm_active = self.vm.is_active()
        uiutil.set_grid_row_visible(
            self.widget("delete-warn-running-vm-box"), vm_active)

        # Enable storage removal by default
        self.widget("delete-remove-storage").set_active(True)
        self.widget("delete-remove-storage").toggled()

        populate_storage_list(self.widget("delete-storage-list"),
                              self.vm, self.conn)
Пример #26
0
    def vm_config_changed(self, vm):
        row = self.rows.get(self.vm_row_key(vm), None)
        if row is None:
            return

        try:
            name = vm.get_name_or_title()
            status = vm.run_status()

            row[ROW_SORT_KEY] = name
            row[ROW_STATUS_ICON] = vm.run_status_icon_name()
            row[ROW_IS_VM_RUNNING] = vm.is_active()
            row[ROW_MARKUP] = self._build_vm_markup(name, status)

            desc = vm.get_description()
            if not uiutil.can_set_row_none:
                desc = desc or ""
            row[ROW_HINT] = util.xml_escape(desc)
        except libvirt.libvirtError, e:
            if util.exception_is_libvirt_error(e, "VIR_ERR_NO_DOMAIN"):
                return
            raise
Пример #27
0
 def _build_vm_markup(self, name, status):
     domtext     = ("<span size='smaller' weight='bold'>%s</span>" %
                    util.xml_escape(name))
     statetext   = "<span size='smaller'>%s</span>" % status
     return domtext + "\n" + statetext
Пример #28
0
class vmmSnapshotPage(vmmGObjectUI):
    def __init__(self, vm, builder, topwin):
        vmmGObjectUI.__init__(self,
                              "snapshots.ui",
                              None,
                              builder=builder,
                              topwin=topwin)

        self.vm = vm

        self._initial_populate = False
        self._unapplied_changes = False

        self._snapmenu = None
        self._init_ui()

        self._snapshot_new = self.widget("snapshot-new")
        self._snapshot_new.set_transient_for(self.topwin)
        self.bind_escape_key_close_helper(self._snapshot_new,
                                          self._snapshot_new_close)

        self.builder.connect_signals({
            "on_snapshot_add_clicked":
            self._on_add_clicked,
            "on_snapshot_delete_clicked":
            self._on_delete_clicked,
            "on_snapshot_start_clicked":
            self._on_start_clicked,
            "on_snapshot_apply_clicked":
            self._on_apply_clicked,
            "on_snapshot_list_changed":
            self._snapshot_selected,
            "on_snapshot_list_button_press_event":
            self._popup_snapshot_menu,
            "on_snapshot_refresh_clicked":
            self._refresh_snapshots,
            "on_snapshot_list_row_activated":
            self._on_start_clicked,

            # 'Create' dialog
            "on_snapshot_new_delete_event":
            self._snapshot_new_close,
            "on_snapshot_new_ok_clicked":
            self._on_new_ok_clicked,
            "on_snapshot_new_cancel_clicked":
            self._snapshot_new_close,
            "on_snapshot_new_name_changed":
            self._snapshot_new_name_changed,
            "on_snapshot_new_name_activate":
            self._on_new_ok_clicked,
        })

        self.top_box = self.widget("snapshot-top-box")
        self.widget("snapshot-top-window").remove(self.top_box)
        selection = self.widget("snapshot-list").get_selection()
        selection.emit("changed")
        selection.set_mode(Gtk.SelectionMode.MULTIPLE)
        selection.set_select_function(self._confirm_changes, None)

    ##############
    # Init stuff #
    ##############

    def _cleanup(self):
        self.vm = None

        self._snapshot_new.destroy()
        self._snapshot_new = None

    def _init_ui(self):
        # pylint: disable=redefined-variable-type
        blue = Gdk.color_parse("#0072A8")
        self.widget("header").modify_bg(Gtk.StateType.NORMAL, blue)

        self.widget("snapshot-notebook").set_show_tabs(False)

        buf = Gtk.TextBuffer()
        buf.connect("changed", self._description_changed)
        self.widget("snapshot-description").set_buffer(buf)

        buf = Gtk.TextBuffer()
        self.widget("snapshot-new-description").set_buffer(buf)

        # [name, row label, tooltip, icon name, sortname, current]
        model = Gtk.ListStore(str, str, str, str, str, bool)
        model.set_sort_column_id(4, Gtk.SortType.ASCENDING)

        col = Gtk.TreeViewColumn("")
        col.set_min_width(150)
        col.set_spacing(6)

        img = Gtk.CellRendererPixbuf()
        img.set_property("stock-size", Gtk.IconSize.LARGE_TOOLBAR)
        col.pack_start(img, False)
        col.add_attribute(img, 'icon-name', 3)

        txt = Gtk.CellRendererText()
        txt.set_property("ellipsize", Pango.EllipsizeMode.END)
        col.pack_start(txt, False)
        col.add_attribute(txt, 'markup', 1)

        img = Gtk.CellRendererPixbuf()
        img.set_property("stock-size", Gtk.IconSize.MENU)
        img.set_property("icon-name", Gtk.STOCK_APPLY)
        img.set_property("xalign", 0.0)
        col.pack_start(img, False)
        col.add_attribute(img, "visible", 5)

        def _sep_cb(_model, _iter, ignore):
            return not bool(_model[_iter][0])

        slist = self.widget("snapshot-list")
        slist.set_model(model)
        slist.set_tooltip_column(2)
        slist.append_column(col)
        slist.set_row_separator_func(_sep_cb, None)

        # Snapshot popup menu
        menu = Gtk.Menu()

        item = Gtk.ImageMenuItem.new_with_label(_("_Start snapshot"))
        item.set_use_underline(True)
        img = Gtk.Image()
        img.set_from_stock(Gtk.STOCK_MEDIA_PLAY, Gtk.IconSize.MENU)
        item.set_image(img)
        item.show()
        item.connect("activate", self._on_start_clicked)
        menu.add(item)

        item = Gtk.ImageMenuItem.new_with_label(_("_Delete snapshot"))
        item.set_use_underline(True)
        img = Gtk.Image()
        img.set_from_stock(Gtk.STOCK_DELETE, Gtk.IconSize.MENU)
        item.set_image(img)
        item.show()
        item.connect("activate", self._on_delete_clicked)
        menu.add(item)

        self._snapmenu = menu

    ###################
    # Functional bits #
    ###################

    def _get_selected_snapshots(self):
        selection = self.widget("snapshot-list").get_selection()

        def add_snap(treemodel, path, it, snaps):
            ignore = path
            try:
                name = treemodel[it][0]
                for snap in self.vm.list_snapshots():
                    if name == snap.get_name():
                        snaps.append(snap)
            except:
                pass

        snaps = []
        selection.selected_foreach(add_snap, snaps)
        return snaps

    def _refresh_snapshots(self, select_name=None):
        self.vm.refresh_snapshots()
        self._populate_snapshot_list(select_name)

    def show_page(self):
        if not self._initial_populate:
            self._populate_snapshot_list()

    def _set_error_page(self, msg):
        self._set_snapshot_state(None)
        self.widget("snapshot-notebook").set_current_page(1)
        self.widget("snapshot-error-label").set_text(msg)

    def _populate_snapshot_list(self, select_name=None):
        cursnaps = []
        for i in self._get_selected_snapshots():
            cursnaps.append(i.get_name())

        model = self.widget("snapshot-list").get_model()
        model.clear()

        try:
            snapshots = self.vm.list_snapshots()
        except Exception, e:
            logging.exception(e)
            self._set_error_page(
                _("Error refreshing snapshot list: %s") % str(e))
            return

        has_external = False
        has_internal = False
        for snap in snapshots:
            desc = snap.get_xmlobj().description
            name = snap.get_name()
            state = util.xml_escape(snap.run_status())
            if snap.is_external():
                has_external = True
                sortname = "3%s" % name
                external = " (%s)" % _("External")
            else:
                has_internal = True
                external = ""
                sortname = "1%s" % name

            label = "%s\n<span size='small'>%s: %s%s</span>" % (
                (name, _("VM State"), state, external))
            model.append([
                name, label, desc,
                snap.run_status_icon_name(), sortname,
                snap.is_current()
            ])

        if has_internal and has_external:
            model.append([None, None, None, None, "2", False])

        def check_selection(treemodel, path, it, snaps):
            if select_name:
                if treemodel[it][0] == select_name:
                    selection.select_path(path)
            elif treemodel[it][0] in snaps:
                selection.select_path(path)

        selection = self.widget("snapshot-list").get_selection()
        model = self.widget("snapshot-list").get_model()
        selection.unselect_all()
        model.foreach(check_selection, cursnaps)

        self._initial_populate = True