[PATCH 1/2] cloner: clone serial files

Oleg Vasilev oleg.vasilev at virtuozzo.com
Fri Dec 2 08:45:10 UTC 2022


Before this, on clone the serial file would remain the same for the cloned
domain. This doesn't make much sense as the output would be an intermix of two
unrelated output sequences.

Here we apply the the same filename changing algorithm, as with disk files.

Signed-off-by: Oleg Vasilev <oleg.vasilev at virtuozzo.com>
---
 virtinst/cloner.py    | 32 +++++++++++++++++++++++++++-----
 virtinst/virtclone.py |  4 ++++
 2 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/virtinst/cloner.py b/virtinst/cloner.py
index 9334513c..4adc4479 100644
--- a/virtinst/cloner.py
+++ b/virtinst/cloner.py
@@ -9,6 +9,7 @@
 
 import re
 import os
+from itertools import chain
 
 import libvirt
 
@@ -20,6 +21,7 @@ from .devices import DeviceInterface
 from .devices import DeviceDisk
 from .logger import log
 from .devices import DeviceChannel
+from .devices import DeviceSerial
 
 
 def _replace_vm(conn, name):
@@ -70,9 +72,9 @@ def _generate_clone_name(conn, basename):
             sep="", start_num=start_num, force_num=force_num)
 
 
-def _generate_clone_disk_path(conn, origname, newname, origpath):
+def _generate_clone_path(origname, newname, origpath, cb):
     """
-    Generate desired cloned disk path name, derived from the
+    Generate desired cloned path for auxiliary files, derived from the
     original path, original VM name, and proposed new VM name
     """
     if origpath is None:
@@ -99,8 +101,6 @@ def _generate_clone_disk_path(conn, origname, newname, origpath):
         clonebase = newname
 
     clonebase = os.path.join(dirname, clonebase)
-    def cb(p):
-        return DeviceDisk.path_definitely_exists(conn, p)
     return generatename.generate_name(clonebase, cb, suffix=suffix)
 
 
@@ -287,7 +287,14 @@ class Cloner(object):
 
     @staticmethod
     def generate_clone_disk_path(conn, origname, newname, origpath):
-        return _generate_clone_disk_path(conn, origname, newname, origpath)
+        def cb(p):
+            return DeviceDisk.path_definitely_exists(conn, p)
+        return _generate_clone_path(origname, newname, origpath, cb)
+
+    @staticmethod
+    def generate_clone_serial_file_name(origname, newname, origpath):
+        return _generate_clone_path(origname, newname, origpath,
+                                    cb=os.path.exists)
 
     @staticmethod
     def build_clone_disk(orig_disk, clonepath, allow_create, sparse):
@@ -455,6 +462,21 @@ class Cloner(object):
     # Functional methods #
     ######################
 
+    def update_serial_files(self, auto_clone):
+        for serial in chain(self._new_guest.devices.console,
+                            self._new_guest.devices.serial):
+            if serial.type != DeviceSerial.TYPE_FILE:
+                continue
+            if not auto_clone:
+                return False
+
+            serial.source.path = \
+                Cloner.generate_clone_serial_file_name(self.src_name,
+                                                        self.new_guest.name,
+                                                        serial.source.path)
+        return True
+
+
     def _prepare_nvram(self):
         if not self._nvram_diskinfo:
             return
diff --git a/virtinst/virtclone.py b/virtinst/virtclone.py
index 5fbe9e35..18a0a3d3 100644
--- a/virtinst/virtclone.py
+++ b/virtinst/virtclone.py
@@ -182,6 +182,10 @@ def main(conn=None):
     _process_macs(options, cloner)
     _process_disks(options, cloner)
 
+    if not cloner.update_serial_files(options.auto_clone):
+        fail(_("Can't figure out serial file paths for the new guest"
+               " without autoclone."))
+
     cloner.prepare()
 
     _validate_disks(cloner)
-- 
2.38.1



More information about the virt-tools-list mailing list