On 12/05/2011 03:11 PM, Chris Evich wrote:
> Implimented vm.pause, vm.resume, vm.save_to_file, and
> vm.restore_from_file. Added a few virsh_* helper functions
> that should eventually go into libvirt.monitor class when
> it's working.
>
> Signed-off-by: Chris Evich<[email protected]>
> ---
> client/virt/libvirt_vm.py | 99
> +++++++++++++++++++++++++++++++++++++++++---
> 1 files changed, 92 insertions(+), 7 deletions(-)
>
> diff --git a/client/virt/libvirt_vm.py b/client/virt/libvirt_vm.py
> index a48809d..ef00414 100644
> --- a/client/virt/libvirt_vm.py
> +++ b/client/virt/libvirt_vm.py
> @@ -4,7 +4,7 @@ Utility classes and functions to handle Virtual Machine
> creation using qemu.
> @copyright: 2008-2009 Red Hat Inc.
> """
>
> -import time, os, logging, fcntl, re, commands
> +import time, os, logging, fcntl, re, commands, tempfile
> from autotest_lib.client.common_lib import error
> from autotest_lib.client.bin import utils, os_dep
> from xml.dom import minidom
> @@ -156,6 +156,75 @@ def virsh_resume(name, uri = ""):
> logging.error("Resume VM %s failed", name)
> return False
>
> +def __virsh_state_file_generate(name, uri = ""):
^ In order to ease unittesting, in general in autotest we avoid double
underscore. Double underscores are OK only if there's any benefit in
mangling the name and making it inaccessible from outside the class,
which is usually none :)
> + """
> + Internal function to generate absolute path to state file name
> +
> + @param: name: Name of VM to generate state filename for
> + @param: uri: URI of libvirt hypervisor to use
> + @return: absolute path to state filename
> + """
> + name_pfx = "virsh-saved-"
> + vm_uuid = virsh_uuid(name, uri) # avoid name clashes
> + tmpdir = tempfile.gettempdir()
> + filename = name_pfx + name + "-" + vm_uuid
> + return os.path.join(tmpdir, filename)
^ Here we could add some random string to the file name, to avoid
clashes of state files taken in different situations/running in parallel.
> +def virsh_save(name, uri = "", path = ""):
> + """
> + Store state of VM into named file or temporary file if not specified.
> +
> + @param: name: VM Name to operate on
> + @param: uri: URI of libvirt hypervisor to use
> + @param: path: absolute path to state file, generated under /tmp if ""
> + @return: True if libvirt command was successful, False otherwise.
> + """
> + state = virsh_domstate(name, uri)
> + if state not in ('running', 'idle', 'paused'):
> + logging.error("Cannot save a VM that is %s" % state)
> + return False
> + if path == "":
> + path = __virsh_state_file_generate(name,uri)
> + logging.debug("Saving VM %s to %s" %(name, path))
> + result = virsh_cmd("save %s %s" % (name,path))
> + if virsh_is_dead(name,uri): # assume dead b/c save was successful
> + return True
> + else:
> + logging.error("Saving VM failed")
> + return False
> +
> +def virsh_restore(name, uri = "", path = ""):
> + """
> + Load state of VM from named file or temporary file if not specified.
> +
> + Caution is needed to avoid corruption: State of VM's storage must not
> + have changed at all between save/restore. There is no reliable way to
> + check for this condition.
> +
> + @param: name: VM Name to operate on
> + @param: uri: URI of libvirt hypervisor to use
> + @param: path: absolute path to state file, generated under /tmp if ""
> + @return: True if libvirt command was successful, False otherwise.
> + """
> + if path == "":
> + path = __virsh_state_file_generate(name,uri)
> + # No easy way to check which VM was saved in state file
> + # assume coorespondence between 'name' and 'path' and
> + # do simple before/after not-running/running check also
> + state = virsh_domstate(name, uri)
> + if state not in ('shut off',):
> + logging.error("Cannon restore VM that is %s" % state)
> + return False
> + logging.debug("Restoring VM from %s" % path)
> + # Restore automatically removes the state file when successful
> + result = virsh_cmd("restore %s" % path)
> + state = virsh_domstate(name, uri)
> + if state in ('paused',):
> + return True
> + else:
> + logging.error("Restoring VM from %s failed in state %s." %
> + (path,state)
> + return False
>
> def virsh_start(name, uri = ""):
> """
> @@ -1256,14 +1325,30 @@ class VM(virt_vm.BaseVM):
> def migrate(self):
> pass
>
> -
> def pause(self):
> - pass
> -
> + return virsh_suspend(self.name, self.connect_uri)
>
> def resume(self):
> - pass
> + return virsh_resume(self.name, self.connect_uri)
>
> + def save_to_file(self, state_file = ""):
> + """
> + Saves state of VM to named file or temporary file.
> +
> + @param: state_file: absolute path to state file or "" for temp
> + @return: True if successful, False otherwise.
> + """
> + return virsh_save(self.name, uri=self.connect_uri, path=state_file)
> +
> + def restore_from_file(self, state_file = ""):
> + """
> + Restore state of VM from named file or temporary file.
> +
> + Caution is needed to avoid corruption: State of VM's storage must
> not
> + have changed at all between save/restore.
> +
> + @param: state_file: absolute path to state file or "" for temp
> + @return: True if libvirt command was successful, False otherwise.
> + """
> + return virsh_restore(self.name, uri=self.connect_uri,
> path=state_file)
>
> - def save_to_file(self):
> - pass
_______________________________________________
Autotest mailing list
[email protected]
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest