47893da
commit 6fa885e5831e637976487e39c877ab3a80325ee8
47893da
Author: Marc-André Lureau <marcandre.lureau@redhat.com>
47893da
Date:   Tue Apr 5 01:35:31 2011 +0200
47893da
47893da
    addhardware: allow setting the char device target name
47893da
47893da
diff --git a/src/virtManager/addhardware.py b/src/virtManager/addhardware.py
47893da
index a8ceb78..91ece33 100644
47893da
--- a/src/virtManager/addhardware.py
47893da
+++ b/src/virtManager/addhardware.py
47893da
@@ -54,6 +54,7 @@ char_widget_mappings = {
47893da
     "bind_port" : "char-bind-port",
47893da
     "bind_host" : "char-bind-host",
47893da
     "protocol"  : "char-use-telnet",
47893da
+    "target_name" : "char-target-name",
47893da
 }
47893da
 
47893da
 def get_list_selection(widget):
47893da
@@ -117,6 +118,7 @@ class vmmAddHardware(vmmGObjectUI):
47893da
             "char_host_focus_in": (self.update_doc, "source_host"),
47893da
             "char_bind_host_focus_in": (self.update_doc, "bind_host"),
47893da
             "char_telnet_focus_in": (self.update_doc, "protocol"),
47893da
+            "char_name_focus_in": (self.update_doc, "target_name"),
47893da
             })
47893da
         util.bind_escape_key_close(self)
47893da
 
47893da
@@ -443,6 +445,7 @@ class vmmAddHardware(vmmGObjectUI):
47893da
         self.window.get_widget("char-bind-host").set_text("127.0.0.1")
47893da
         self.window.get_widget("char-bind-port").get_adjustment().value = 4556
47893da
         self.window.get_widget("char-use-telnet").set_active(False)
47893da
+        self.window.get_widget("char-target-name").set_text("com.redhat.spice.0")
47893da
 
47893da
         # Hide all notebook pages, so the wizard isn't as big as the largest
47893da
         # page
47893da
@@ -1143,6 +1146,7 @@ class vmmAddHardware(vmmGObjectUI):
47893da
         bind_host = self.window.get_widget("char-bind-host").get_text()
47893da
         source_port = self.window.get_widget("char-port").get_adjustment().value
47893da
         bind_port = self.window.get_widget("char-bind-port").get_adjustment().value
47893da
+        target_name = self.window.get_widget("char-target-name").get_text()
47893da
 
47893da
         if self.window.get_widget("char-use-telnet").get_active():
47893da
             protocol = VirtualCharDevice.CHAR_PROTOCOL_TELNET
47893da
@@ -1156,6 +1160,7 @@ class vmmAddHardware(vmmGObjectUI):
47893da
             "bind_port": bind_port,
47893da
             "bind_host": bind_host,
47893da
             "protocol": protocol,
47893da
+            "target_name": target_name,
47893da
         }
47893da
 
47893da
         try:
47893da
diff --git a/src/vmm-add-hardware.glade b/src/vmm-add-hardware.glade
47893da
index bbd3a42..c5087a1 100644
47893da
--- a/src/vmm-add-hardware.glade
47893da
+++ b/src/vmm-add-hardware.glade
47893da
@@ -1504,7 +1504,7 @@ to connect to the virtual machine.</property>
47893da
                                                 <child>
47893da
                                                   <widget class="GtkTable" id="char-param-table">
47893da
                                                     <property name="visible">True</property>
47893da
-                                                    <property name="n_rows">5</property>
47893da
+                                                    <property name="n_rows">6</property>
47893da
                                                     <property name="n_columns">2</property>
47893da
                                                     <property name="column_spacing">8</property>
47893da
                                                     <property name="row_spacing">8</property>
47893da
@@ -1520,6 +1520,34 @@ to connect to the virtual machine.</property>
47893da
                                                       </packing>
47893da
                                                     </child>
47893da
                                                     <child>
47893da
+                                                      <widget class="GtkEntry" id="char-target-name">
47893da
+                                                        <property name="visible">True</property>
47893da
+                                                        <property name="can_focus">True</property>
47893da
+                                                        <signal name="focus_in_event" handler="char_name_focus_in"/>
47893da
+                                                      </widget>
47893da
+                                                      <packing>
47893da
+                                                        <property name="left_attach">1</property>
47893da
+                                                        <property name="right_attach">2</property>
47893da
+                                                        <property name="top_attach">5</property>
47893da
+                                                        <property name="bottom_attach">6</property>
47893da
+                                                      </packing>
47893da
+                                                    </child>
47893da
+                                                    <child>
47893da
+                                                      <widget class="GtkLabel" id="target-name-label">
47893da
+                                                        <property name="visible">True</property>
47893da
+                                                        <property name="xalign">0</property>
47893da
+                                                        <property name="label" translatable="yes">Name:</property>
47893da
+                                                        <property name="use_underline">True</property>
47893da
+                                                        <property name="mnemonic_widget">char-use-telnet</property>
47893da
+                                                      </widget>
47893da
+                                                      <packing>
47893da
+                                                        <property name="top_attach">5</property>
47893da
+                                                        <property name="bottom_attach">6</property>
47893da
+                                                        <property name="x_options">GTK_FILL</property>
47893da
+                                                        <property name="y_options"></property>
47893da
+                                                      </packing>
47893da
+                                                    </child>
47893da
+                                                    <child>
47893da
                                                       <widget class="GtkCheckButton" id="char-use-telnet">
47893da
                                                         <property name="visible">True</property>
47893da
                                                         <property name="can_focus">True</property>
47893da
commit ce9a125728b6622008849dd9c35309e36104913e
47893da
Author: Marc-André Lureau <marcandre.lureau@redhat.com>
47893da
Date:   Tue Apr 5 01:35:32 2011 +0200
47893da
47893da
    addhardware: fix adding and removing a channel device
47893da
47893da
diff --git a/src/virtManager/addhardware.py b/src/virtManager/addhardware.py
47893da
index 91ece33..885c8b9 100644
47893da
--- a/src/virtManager/addhardware.py
47893da
+++ b/src/virtManager/addhardware.py
47893da
@@ -286,19 +286,6 @@ class vmmAddHardware(vmmGObjectUI):
47893da
         video_dev = self.window.get_widget("video-model")
47893da
         uihelpers.build_video_combo(self.vm, video_dev)
47893da
 
47893da
-        # Char device type
47893da
-        char_devtype = self.window.get_widget("char-device-type")
47893da
-        # Type name, desc
47893da
-        char_devtype_model = gtk.ListStore(str, str)
47893da
-        char_devtype.set_model(char_devtype_model)
47893da
-        text = gtk.CellRendererText()
47893da
-        char_devtype.pack_start(text, True)
47893da
-        char_devtype.add_attribute(text, 'text', 1)
47893da
-        for t in VirtualCharDevice.char_types:
47893da
-            desc = VirtualCharDevice.get_char_type_desc(t)
47893da
-            row = [t, desc + " (%s)" % t]
47893da
-            char_devtype_model.append(row)
47893da
-
47893da
         # Character dev mode
47893da
         char_mode = self.window.get_widget("char-mode")
47893da
         # Mode name, desc
47893da
@@ -358,6 +345,10 @@ class vmmAddHardware(vmmGObjectUI):
47893da
                       self.vm.is_hvm(),
47893da
                       _("Not supported for this guest type."),
47893da
                       "parallel")
47893da
+        add_hw_option("Channel", gtk.STOCK_CONNECT, PAGE_CHAR,
47893da
+                      self.vm.is_hvm(),
47893da
+                      _("Not supported for this guest type."),
47893da
+                      "channel")
47893da
         add_hw_option("USB Host Device", "system-run", PAGE_HOSTDEV,
47893da
                       self.vm.get_connection().is_nodedev_capable(),
47893da
                       _("Connection does not support host device enumeration"),
47893da
@@ -688,6 +679,23 @@ class vmmAddHardware(vmmGObjectUI):
47893da
     def get_hw_selection(self):
47893da
         return get_list_selection(self.window.get_widget("hardware-list"))
47893da
 
47893da
+    def update_char_device_type_model(self):
47893da
+        # Char device type
47893da
+        char_devtype = self.window.get_widget("char-device-type")
47893da
+        dev_type = self.get_char_type()
47893da
+        # Type name, desc
47893da
+        char_devtype_model = gtk.ListStore(str, str)
47893da
+        char_devtype.clear()
47893da
+        char_devtype.set_model(char_devtype_model)
47893da
+        text = gtk.CellRendererText()
47893da
+        char_devtype.pack_start(text, True)
47893da
+        char_devtype.add_attribute(text, 'text', 1)
47893da
+        for t in VirtualCharDevice.char_types_for_dev_type[dev_type]:
47893da
+            desc = VirtualCharDevice.get_char_type_desc(t)
47893da
+            row = [t, desc + " (%s)" % t]
47893da
+            char_devtype_model.append(row)
47893da
+        char_devtype.set_active(0)
47893da
+
47893da
     def hw_selected(self, src=None):
47893da
         ignore = src
47893da
         self._dev = None
47893da
@@ -707,6 +715,7 @@ class vmmAddHardware(vmmGObjectUI):
47893da
             self.window.get_widget("hardware-info").set_text(msg)
47893da
 
47893da
         if page == PAGE_CHAR:
47893da
+            self.update_char_device_type_model()
47893da
             devtype = self.window.get_widget("char-device-type")
47893da
             self.change_char_device_type(devtype)
47893da
 
47893da
@@ -814,6 +823,8 @@ class vmmAddHardware(vmmGObjectUI):
47893da
 
47893da
         if label == "parallel":
47893da
             return VirtualDevice.VIRTUAL_DEV_PARALLEL
47893da
+        elif label == "channel":
47893da
+            return VirtualDevice.VIRTUAL_DEV_CHANNEL
47893da
         return VirtualDevice.VIRTUAL_DEV_SERIAL
47893da
 
47893da
     def dev_to_title(self, page):
47893da
@@ -849,6 +860,9 @@ class vmmAddHardware(vmmGObjectUI):
47893da
 
47893da
     def change_char_device_type(self, src):
47893da
         self.update_doc(None, None, "char_type")
47893da
+        idx = src.get_active()
47893da
+        if idx < 0:
47893da
+            return
47893da
 
47893da
         chartype = self.get_char_type()
47893da
         devtype = src.get_model()[src.get_active()][0]
47893da
@@ -863,7 +877,6 @@ class vmmAddHardware(vmmGObjectUI):
47893da
             self.window.get_widget(widget_name).set_sensitive(make_visible)
47893da
 
47893da
         has_mode = self._dev.supports_property("source_mode")
47893da
-
47893da
         if has_mode and self.window.get_widget("char-mode").get_active() == -1:
47893da
             self.window.get_widget("char-mode").set_active(0)
47893da
 
47893da
diff --git a/src/virtManager/details.py b/src/virtManager/details.py
47893da
index 69e2b1a..ca21c2d 100644
47893da
--- a/src/virtManager/details.py
47893da
+++ b/src/virtManager/details.py
47893da
@@ -2752,7 +2752,7 @@ class vmmDetails(vmmGObjectUI):
47893da
             port = chardev.target_port
47893da
 
47893da
             label = devtype.capitalize()
47893da
-            if devtype != "console":
47893da
+            if devtype not in ["console", "channel"]:
47893da
                 # Don't show port for console
47893da
                 label += " %s" % (int(port) + 1)
47893da
 
47893da
diff --git a/src/virtManager/domain.py b/src/virtManager/domain.py
47893da
index 9730233..7fc66ed 100644
47893da
--- a/src/virtManager/domain.py
47893da
+++ b/src/virtManager/domain.py
47893da
@@ -46,6 +46,7 @@ def compare_device(origdev, newdev, idx):
47893da
         "console"   : ["char_type", "target_type", "target_port"],
47893da
         "graphics"  : ["type", "vmmindex"],
47893da
         "controller" : ["type", "index"],
47893da
+        "channel"   : ["char_type", "target_name"],
47893da
     }
47893da
 
47893da
     if id(origdev) == id(newdev):
47893da
@@ -713,8 +714,9 @@ class vmmDomainBase(vmmLibvirtObject):
47893da
         serials     = self._build_device_list("serial")
47893da
         parallels   = self._build_device_list("parallel")
47893da
         consoles    = self._build_device_list("console")
47893da
+        channels    = self._build_device_list("channel")
47893da
 
47893da
-        for devicelist in [serials, parallels, consoles]:
47893da
+        for devicelist in [serials, parallels, consoles, channels]:
47893da
             devs.extend(devicelist)
47893da
 
47893da
         # Don't display <console> if it's just a duplicate of <serial>
47893da
commit 127e065d9ee7c5bee0f221352e51fb51ccff1626
47893da
Author: Marc-André Lureau <marcandre.lureau@redhat.com>
47893da
Date:   Tue Apr 5 01:35:33 2011 +0200
47893da
47893da
    details: show char device target name
47893da
47893da
diff --git a/src/virtManager/details.py b/src/virtManager/details.py
47893da
index ca21c2d..8e6e50e 100644
47893da
--- a/src/virtManager/details.py
47893da
+++ b/src/virtManager/details.py
47893da
@@ -2495,6 +2495,7 @@ class vmmDetails(vmmGObjectUI):
47893da
         target_port = chardev.target_port
47893da
         dev_type = chardev.char_type or "pty"
47893da
         src_path = chardev.source_path
47893da
+        target_name = chardev.target_name
47893da
         primary = hasattr(chardev, "virtmanager_console_dup")
47893da
 
47893da
         typelabel = ""
47893da
@@ -2518,6 +2519,7 @@ class vmmDetails(vmmGObjectUI):
47893da
         self.window.get_widget("char-type").set_markup(typelabel)
47893da
         self.window.get_widget("char-dev-type").set_text(dev_type)
47893da
         self.window.get_widget("char-source-path").set_text(src_path or "-")
47893da
+        self.window.get_widget("char-target-name").set_text(target_name or "-")
47893da
 
47893da
     def refresh_hostdev_page(self):
47893da
         hostdev = self.get_hw_selection(HW_LIST_COL_DEVICE)
47893da
diff --git a/src/vmm-details.glade b/src/vmm-details.glade
47893da
index d0d3837..d23c3da 100644
47893da
--- a/src/vmm-details.glade
47893da
+++ b/src/vmm-details.glade
47893da
@@ -4681,7 +4681,7 @@ I/O:</property>
47893da
                                           <widget class="GtkTable" id="table37">
47893da
                                             <property name="visible">True</property>
47893da
                                             <property name="border_width">3</property>
47893da
-                                            <property name="n_rows">2</property>
47893da
+                                            <property name="n_rows">3</property>
47893da
                                             <property name="n_columns">2</property>
47893da
                                             <property name="column_spacing">8</property>
47893da
                                             <property name="row_spacing">4</property>
47893da
@@ -4689,7 +4689,7 @@ I/O:</property>
47893da
                                               <widget class="GtkLabel" id="label503">
47893da
                                                 <property name="visible">True</property>
47893da
                                                 <property name="xalign">1</property>
47893da
-                                                <property name="label" translatable="yes">Device Type:</property>
47893da
+                                                <property name="label" translatable="yes">Device type:</property>
47893da
                                               </widget>
47893da
                                               <packing>
47893da
                                                 <property name="x_options">GTK_FILL</property>
47893da
@@ -4700,7 +4700,7 @@ I/O:</property>
47893da
                                               <widget class="GtkLabel" id="label505">
47893da
                                                 <property name="visible">True</property>
47893da
                                                 <property name="xalign">1</property>
47893da
-                                                <property name="label" translatable="yes">Source Path:</property>
47893da
+                                                <property name="label" translatable="yes">Source path:</property>
47893da
                                               </widget>
47893da
                                               <packing>
47893da
                                                 <property name="top_attach">1</property>
47893da
@@ -4710,6 +4710,19 @@ I/O:</property>
47893da
                                               </packing>
47893da
                                             </child>
47893da
                                             <child>
47893da
+                                              <widget class="GtkLabel" id="label505">
47893da
+                                                <property name="visible">True</property>
47893da
+                                                <property name="xalign">1</property>
47893da
+                                                <property name="label" translatable="yes">Target name:</property>
47893da
+                                              </widget>
47893da
+                                              <packing>
47893da
+                                                <property name="top_attach">2</property>
47893da
+                                                <property name="bottom_attach">3</property>
47893da
+                                                <property name="x_options">GTK_FILL</property>
47893da
+                                                <property name="y_options"></property>
47893da
+                                              </packing>
47893da
+                                            </child>
47893da
+                                            <child>
47893da
                                               <widget class="GtkLabel" id="char-dev-type">
47893da
                                                 <property name="visible">True</property>
47893da
                                                 <property name="xalign">0</property>
47893da
@@ -4739,6 +4752,22 @@ I/O:</property>
47893da
                                                 <property name="y_options"></property>
47893da
                                               </packing>
47893da
                                             </child>
47893da
+                                            <child>
47893da
+                                              <widget class="GtkLabel" id="char-target-name">
47893da
+                                                <property name="visible">True</property>
47893da
+                                                <property name="xalign">0</property>
47893da
+                                                <property name="label" translatable="yes">label508</property>
47893da
+                                                <property name="selectable">True</property>
47893da
+                                              </widget>
47893da
+                                              <packing>
47893da
+                                                <property name="left_attach">1</property>
47893da
+                                                <property name="right_attach">2</property>
47893da
+                                                <property name="top_attach">2</property>
47893da
+                                                <property name="bottom_attach">3</property>
47893da
+                                                <property name="x_options">GTK_FILL</property>
47893da
+                                                <property name="y_options"></property>
47893da
+                                              </packing>
47893da
+                                            </child>
47893da
                                           </widget>
47893da
                                         </child>
47893da
                                       </widget>
47893da
commit 69ba897ac35731bf6cfca00a3e8ac30485a9855d
47893da
Author: Marc-André Lureau <marcandre.lureau@redhat.com>
47893da
Date:   Tue Apr 5 01:35:34 2011 +0200
47893da
47893da
    details: propose to add or remove Spice agent when switching
47893da
    
47893da
    crobinso: Improve metric for deciding to ask about add/remove agent
47893da
47893da
diff --git a/src/virtManager/details.py b/src/virtManager/details.py
47893da
index 8e6e50e..eb5a9e5 100644
47893da
--- a/src/virtManager/details.py
47893da
+++ b/src/virtManager/details.py
47893da
@@ -1850,17 +1850,54 @@ class vmmDetails(vmmGObjectUI):
47893da
                                           (dev_id_info, nettype, source)])
47893da
 
47893da
     # Graphics options
47893da
+    def _do_change_spicevmc(self, gdev, newgtype):
47893da
+        has_multi_spice = (len(filter(
47893da
+                                lambda dev: dev.type == dev.TYPE_SPICE,
47893da
+                                self.vm.get_graphics_devices())) > 1)
47893da
+        has_spicevmc = bool(filter(
47893da
+                            (lambda dev:
47893da
+                                (dev.dev_type == dev.DEV_CHANNEL and
47893da
+                                 dev.char_type == dev.CHAR_SPICEVMC)),
47893da
+                            self.vm.get_char_devices()))
47893da
+        fromspice = (gdev.type == "spice")
47893da
+        tospice = (newgtype == "spice")
47893da
+
47893da
+        if fromspice and tospice:
47893da
+            return False
47893da
+        if not fromspice and not tospice:
47893da
+            return False
47893da
+
47893da
+        print tospice, fromspice, has_spicevmc, has_multi_spice
47893da
+
47893da
+        if tospice and has_spicevmc:
47893da
+            return False
47893da
+        if fromspice and not has_spicevmc:
47893da
+            return False
47893da
+
47893da
+        if fromspice and has_multi_spice:
47893da
+            # Don't offer to remove if there are other spice displays
47893da
+            return False
47893da
+
47893da
+        msg = (_("You are switching graphics type to %(gtype)s, "
47893da
+                 "would you like to %(action)s Spice agent channels?") %
47893da
+                {"gtype": newgtype,
47893da
+                 "action": fromspice and "remove" or "add"})
47893da
+        return self.err.yes_no(msg)
47893da
+
47893da
     def config_graphics_apply(self, dev_id_info):
47893da
         gtype = self.get_combo_label_value("gfx-type")
47893da
         passwd = self.window.get_widget("gfx-password").get_text() or None
47893da
         keymap = self.get_combo_label_value("gfx-keymap")
47893da
 
47893da
+        change_spicevmc = self._do_change_spicevmc(dev_id_info, gtype)
47893da
+
47893da
         return self._change_config_helper([self.vm.define_graphics_password,
47893da
                                            self.vm.define_graphics_keymap,
47893da
                                            self.vm.define_graphics_type],
47893da
                                           [(dev_id_info, passwd),
47893da
                                            (dev_id_info, keymap),
47893da
-                                           (dev_id_info, gtype)],
47893da
+                                           (dev_id_info, gtype,
47893da
+                                            change_spicevmc)],
47893da
                                           [self.vm.hotplug_graphics_password],
47893da
                                           [(dev_id_info, passwd)])
47893da
 
47893da
diff --git a/src/virtManager/domain.py b/src/virtManager/domain.py
47893da
index 7fc66ed..a4d2f5c 100644
47893da
--- a/src/virtManager/domain.py
47893da
+++ b/src/virtManager/domain.py
47893da
@@ -26,6 +26,7 @@ import threading
47893da
 import gobject
47893da
 
47893da
 import virtinst
47893da
+from virtinst.VirtualCharDevice import VirtualCharSpicevmcDevice
47893da
 from virtManager import util
47893da
 import virtinst.support as support
47893da
 
47893da
@@ -450,9 +451,20 @@ class vmmDomainBase(vmmLibvirtObject):
47893da
         def change(editdev):
47893da
             editdev.keymap = newval
47893da
         return self._redefine_device(change, devobj)
47893da
-    def define_graphics_type(self, devobj, newval):
47893da
+    def define_graphics_type(self, devobj, newval, spicevmc):
47893da
         def change(editdev):
47893da
             editdev.type = newval
47893da
+            if spicevmc:
47893da
+                guest = self._get_guest_to_define()
47893da
+                if newval == "spice":
47893da
+                    guest.add_device(VirtualCharSpicevmcDevice(guest.conn))
47893da
+                else:
47893da
+                    channels = guest.get_devices("channel")
47893da
+                    channels = filter(lambda x: x.char_type ==
47893da
+                                      virtinst.VirtualCharDevice.CHAR_SPICEVMC, channels)
47893da
+                    for dev in channels:
47893da
+                        guest.remove_device(dev)
47893da
+
47893da
         return self._redefine_device(change, devobj)
47893da
 
47893da
     def define_sound_model(self, devobj, newmodel):