[virt-tools-list] [virt-manager PATCH 2/2] virt-clone: add support to clone nvram VARS

Pavel Hrdina phrdina at redhat.com
Mon Mar 6 08:43:51 UTC 2017


Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1243335

Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
---
 man/virt-clone.pod                 |  6 ++++++
 tests/clone-xml/nvram-auto-in.xml  | 23 +++++++++++++++++++++++
 tests/clone-xml/nvram-auto-out.xml | 23 +++++++++++++++++++++++
 tests/clonetest.py                 |  4 ++++
 tests/testdriver.xml               | 27 +++++++++++++++++++++++++++
 virt-clone                         |  4 ++++
 virtinst/cloner.py                 | 34 ++++++++++++++++++++++++++++++++++
 7 files changed, 121 insertions(+)
 create mode 100644 tests/clone-xml/nvram-auto-in.xml
 create mode 100644 tests/clone-xml/nvram-auto-out.xml

diff --git a/man/virt-clone.pod b/man/virt-clone.pod
index dd04747f..bd98ae33 100644
--- a/man/virt-clone.pod
+++ b/man/virt-clone.pod
@@ -88,6 +88,12 @@ for the new guest's virtual disk. If the original guest has multiple disks,
 this parameter must be repeated multiple times, once per disk in the original
 virtual machine.
 
+=item B<--nvram> NVRAMFILE
+
+Optional path to the new nvram VARS file, if no path is specified and the
+guest has nvram the new nvram path will be auto-generated. If the guest
+doesn't have nvram this option will be ignored.
+
 =item B<--force-copy> TARGET
 
 Force cloning the passed disk target ('hdc', 'sda', etc.). By default,
diff --git a/tests/clone-xml/nvram-auto-in.xml b/tests/clone-xml/nvram-auto-in.xml
new file mode 100644
index 00000000..dc95f6ac
--- /dev/null
+++ b/tests/clone-xml/nvram-auto-in.xml
@@ -0,0 +1,23 @@
+<domain type='kvm'>
+  <name>clone-orig</name>
+  <uuid>aaa3ae22-fed2-bfbd-ac02-3bea3bcfad82</uuid>
+  <memory>262144</memory>
+  <currentMemory>262144</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='cdrom'/>
+    <loader readonly='yes' type='pflash'>/usr/share/ovmf/ovmf-efi.fd</loader>
+    <nvram>/nvram/clone-orig_VARS.fd</nvram>
+  </os>
+  <features>
+    <acpi/>
+  </features>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-kvm</emulator>
+  </devices>
+</domain>
diff --git a/tests/clone-xml/nvram-auto-out.xml b/tests/clone-xml/nvram-auto-out.xml
new file mode 100644
index 00000000..c59eaea8
--- /dev/null
+++ b/tests/clone-xml/nvram-auto-out.xml
@@ -0,0 +1,23 @@
+<domain type="kvm">
+  <name>clone-new</name>
+  <uuid>12345678-1234-1234-1234-123456789012</uuid>
+  <memory>262144</memory>
+  <currentMemory>262144</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch="i686" machine="pc">hvm</type>
+    <boot dev="cdrom"/>
+    <loader readonly="yes" type="pflash">/usr/share/ovmf/ovmf-efi.fd</loader>
+    <nvram>/nvram/clone-new_VARS.fd</nvram>
+  </os>
+  <features>
+    <acpi/>
+  </features>
+  <clock offset="utc"/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-kvm</emulator>
+  </devices>
+</domain>
diff --git a/tests/clonetest.py b/tests/clonetest.py
index ddab4f20..b9f0dd4a 100644
--- a/tests/clonetest.py
+++ b/tests/clonetest.py
@@ -175,3 +175,7 @@ class TestClone(unittest.TestCase):
             return
 
         raise AssertionError("Expected exception, but none raised.")
+
+    def testCloneNvramAuto(self):
+        base = "nvram-auto"
+        self._clone_helper(base)
diff --git a/tests/testdriver.xml b/tests/testdriver.xml
index 1f9f6c86..0107db42 100644
--- a/tests/testdriver.xml
+++ b/tests/testdriver.xml
@@ -2242,6 +2242,33 @@ ba</description>
   </source>
 </pool>
 
+<pool type="dir">
+  <name>nvram</name>
+  <source>
+  </source>
+  <target>
+    <path>/nvram</path>
+    <permissions>
+      <mode>0700</mode>
+      <owner>0</owner>
+      <group>0</group>
+    </permissions>
+  </target>
+
+  <volume type='file'>
+    <name>clone-orig_VARS.fd</name>
+    <capacity>1000</capacity>
+    <allocation>1000</allocation>
+    <target>
+      <permissions>
+        <mode>0700</mode>
+        <owner>0</owner>
+        <group>0</group>
+      </permissions>
+    </target>
+  </volume>
+
+</pool>
 
 
 
diff --git a/virt-clone b/virt-clone
index 905c91ed..572977a9 100755
--- a/virt-clone
+++ b/virt-clone
@@ -136,6 +136,8 @@ def parse_args():
                     dest="preserve", default=True,
                     help=_("Do not clone storage, new disk images specified "
                            "via --file are preserved unchanged"))
+    stog.add_argument("--nvram", dest="new_nvram",
+                      help=_("New file to use as storage for nvram VARS"))
 
     netg = parser.add_argument_group(_("Networking Configuration"))
     netg.add_argument("-m", "--mac", dest="new_mac", action="append",
@@ -192,6 +194,8 @@ def main(conn=None):
     design.clone_sparse = options.sparse
     design.preserve = options.preserve
 
+    design.clone_nvram = options.new_nvram
+
     # This determines the devices that need to be cloned, so that
     # get_clone_diskfile knows how many new disk paths it needs
     design.setup_original()
diff --git a/virtinst/cloner.py b/virtinst/cloner.py
index 5255acfe..66a2bca9 100644
--- a/virtinst/cloner.py
+++ b/virtinst/cloner.py
@@ -57,6 +57,8 @@ class Cloner(object):
         self._clone_uuid = None
         self._clone_sparse = True
         self._clone_xml = None
+        self.clone_nvram = None
+        self._nvram_disk = None
 
         self._force_target = []
         self._skip_target = []
@@ -361,6 +363,33 @@ class Cloner(object):
         clone_disk.validate()
 
 
+    def _prepare_nvram(self):
+        if self.clone_nvram is None:
+            nvram_dir = os.path.dirname(self._guest.os.nvram)
+            self.clone_nvram = os.path.join(nvram_dir,
+                                            "%s_VARS.fd" % self._clone_name)
+
+        nvram = VirtualDisk(self.conn)
+        nvram.path = self.clone_nvram
+        if (not self.preserve_dest_disks and
+            nvram.wants_storage_creation()):
+
+            old_nvram = VirtualDisk(self.conn)
+            old_nvram.path = self._guest.os.nvram
+
+            nvram_install = VirtualDisk.build_vol_install(
+                    self.conn, os.path.basename(nvram.path),
+                    nvram.get_parent_pool(), nvram.get_size(), False)
+            nvram_install.input_vol = old_nvram.get_vol_object()
+            nvram_install.sync_input_vol(only_format=True)
+            nvram_install.reflink = self.reflink
+            nvram.set_vol_install(nvram_install)
+
+        nvram.validate()
+        self._nvram_disk = nvram
+        self._guest.os.nvram = nvram.path
+
+
     def setup_clone(self):
         """
         Validate and set up all parameters needed for the new (clone) VM
@@ -420,6 +449,9 @@ class Cloner(object):
             if channel.type == VirtualChannelDevice.TYPE_UNIX:
                 channel.source_path = None
 
+        if self._guest.os.nvram:
+            self._prepare_nvram()
+
         # Save altered clone xml
         self._clone_xml = self._guest.get_xml_config()
         logging.debug("Clone guest xml is\n%s", self._clone_xml)
@@ -452,6 +484,8 @@ class Cloner(object):
             if self.preserve:
                 for dst_dev in self.clone_disks:
                     dst_dev.setup(meter=meter)
+                if self._nvram_disk:
+                    self._nvram_disk.setup(meter=meter)
         except Exception, e:
             logging.debug("Duplicate failed: %s", str(e))
             if dom:
-- 
2.12.0




More information about the virt-tools-list mailing list