Hello community, here is the log from the commit of package vm-install for openSUSE:Factory checked in at 2014-01-28 12:03:58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/vm-install (Old) and /work/SRC/openSUSE:Factory/.vm-install.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "vm-install" Changes: -------- --- /work/SRC/openSUSE:Factory/vm-install/vm-install.changes 2014-01-15 16:27:27.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.vm-install.new/vm-install.changes 2014-01-28 12:03:59.000000000 +0100 @@ -1,0 +2,9 @@ +Wed Jan 22 14:18:58 MST 2014 - [email protected] + +- Add support for launching VMs using the 'xl' command with --use-xl + command line flag. Update the man page. +- Fix broken libvirt_hypervisor.py wait_domain() method +- Raise error if connecting to libvirt fails +- Version 0.8.2 + +------------------------------------------------------------------- Old: ---- vm-install-0.8.1.tar.bz2 New: ---- vm-install-0.8.2.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ vm-install.spec ++++++ --- /var/tmp/diff_new_pack.plqyMb/_old 2014-01-28 12:03:59.000000000 +0100 +++ /var/tmp/diff_new_pack.plqyMb/_new 2014-01-28 12:03:59.000000000 +0100 @@ -15,19 +15,18 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # - Name: vm-install Url: http://developer.novell.com/wiki/index.php/Vm-install BuildRequires: python-devel BuildRequires: update-desktop-files # For directory ownership: BuildRequires: yast2 -Version: 0.8.1 +Version: 0.8.2 Release: 0 Summary: Tool to Define a Virtual Machine and Install Its Operating System License: GPL-2.0 Group: System/Emulators/PC -Source0: %{name}-0.8.1.tar.bz2 +Source0: %{name}-0.8.2.tar.bz2 Source1: vm-install.conf BuildRoot: %{_tmppath}/%{name}-%{version}-build ExclusiveArch: %ix86 x86_64 s390x ++++++ vm-install-0.8.1.tar.bz2 -> vm-install-0.8.2.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vm-install-0.8.1/Makefile new/vm-install-0.8.2/Makefile --- old/vm-install-0.8.1/Makefile 2014-01-07 22:03:13.000000000 +0100 +++ new/vm-install-0.8.2/Makefile 2014-01-22 22:21:35.000000000 +0100 @@ -1,5 +1,5 @@ PACKAGE = vm-install -VER = 0.8.1 +VER = 0.8.2 default: @echo "Run 'make install DESTDIR=$destdir' to install." diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vm-install-0.8.1/bin/vm-install new/vm-install-0.8.2/bin/vm-install --- old/vm-install-0.8.1/bin/vm-install 2014-01-03 14:59:13.000000000 +0100 +++ new/vm-install-0.8.2/bin/vm-install 2014-01-23 00:44:05.000000000 +0100 @@ -203,7 +203,8 @@ parser.add_option('', '--preserve-on-error', action='store_true', dest='preserve_on_error', help="On error, do not delete temporary, configuration and image files") parser.add_option('', '--use-xl', action='store_true', dest='use_xl', - help="Use the xl command to start the VM; this is for debugging only") + help="Xen specific option. Use the xl command to start the VM; " \ + "Only vncviewer is supported") # Manually copy option keys/values into optparse's values, rather # than relying on optparse.parser.add_option, so my options class @@ -275,8 +276,12 @@ # Create a console instance based on the type of hypervisor running. if vminstall.hypervisor.connection.use_libvirt is False: - from vminstall.xen_console import XenConsole - vminstall.console.console = XenConsole() + if options.use_xl is False: + from vminstall.xen_console import XenConsole + vminstall.console.console = XenConsole() + else: + from vminstall.xl_console import XlConsole + vminstall.console.console = XlConsole() else: from vminstall.libvirt_console import LibVirtConsole vminstall.console.console = LibVirtConsole() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vm-install-0.8.1/man/vm-install.8 new/vm-install-0.8.2/man/vm-install.8 --- old/vm-install-0.8.1/man/vm-install.8 2013-11-19 00:33:16.000000000 +0100 +++ new/vm-install-0.8.2/man/vm-install.8 2014-01-23 22:38:38.000000000 +0100 @@ -289,6 +289,12 @@ .TP .B --upgrade Upgrade an existing paravirtualized VM. +.TP +.B --use-xl +This Xen only option uses the xl toolstack to create the VM. This option will +create a VM that is unknown and unmanaged by libvirt. Because virt-viewer +requires a libvirt connection, only vncviewer may be used to view the graphical +console of a VM created with this option. .SH EXAMPLES As a trivial way to get started, run \fBvm-install\fR with no arguments: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vm-install-0.8.1/setup.py new/vm-install-0.8.2/setup.py --- old/vm-install-0.8.1/setup.py 2014-01-07 22:03:10.000000000 +0100 +++ new/vm-install-0.8.2/setup.py 2014-01-22 22:21:31.000000000 +0100 @@ -1,7 +1,7 @@ from distutils.core import setup setup(name='vminstall', - version='0.8.1', + version='0.8.2', description='Define a virtual machine and install its operating system', author='Charles Coffing', author_email='[email protected]', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vm-install-0.8.1/src/vminstall/caps.py new/vm-install-0.8.2/src/vminstall/caps.py --- old/vm-install-0.8.1/src/vminstall/caps.py 2014-01-03 17:10:34.000000000 +0100 +++ new/vm-install-0.8.2/src/vminstall/caps.py 2014-01-22 22:08:07.000000000 +0100 @@ -73,6 +73,16 @@ free_memory = free_memory + ((int)(mem) / 1024) return free_memory +def maximum_memory(): + # xl only function + cmd = '/usr/sbin/xl info | grep total_memory' + rfd = os.popen(cmd) + data = rfd.read() + status = rfd.close() + total_memory = data.split(':',1)[1] + total_memory = total_memory.strip() + return total_memory + _arch = None def arch(): global _arch diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vm-install-0.8.1/src/vminstall/console.py new/vm-install-0.8.2/src/vminstall/console.py --- old/vm-install-0.8.1/src/vminstall/console.py 2014-01-03 00:53:32.000000000 +0100 +++ new/vm-install-0.8.2/src/vminstall/console.py 2014-01-23 00:45:00.000000000 +0100 @@ -152,11 +152,8 @@ default_viewer = 'vncviewer' else: default_viewer = 'virt-viewer' - if guest.options.use_xl: - vncport = 5900 - else: - domid = self.get_domid_from_uuid(guest.uuid) - vncport = self.get_vnc_port_from_domid(domid, timeout=10.0) + domid = self.get_domid_from_uuid(guest.uuid) + vncport = self.get_vnc_port_from_domid(domid, timeout=10.0) if vncport == None: log.info("Did not find VNC port, so not using VNC.") raise NotImplementedError diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vm-install-0.8.1/src/vminstall/gtk/interface.py new/vm-install-0.8.2/src/vminstall/gtk/interface.py --- old/vm-install-0.8.1/src/vminstall/gtk/interface.py 2013-11-19 00:33:15.000000000 +0100 +++ new/vm-install-0.8.2/src/vminstall/gtk/interface.py 2014-01-23 00:44:33.000000000 +0100 @@ -34,6 +34,7 @@ import vminstall import vminstall.libvirt_console import vminstall.xen_console +import vminstall.xl_console import vminstall.nics import vminstall.options import vminstall.hypervisor @@ -1726,7 +1727,10 @@ if caps.is_kvm() or caps.is_qemu(): guest_console = vminstall.libvirt_console.LibVirtConsole() else: - guest_console = vminstall.xen_console.XenConsole() + if self.options.use_xl is False: + guest_console = vminstall.xen_console.XenConsole() + else: + guest_console = vminstall.xl_console.XlConsole() if self.virtman: domid = guest_console.get_domid_from_uuid(uuid) signal = 'action-show-terminal' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vm-install-0.8.1/src/vminstall/job.py new/vm-install-0.8.2/src/vminstall/job.py --- old/vm-install-0.8.1/src/vminstall/job.py 2014-01-06 21:46:02.000000000 +0100 +++ new/vm-install-0.8.2/src/vminstall/job.py 2014-01-23 00:45:16.000000000 +0100 @@ -335,8 +335,12 @@ if self._options.noautoconsole: if hypervisor.connection.use_libvirt is False: - from xen_console import XenConsole - console.console = XenConsole() + if self._options.use_xl is False: + from xen_console import XenConsole + console.console = XenConsole() + else: + from xl_console import XlConsole + console.console = XlConsole() else: from libvirt_console import LibVirtConsole console.console = LibVirtConsole() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vm-install-0.8.1/src/vminstall/libvirt_hypervisor.py new/vm-install-0.8.2/src/vminstall/libvirt_hypervisor.py --- old/vm-install-0.8.1/src/vminstall/libvirt_hypervisor.py 2014-01-03 22:55:27.000000000 +0100 +++ new/vm-install-0.8.2/src/vminstall/libvirt_hypervisor.py 2014-01-22 23:02:23.000000000 +0100 @@ -23,6 +23,7 @@ import dbus import os import hypervisor +import msg #--------------------------------------------------------------------------- # Method: libvirt_error_handler @@ -58,13 +59,7 @@ try: self.virConn = libvirt.open(self.uri) except: - self.virConn = libvirt.openReadOnly(self.uri) - #self.virConn = libvirt.openAuth(self.uri, - # [[libvirt.VIR_CRED_AUTHNAME, - # libvirt.VIR_CRED_PASSPHRASE, - # libvirt.VIR_CRED_EXTERNAL], - # self._authenticate, - # None], 0) + raise RuntimeError(msg.libvirt_connection) self.virNode = None self.virDom = None self.use_libvirt = True @@ -224,21 +219,9 @@ domain = self.domain(domid) if not domain: return False - if self.use_libvirt is False: - wait = False - for d in domain: - if type(d) == list and len(d) > 1 and d[0] == 'state': - if len(d[1]) > 1 and not 'p' in d[1]: - return True - time.sleep(1.0) - wait = True - break - if not wait: - break - else: - domInfo = domain.info() - if domInfo[0] == 0 or domInfo[0] == 1: - return True + wait = False + if self.domain_running(domid): + return True + time.sleep(1.0) return False - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vm-install-0.8.1/src/vminstall/msg.py new/vm-install-0.8.2/src/vminstall/msg.py --- old/vm-install-0.8.1/src/vminstall/msg.py 2014-01-03 17:08:39.000000000 +0100 +++ new/vm-install-0.8.2/src/vminstall/msg.py 2014-01-22 23:02:14.000000000 +0100 @@ -32,6 +32,7 @@ disk_block_or_file = _("The virtual disk may only be stored on a block device or in a file.") no_media = _("No media is present in the drive.") must_be_root = _("Must be the 'root' user to run vm-install") +libvirt_connection = _("Failed to open a connection to libvirt. Please verify the libvirt daemon is running.") # Error prompts for the CLI correct_retry = _("Please correct the error and try again.") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vm-install-0.8.1/src/vminstall/options.py new/vm-install-0.8.2/src/vminstall/options.py --- old/vm-install-0.8.1/src/vminstall/options.py 2014-01-06 21:45:07.000000000 +0100 +++ new/vm-install-0.8.2/src/vminstall/options.py 2014-01-22 22:07:39.000000000 +0100 @@ -294,8 +294,10 @@ elif item == 'connect': import libvirt_hypervisor import xen_hypervisor + import xl_hypervisor if not isinstance(value, libvirt_hypervisor.LibVirtHypervisor) and \ - not isinstance(value, xen_hypervisor.Xend): + not isinstance(value, xen_hypervisor.Xend) and \ + not isinstance(value, xl_hypervisor.Xl): bad() elif item == 'acpi' or item == 'blkif' or \ item == 'hap' or item == 'hpet' or item == 'isa' or \ @@ -404,7 +406,7 @@ hypervisor.connection = options.connect options.use_libvirt = True elif hypervisor.connection is None: - if not caps.is_xen() or not util.is_xend_running(): + if not caps.is_xen() or not util.is_xend_running() and not options.use_xl: # NOTE: the KVM path is coming through here! Yea! import libvirt_hypervisor if caps.is_xen(): @@ -414,7 +416,11 @@ defaults.use_libvirt = options.use_libvirt = True else: import xen_hypervisor - defaults.connect = xen_hypervisor.Xend(None) + import xl_hypervisor + if options.use_xl is False: + defaults.connect = xen_hypervisor.Xend(None) + else: + defaults.connect = xl_hypervisor.Xl(None) defaults.use_libvirt = options.use_libvirt = False hypervisor.connection = defaults.connect diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vm-install-0.8.1/src/vminstall/xen_guest.py new/vm-install-0.8.2/src/vminstall/xen_guest.py --- old/vm-install-0.8.1/src/vminstall/xen_guest.py 2014-01-03 22:55:47.000000000 +0100 +++ new/vm-install-0.8.2/src/vminstall/xen_guest.py 2014-01-22 22:07:17.000000000 +0100 @@ -21,6 +21,7 @@ import vmdisks import hypervisor import xen_hypervisor +import xl_hypervisor import libvirt_hypervisor import keytable from guest import Guest diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vm-install-0.8.1/src/vminstall/xl_console.py new/vm-install-0.8.2/src/vminstall/xl_console.py --- old/vm-install-0.8.1/src/vminstall/xl_console.py 1970-01-01 01:00:00.000000000 +0100 +++ new/vm-install-0.8.2/src/vminstall/xl_console.py 2014-01-23 00:44:53.000000000 +0100 @@ -0,0 +1,162 @@ +################################################################################ +# Initially derived from virt-inst, Copyright 2005-2006 Red Hat, Inc. +# Copyright 2006-2007 Novell, Inc. +# Author: Charles Coffing <[email protected]> +# +# This software may be freely redistributed under the terms of the GNU +# general public license. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +################################################################################ + +from console import Console +from log import log +import threading +import time +import util + +try: + from xen.xend.xenstore.xstransact import xstransact +except: + pass +try: + from xen.xend.xenstore.xswatch import xswatch +except: + pass + + +################################################################################ +# CLASS: XlConsole +# +# This class contains the Xen console implementation. +# +################################################################################ +class XlConsole(Console): + + #--------------------------------------------------------------------------- + # Class: XlConsole + # Method: get_domid_from_uuid + # Parms: + # uuid: uuid from the domain + # + # This method gets the domain ID for the given UUID. + # + #--------------------------------------------------------------------------- + def get_domid_from_uuid(self, uuid): + vm_path = '/vm/%s' % uuid + ids = util.run(['/usr/bin/xenstore-list', '/local/domain']) + domids = ids.split() + for domid in domids: + if domid == '0': + continue + read_path = '/local/domain/%s/vm' % domid + path = util.run(['/usr/bin/xenstore-read', '-s', read_path]) + path = path.strip() + if path == vm_path: + read_path = '/local/domain/%s/domid' % domid + d = util.run(['/usr/bin/xenstore-read', '-s', read_path]) + if d == 'None': + continue + domid = int(domid) + log.debug("Domain %s has ID %d" % (uuid, domid)) + return domid + log.debug("Domain %s is not running" % uuid) + return None + + + #--------------------------------------------------------------------------- + # Class: XlConsole + # Method: get_tty_from_domid + # Parms: + # domid: domain ID + # + # This method gets the tty number for a given domain. + # + # This method is stubbed out in the base class. It is expected that + # anyone that subclasses this class will create their own method. + #--------------------------------------------------------------------------- + def get_tty_from_domid(self, domid): + if domid is None: + return None + tty = None + console_path = '/local/domain/%d/console/tty' % domid + tty = util.run(['/usr/bin/xenstore-read', '-s', console_path]) + log.info('Domain ID %d has tty %s' % (domid, str(tty))) + return tty + + + #--------------------------------------------------------------------------- + # Class: XlConsole + # Method: wait_for_domid_to_exit + # Parms: + # domid: The domain ID of the domain that we are waiting to exit. + # uuid: UUID from the domain + # + # This method waits for the given domain to exit. + # + #--------------------------------------------------------------------------- + def wait_for_domid_to_exit(self, domid, uuid): + """Wait for domid to exit (or, for domid's UUID to not match + the specified uuid, which would indicate a race condition in + which domid has already exited and was replace by another).""" + # No Op for now. Just return for xl + return + if domid is None: + return + uuid_path = '/local/domain/%d/vm' % domid + log.debug("Watching xenstore path '%s'" % uuid_path) + cv = threading.Condition() + def fn(path): + log.debug("Watch fired for '%s'" % uuid_path) + cv.acquire() + #u = xstransact.Read(uuid_path) + u = util.run(['/usr/bin/xenstore-read', '-s', uuid_path]) + u = u.strip() + log.debug("UUID is '%s'", u) + if u is None: + again = False + else: + u = u.split('/')[-1] # Why does uuid have "/vm/" prefix? + if u == uuid: + again = True + else: + again = False + if not again: + cv.notifyAll() + cv.release() + return again + cv.acquire() + #w = xswatch(uuid_path, fn) + cv.wait() + cv.release() + + + #--------------------------------------------------------------------------- + # Class: XlConsole + # Method: get_vnc_port_from_domid + # + # Parms: + # domid: The domain ID of the domain that we are waiting to exit. + # timeout: Wait only so long. + # + # This method finds the vnc port for the given domain. + # + # This method is stubbed out in the base class. It is expected that + # anyone that subclasses this class will create their own method. + #--------------------------------------------------------------------------- + def get_vnc_port_from_domid(self, domid, timeout=0.0): + if domid is None: + return None + ports = [None] + console_path = '/local/domain/%d/console/vnc-port' % domid + console_path = console_path.strip() + for _ in xrange(10): + p = util.run(['/usr/bin/xenstore-read', '-s', console_path]) + p = p.strip() + if p is not None: + return int(p) + time.sleep(1) + return None + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vm-install-0.8.1/src/vminstall/xl_hypervisor.py new/vm-install-0.8.2/src/vminstall/xl_hypervisor.py --- old/vm-install-0.8.1/src/vminstall/xl_hypervisor.py 1970-01-01 01:00:00.000000000 +0100 +++ new/vm-install-0.8.2/src/vminstall/xl_hypervisor.py 2014-01-22 22:06:36.000000000 +0100 @@ -0,0 +1,132 @@ +################################################################################ +# Communicates with xend +# +# Copyright 2006-2007 Novell, Inc. +# Author: Charles Coffing <[email protected]> +# +# This software may be freely redistributed under the terms of the GNU +# general public license. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +# This is the file that communicates with the xen hypervisor. +# +################################################################################ + +import time +import os +from hypervisor import Hypervisor +from exceptions import ParamError, XenError +import util +import caps + +def parse_string(uri): + if not uri.startswith("xen") and not uri.startswith("qemu"): + raise ParamError(err=ParamError.E_INVALID, details=uri) + return Xl(uri) + +################################################################################ +# Class: XenHypervisor +# +# Xen Hypervisor specifics. +################################################################################ +class Xl(Hypervisor): + """Thin abstraction to talk to Xl. + + In case you don't want to use libvirt. + """ + + #--------------------------------------------------------------------------- + # Method: __init__ + # + # Comments: + # Sets the connection information to talk to xen. + # + #--------------------------------------------------------------------------- + def __init__(self, uri): + if os.getuid() != 0: + raise XenError(err=XenError.E_ROOT, details=uri) + self.use_libvirt = False + + #--------------------------------------------------------------------------- + # Method: delete + #--------------------------------------------------------------------------- + def delete(self, domid): + """Destroys a running instance; erases from xl""" + try: + output = util.run(['/usr/sbin/xl', 'shutdown', str(domid)]) + except: + pass + + #--------------------------------------------------------------------------- + # Method: destroy + #--------------------------------------------------------------------------- + def destroy(self, domid): + """Destroys a running instance; does not erase from xend""" + try: + output = util.run(['/usr/sbin/xl', 'shutdown', str(domid)]) + except: + pass + + #--------------------------------------------------------------------------- + # Method: domain + #--------------------------------------------------------------------------- + def domain(self, domid): + # xl doesn't have managed domains + return None + + #--------------------------------------------------------------------------- + # Method: get_dom0_min_memory + #--------------------------------------------------------------------------- + def get_dom0_min_memory(self): + return 0 + + #--------------------------------------------------------------------------- + # Method: domain_running + #--------------------------------------------------------------------------- + def domain_running(self, domid): + try: + output = util.run(['/usr/sbin/xl', 'list', str(domid)]) + except: + return False + return True + + #--------------------------------------------------------------------------- + # Method: info + #--------------------------------------------------------------------------- + def info(self): + maxmem = caps.free_memory(True) + if maxmem > 524288: + maxmem = 524288 + num_cpus = caps.cpu_processors() + total_memory = caps.maximum_memory() + return dict([('nr_cpus', num_cpus), ('total_memory', total_memory), ('max_hvm_memory', maxmem), ('max_para_memory', maxmem)]) + + #--------------------------------------------------------------------------- + # Method: lookup + #--------------------------------------------------------------------------- + def lookup(self, domid): + """Lookup the domain by name, UUID, or hypervisor ID""" + return self.domain_running(domid) + + #--------------------------------------------------------------------------- + # Method: wait_domain + #--------------------------------------------------------------------------- + def wait_domain(self, domid): + # This is ugly (polling instead of event driven) but XenAPI doesn't + # yet grok unix socket. + # + # If domain and 'state' are both found, then assume VM is trying + # to come up, so keep waiting. Otherwise, fail. + for _ in xrange(10): + domain = self.domain(domid) + if not domain: + return False + wait = False + if self.domain_running(domid): + return True + time.sleep(1.0) + return False + -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
