Skip to content
This repository was archived by the owner on Jan 22, 2026. It is now read-only.

Commit 35dde72

Browse files
committed
virt-clone: Add --clone-running option
Skips shutoff/paused check to allow cloning running VMs. Useful for testing.
1 parent 070699e commit 35dde72

3 files changed

Lines changed: 20 additions & 1 deletion

File tree

tests/clitest.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,11 +576,15 @@
576576
"--original-xml %(CLONE_DISK_XML)s --auto-clone",
577577
# Auto flag w/ managed storage,
578578
"--original-xml %(CLONE_STORAGE_XML)s --auto-clone",
579+
# Auto flag, actual VM, skip state check
580+
"-o test-for-clone --auto-clone --clone-running",
579581
],
580582

581583
"invalid" : [
582584
# Just the auto flag
583585
"--auto-clone"
586+
# Auto flag, actual VM, without state skip
587+
"-o test-for-clone --auto-clone",
584588
]
585589
}, # category "misc"
586590

virt-clone

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ def parse_args():
190190
help=_("Do not prompt for input. Answers yes where "
191191
"applicable, terminates for all other prompts"),
192192
default=False)
193+
misc.add_option("", "--clone-running", action="store_true",
194+
dest="clone_running", default=False,
195+
help=_("Allow cloning a running domain"))
193196
parser.add_option_group(misc)
194197

195198
(options, dummy) = parser.parse_args()
@@ -211,6 +214,7 @@ def main():
211214
design = clmgr.CloneDesign(connection=conn)
212215

213216
try:
217+
design.clone_running = options.clone_running
214218
get_original_guest(options.original_guest, options.original_xml,
215219
design)
216220
get_clone_name(options.new_name, options.auto_clone, design)

virtinst/CloneManager.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ def __init__(self, connection):
128128
self._force_target = []
129129
self._skip_target = []
130130
self._preserve = True
131+
self._clone_running = False
131132

132133
# Default clone policy for back compat: don't clone readonly,
133134
# shareable, or empty disks
@@ -368,6 +369,15 @@ def get_clone_policy(self):
368369
doc="List of policy rules for determining which "
369370
"vm disks to clone. See CLONE_POLICY_*")
370371

372+
def get_clone_running(self):
373+
return self._clone_running
374+
def set_clone_running(self, val):
375+
self._clone_running = bool(val)
376+
clone_running = property(get_clone_running, set_clone_running,
377+
doc="Allow cloning a running VM. If enabled, "
378+
"domain state is not checked before "
379+
"cloning.")
380+
371381
# Functional methods
372382

373383
def setup_original(self):
@@ -390,7 +400,8 @@ def setup_original(self):
390400
logging.debug("Original sizes: %s" % (self.original_devices_size))
391401

392402
# If domain has devices to clone, it must be 'off' or 'paused'
393-
if self._original_dom and len(self.original_devices) != 0:
403+
if (not self.clone_running and
404+
(self._original_dom and len(self.original_devices) != 0)):
394405
status = self._original_dom.info()[0]
395406

396407
if status not in [libvirt.VIR_DOMAIN_SHUTOFF,

0 commit comments

Comments
 (0)