[virt-tools-list] [PATCH 1/2] Add GUI and basic functionality to support virtuozzo hypervisor

Mikhail Feoktistov mfeoktistov at virtuozzo.com
Thu Apr 14 08:54:10 UTC 2016


GUI changes:
Add virtuozzo hypervisor to connection list.
Add radio buttons for choosing VM or container virtualization type.
New wizzard window for setting template name for containers.

Creating guest:
We don't call createXML() for virtuozzo guests, because
virtuozzo driver in libvirt doesn't support transient domains.
Instead of this we call defineXML() and createDomain().

If we create container from template we generate XML which
contains only one storage device with type "template".
Virtuozzo hypervisor will create new container and filesystem for it.
After container was created we should not call the second
defineXML(final_xml) because it rewrites "devices" section in XML
and deletes container filesytem.
---
 ui/create.ui              | 155 +++++++++++++++++++++++++++++++++++++++++++++-
 virtManager/connect.py    |   8 ++-
 virtManager/connection.py |   1 +
 virtManager/create.py     |  58 ++++++++++++++++-
 virtinst/connection.py    |   3 +
 virtinst/guest.py         |  24 ++++++-
 virtinst/support.py       |   2 +-
 7 files changed, 240 insertions(+), 11 deletions(-)

diff --git a/ui/create.ui b/ui/create.ui
index 4185cd1..96a0921 100644
--- a/ui/create.ui
+++ b/ui/create.ui
@@ -143,9 +143,89 @@
                             <property name="vexpand">False</property>
                             <property name="row_spacing">12</property>
                             <child>
+                              <object class="GtkVBox" id="vz-install-box">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="spacing">8</property>
+                                <child>
+                                  <object class="GtkLabel" id="label39">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="label" translatable="yes">Choose virtualization type</property>
+                                    <property name="xalign">0</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkAlignment" id="alignment3">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="left_padding">15</property>
+                                    <child>
+                                      <object class="GtkVBox" id="vbox5">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="spacing">3</property>
+                                        <child>
+                                          <object class="GtkRadioButton" id="vz-virt-type-hvm">
+                                            <property name="label" translatable="yes">_Virtual machine</property>
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="receives_default">False</property>
+                                            <property name="use_underline">True</property>
+                                            <property name="xalign">0</property>
+                                            <property name="active">True</property>
+                                            <property name="draw_indicator">True</property>
+                                            <signal name="toggled" handler="on_vz_virt_type_changed" swapped="no"/>
+                                          </object>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="fill">False</property>
+                                            <property name="position">0</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkRadioButton" id="vz-virt-type-exe">
+                                            <property name="label" translatable="yes">_Container</property>
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="receives_default">False</property>
+                                            <property name="use_underline">True</property>
+                                            <property name="xalign">0</property>
+                                            <property name="draw_indicator">True</property>
+                                            <property name="group">vz-virt-type-hvm</property>
+                                            <signal name="toggled" handler="on_vz_virt_type_changed" swapped="no"/>
+                                          </object>
+                                          <packing>
+                                            <property name="expand">False</property>
+                                            <property name="fill">False</property>
+                                            <property name="position">1</property>
+                                          </packing>
+                                        </child>
+                                      </object>
+                                    </child>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="left_attach">0</property>
+                                <property name="top_attach">0</property>
+                              </packing>
+                            </child>
+                            <child>
                               <object class="GtkVBox" id="virt-install-box">
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
+                                <property name="no_show_all">True</property>
                                 <property name="vexpand">False</property>
                                 <property name="spacing">8</property>
                                 <child>
@@ -255,7 +335,7 @@
                               </object>
                               <packing>
                                 <property name="left_attach">0</property>
-                                <property name="top_attach">0</property>
+                                <property name="top_attach">1</property>
                               </packing>
                             </child>
                             <child>
@@ -334,7 +414,7 @@
                               </object>
                               <packing>
                                 <property name="left_attach">0</property>
-                                <property name="top_attach">1</property>
+                                <property name="top_attach">2</property>
                               </packing>
                             </child>
                           </object>
@@ -1620,6 +1700,76 @@ is not yet supported.</small></property>
                                 <property name="tab_fill">False</property>
                               </packing>
                             </child>
+                            <child>
+                              <object class="GtkVBox" id="vbozzz1">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="spacing">6</property>
+                                <child>
+                                  <object class="GtkLabel" id="label53">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="label" translatable="yes">Select container template</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="mnemonic_widget">install-oscontainer-fs</property>
+                                    <property name="xalign">0</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkAlignment" id="alignment4">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="left_padding">12</property>
+                                    <child>
+                                      <object class="GtkHBox" id="hbox6">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="spacing">6</property>
+                                        <child>
+                                          <object class="GtkEntry" id="vz-template">
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="text" translatable="yes">centos-6-x86_64</property>
+                                          </object>
+                                          <packing>
+                                            <property name="expand">True</property>
+                                            <property name="fill">True</property>
+                                            <property name="position">0</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <placeholder/>
+                                        </child>
+                                      </object>
+                                    </child>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="position">6</property>
+                              </packing>
+                            </child>
+                            <child type="tab">
+                              <object class="GtkLabel" id="label52">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="label" translatable="yes">VZ templates</property>
+                              </object>
+                              <packing>
+                                <property name="position">6</property>
+                                <property name="tab_fill">False</property>
+                              </packing>
+                            </child>
                           </object>
                           <packing>
                             <property name="expand">True</property>
@@ -2650,4 +2800,5 @@ is not yet supported.</small></property>
       </object>
     </child>
   </object>
+  <object class="GtkListStore" id="liststore1"/>
 </interface>
diff --git a/virtManager/connect.py b/virtManager/connect.py
index 30add14..4cec8ca 100644
--- a/virtManager/connect.py
+++ b/virtManager/connect.py
@@ -34,7 +34,8 @@ from .baseclass import vmmGObjectUI
 HV_XEN,
 HV_LXC,
 HV_QEMU_SESSION,
-HV_BHYVE) = range(5)
+HV_BHYVE,
+HV_VZ) = range(6)
 
 (CONN_SSH,
 CONN_TCP,
@@ -169,6 +170,7 @@ class vmmConnect(vmmGObjectUI):
         _add_hv_row(HV_XEN, "xen", "Xen")
         _add_hv_row(HV_LXC, "lxc", "LXC (" + _("Linux Containers") + ")")
         _add_hv_row(HV_BHYVE, "bhyve", "Bhyve")
+        _add_hv_row(HV_VZ, "vz", "Virtuozzo")
         combo.set_model(model)
         uiutil.init_combo_text_column(combo, 1)
 
@@ -384,6 +386,8 @@ class vmmConnect(vmmGObjectUI):
             hvstr = "qemu"
         elif hv == HV_BHYVE:
             hvstr = "bhyve"
+        elif hv == HV_VZ:
+            hvstr = "vz"
         else:
             hvstr = "lxc"
 
@@ -408,7 +412,7 @@ class vmmConnect(vmmGObjectUI):
             hoststr += addrstr + "/"
 
         uri = hvstr + hoststr
-        if hv in (HV_QEMU, HV_BHYVE):
+        if hv in (HV_QEMU, HV_BHYVE, HV_VZ):
             uri += "system"
         elif hv == HV_QEMU_SESSION:
             uri += "session"
diff --git a/virtManager/connection.py b/virtManager/connection.py
index ce0afbf..2476fb8 100644
--- a/virtManager/connection.py
+++ b/virtManager/connection.py
@@ -343,6 +343,7 @@ class vmmConnection(vmmGObject):
     is_container = property(lambda s: getattr(s, "_backend").is_container)
     is_lxc = property(lambda s: getattr(s, "_backend").is_lxc)
     is_openvz = property(lambda s: getattr(s, "_backend").is_openvz)
+    is_vz = property(lambda s: getattr(s, "_backend").is_vz)
     is_xen = property(lambda s: getattr(s, "_backend").is_xen)
     is_remote = property(lambda s: getattr(s, "_backend").is_remote)
     is_qemu = property(lambda s: getattr(s, "_backend").is_qemu)
diff --git a/virtManager/create.py b/virtManager/create.py
index ca83674..188c887 100644
--- a/virtManager/create.py
+++ b/virtManager/create.py
@@ -56,7 +56,8 @@ DEFAULT_MEM = 1024
  INSTALL_PAGE_PXE,
  INSTALL_PAGE_IMPORT,
  INSTALL_PAGE_CONTAINER_APP,
- INSTALL_PAGE_CONTAINER_OS) = range(6)
+ INSTALL_PAGE_CONTAINER_OS,
+ INSTALL_PAGE_VZ_TEMPLATE) = range(7)
 
 # Column numbers for os type/version list models
 (OS_COL_ID,
@@ -154,6 +155,7 @@ class vmmCreate(vmmGObjectUI):
             "on_arch_changed": self._arch_changed,
             "on_virt_type_changed": self._virt_type_changed,
             "on_machine_changed": self._machine_changed,
+            "on_vz_virt_type_changed": self._vz_virt_type_changed,
 
             "on_install_cdrom_radio_toggled": self._local_media_toggled,
             "on_install_iso_entry_changed": self._iso_changed,
@@ -370,6 +372,7 @@ class vmmCreate(vmmGObjectUI):
         self.widget("create-conn").set_active(-1)
         activeconn = self._populate_conn_list(urihint)
         self.widget("arch-expander").set_expanded(False)
+        self.widget("vz-virt-type-hvm").set_active(True)
 
         if self._set_conn(activeconn) is False:
             return False
@@ -436,6 +439,7 @@ class vmmCreate(vmmGObjectUI):
         can_storage = (is_local or is_storage_capable)
         is_pv = (self._capsinfo.os_type == "xen")
         is_container = self.conn.is_container()
+        is_vz = self.conn.is_vz()
         can_remote_url = self.conn.get_backend().support_remote_url_install()
 
         installable_arch = (self._capsinfo.arch in
@@ -517,6 +521,7 @@ class vmmCreate(vmmGObjectUI):
         method_container_app.set_active(True)
         self.widget("virt-install-box").set_visible(not is_container)
         self.widget("container-install-box").set_visible(is_container)
+        self.widget("vz-install-box").set_visible(is_vz)
 
         show_dtb = ("arm" in self._capsinfo.arch or
                     "microblaze" in self._capsinfo.arch or
@@ -580,6 +585,21 @@ class vmmCreate(vmmGObjectUI):
                  "are not loaded. Your virtual machines may perform poorly.")
                 self._show_startup_warning(error)
 
+        elif self.conn.is_vz():
+            has_hvm_guests = False
+            has_exe_guests = False
+            for g in self.conn.caps.guests:
+                if g.os_type == "hvm":
+                    has_hvm_guests = True
+                if g.os_type == "exe":
+                    has_exe_guests = True
+
+            self.widget("vz-virt-type-hvm").set_sensitive(has_hvm_guests)
+            self.widget("virt-install-box").set_sensitive(has_hvm_guests)
+            self.widget("vz-virt-type-exe").set_sensitive(has_exe_guests)
+            if not has_hvm_guests and has_exe_guests:
+                self.widget("vz-virt-type-exe").set_active(True)
+
         # Install local
         iso_option = self.widget("install-iso-radio")
         cdrom_option = self.widget("install-cdrom-radio")
@@ -1069,6 +1089,8 @@ class vmmCreate(vmmGObjectUI):
             install = _("Application container")
         elif instmethod == INSTALL_PAGE_CONTAINER_OS:
             install = _("Operating system container")
+        elif instmethod == INSTALL_PAGE_VZ_TEMPLATE:
+            install = self.widget("vz-template").get_text()
 
         osstr = ""
         have_os = True
@@ -1105,6 +1127,9 @@ class vmmCreate(vmmGObjectUI):
             check_visible=True)
 
     def _get_config_install_page(self):
+        if self.widget("vz-install-box").get_visible():
+            if self.widget("vz-virt-type-exe").get_active():
+                return INSTALL_PAGE_VZ_TEMPLATE
         if self.widget("virt-install-box").get_visible():
             if self.widget("method-local").get_active():
                 return INSTALL_PAGE_ISO
@@ -1122,11 +1147,13 @@ class vmmCreate(vmmGObjectUI):
 
     def _is_container_install(self):
         return self._get_config_install_page() in [INSTALL_PAGE_CONTAINER_APP,
-                                                   INSTALL_PAGE_CONTAINER_OS]
+                                                   INSTALL_PAGE_CONTAINER_OS,
+                                                   INSTALL_PAGE_VZ_TEMPLATE]
     def _should_skip_disk_page(self):
         return self._get_config_install_page() in [INSTALL_PAGE_IMPORT,
                                                    INSTALL_PAGE_CONTAINER_APP,
-                                                   INSTALL_PAGE_CONTAINER_OS]
+                                                   INSTALL_PAGE_CONTAINER_OS,
+                                                   INSTALL_PAGE_VZ_TEMPLATE]
 
     def _get_config_os_info(self):
         drow = uiutil.get_list_selected_row(self.widget("install-os-type"))
@@ -1289,6 +1316,13 @@ class vmmCreate(vmmGObjectUI):
 
         self._change_caps(self._capsinfo.os_type, self._capsinfo.arch, domtype)
 
+    def _vz_virt_type_changed(self, ignore):
+        is_hvm = self.widget("vz-virt-type-hvm").get_active()
+        self.widget("virt-install-box").set_sensitive(is_hvm)
+        if is_hvm:
+            self._change_caps("hvm")
+        else:
+            self._change_caps("exe")
 
     # Install page listeners
     def _detectable_media_widget_changed(self, widget, checkfocus=True):
@@ -1670,6 +1704,9 @@ class vmmCreate(vmmGObjectUI):
             guest.x86_cpu_default = self.config.get_default_cpu_setting(
                 for_cpu=True)
 
+            if guest.conn.is_vz():
+                guest.skip_default_console = True
+
             guest.add_default_devices()
         except Exception, e:
             self.err.show_err(_("Error setting up default devices:") + str(e))
@@ -1737,6 +1774,7 @@ class vmmCreate(vmmGObjectUI):
         is_import = False
         init = None
         fs = None
+        template = None
         distro, variant, valid, ignore1, ignore2 = self._get_config_os_info()
 
         if not valid:
@@ -1788,6 +1826,12 @@ class vmmCreate(vmmGObjectUI):
             if not fs:
                 return self.err.val_err(_("An OS directory path is required."))
 
+        elif instmethod == INSTALL_PAGE_VZ_TEMPLATE:
+            instclass = virtinst.ContainerInstaller
+            template = self.widget("vz-template").get_text()
+            if not template:
+                return self.err.val_err(_("A template name is required."))
+
         # Build the installer and Guest instance
         try:
             # Overwrite the guest
@@ -1818,6 +1862,14 @@ class vmmCreate(vmmGObjectUI):
                 fsdev.target = "/"
                 fsdev.source = fs
                 self._guest.add_device(fsdev)
+
+            if template:
+                fsdev = virtinst.VirtualFilesystem(self._guest.conn)
+                fsdev.target = "/"
+                fsdev.type = "template"
+                fsdev.source = template
+                self._guest.add_device(fsdev)
+
         except Exception, e:
             return self.err.val_err(
                                 _("Error setting install media location."), e)
diff --git a/virtinst/connection.py b/virtinst/connection.py
index a09f4df..14e8bff 100644
--- a/virtinst/connection.py
+++ b/virtinst/connection.py
@@ -382,6 +382,9 @@ class VirtualConnection(object):
         return self._uriobj.scheme.startswith("openvz")
     def is_container(self):
         return self.is_lxc() or self.is_openvz()
+    def is_vz(self):
+        return (self._uriobj.scheme.startswith("vz") or
+                self._uriobj.scheme.startswith("parallels"))
 
 
     #########################
diff --git a/virtinst/guest.py b/virtinst/guest.py
index da07410..5a2cda3 100644
--- a/virtinst/guest.py
+++ b/virtinst/guest.py
@@ -359,6 +359,11 @@ class Guest(XMLBuilder):
             self.on_reboot = "destroy"
             self.on_crash = "destroy"
 
+        if self.conn.is_vz():
+            self.on_reboot = "restart"
+            self.on_crash = "destroy"
+            self.on_poweroff = "destroy"
+
         self._set_osxml_defaults()
 
         self.bootloader = None
@@ -413,7 +418,11 @@ class Guest(XMLBuilder):
         doboot = not noboot or self.installer.has_install_phase()
 
         if is_initial and doboot:
-            dom = self.conn.createLinux(start_xml or final_xml, 0)
+            if self.conn.is_vz():
+                dom = self.conn.defineXML(start_xml or final_xml)
+                dom.create()
+            else:
+                dom = self.conn.createLinux(start_xml or final_xml, 0)
         else:
             dom = self.conn.defineXML(start_xml or final_xml)
             if doboot:
@@ -422,7 +431,9 @@ class Guest(XMLBuilder):
         self.domain = dom
         meter.end(0)
 
-        self.domain = self.conn.defineXML(final_xml)
+        if start_xml != None and start_xml != final_xml:
+            self.domain = self.conn.defineXML(final_xml)
+
         if is_initial:
             try:
                 logging.debug("XML fetched from libvirt object:\n%s",
@@ -679,7 +690,7 @@ class Guest(XMLBuilder):
             return
         if self.get_devices("graphics"):
             return
-        if self.os.is_container():
+        if self.os.is_container() and not self.conn.is_vz():
             return
         if self.os.arch not in ["x86_64", "i686", "ppc64", "ppc64le", "ia64"]:
             return
@@ -812,6 +823,10 @@ class Guest(XMLBuilder):
             self.emulator = None
             return
 
+        if self.conn.is_vz():
+            self.emulator = None
+            return
+
         if self.emulator:
             return
 
@@ -868,6 +883,9 @@ class Guest(XMLBuilder):
                     self.clock.remove_timer(i)
 
     def _set_feature_defaults(self):
+        if self.conn.is_vz():
+            return
+
         if self.os.is_container():
             self.features.acpi = None
             self.features.apic = None
diff --git a/virtinst/support.py b/virtinst/support.py
index 4b3a945..23e3957 100644
--- a/virtinst/support.py
+++ b/virtinst/support.py
@@ -258,7 +258,7 @@ SUPPORT_CONN_DISK_SD = _make(version="1.1.2")
 # default to qcow2. It might be fine for xen or qemu older than the versions
 # here, but until someone tests things I'm going to be a bit conservative.
 SUPPORT_CONN_DEFAULT_QCOW2 = _make(
-    version="0.8.0", hv_version={"qemu": "1.2.0", "test": 0})
+    version="0.8.0", hv_version={"qemu": "1.2.0", "test": 0, "vz": "7.0.0", "parallels": "7.0.0"})
 SUPPORT_CONN_DEFAULT_USB2 = _make(
     version="0.9.7", hv_version={"qemu": "1.0.0", "test": 0})
 SUPPORT_CONN_CAN_ACPI = _make(hv_version={"xen": "3.1.0", "all": 0})
-- 
2.5.5




More information about the virt-tools-list mailing list