virt-manager/virt-manager

295 lines
10 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env python3
#
# Copyright (C) 2006, 2014 Red Hat, Inc.
# Copyright (C) 2006 Daniel P. Berrange <berrange@redhat.com>
#
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
2006-03-29 01:13:50 +08:00
import argparse
import logging
import os
import signal
import sys
import traceback
import gi
gi.require_version('LibvirtGLib', '1.0')
Convert to use GTK3 and GObject Introspection bindings Switch over to use GObject introspection bindings for all python modules related to GObject/GTK3/etc. It is not possible to mix and match old pyggtk/pygobject manual bindings with new introspection based bindings so it must be all changed in one go. Imports like import gtk Change to from gi.repository import Gtk The vmmGObject class is changed to always inherit from GObject.GObject There is no compelling reason to avoid a GObject dep for the virt-manager TUI & it horribly messed up the code. Signal declarations are changed from vmmChooseCD.signal_new(vmmChooseCD, "cdrom-chosen", [object, str]) To __gsignals__ = { "cdrom-chosen": (GObject.SignalFlags.RUN_FIRST, None, [object, str]) } which is required by new GObject bindings Most of the rest of the change is simply dealing with renamed constants / classes. Alot of legacy compat code was removed - ie helpers which check to see if certain GTK2 methods are available are no longer required since we're mandating GTK3 only. The event loop is replaced with LibvirtGLib's event loop. Still todo - Rip out all DBus stuff & make vmmEngine class inherit GtkApplication which provides unique support & DBus method handling - Switch to use LibvirtGConfig & LibvirtGObject for libvirt interaction - Possibly switch to Python 3 too ? - Figure out why GNOME keyring is missing Introspection support My suggestion is that the standalone GIT repo for virt-install only live on as a support branch for legacy platforms. A stable-0.9 branch of virt-manager can be kept for legacy PyGtk2 based virt-manager releases. The virt-manager master branch should exclusively use GObject inspection and ideally Python3 and contain both the virt-manager and virt-install codebases in one since they are intimately related to each other & using separate GIT repos has needlessly complicated life for everyone. crobinso: Some locking fixes Misc cleanups and dropping now-useless code Fix dbus usage Fix graph cell renderer regression Fix a couple tooltip issues
2012-05-14 21:24:56 +08:00
from gi.repository import LibvirtGLib
from virtinst import util as util
2013-07-06 03:14:11 +08:00
from virtinst import cli as virtinstcli
from virtcli import CLIConfig
# This is massively heavy handed, but I can't figure out any way to shut
# up the slew of gtk deprecation warnings that clog up our very useful
# stdout --debug output. Of course we could drop use of deprecated APIs,
# but it's a serious quantity of churn
2016-04-19 04:42:12 +08:00
import warnings # pylint: disable=wrong-import-order
warnings.simplefilter("ignore")
try:
gi.check_version("3.14.0")
except (ValueError, AttributeError):
print("pygobject3 3.14.0 or later is required.")
sys.exit(1)
def _show_startup_error(msg, details):
logging.debug("Error starting virt-manager: %s\n%s", msg, details,
exc_info=True)
from virtManager.error import vmmErrorDialog
err = vmmErrorDialog.get_instance()
title = _("Error starting Virtual Machine Manager")
err.show_err(title + ": " + msg,
details=details,
title=title,
modal=True,
debug=False)
def _import_gtk(leftovers):
# The never ending fork+gsettings problems now require us to
# import Gtk _after_ the fork. This creates a funny race, since we
# need to parse the command line arguments to know if we need to
# fork, but need to import Gtk before cli processing so it can
# handle --g-fatal-args. We strip out our flags first and pass the
# left overs to gtk
origargv = sys.argv
try:
sys.argv = origargv[:1] + leftovers[:]
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
leftovers = sys.argv[1:]
if Gtk.check_version(3, 14, 0):
print("gtk3 3.14.0 or later is required.")
sys.exit(1)
# This will error if Gtk wasn't correctly initialized
Gtk.init()
globals()["Gtk"] = Gtk
# This ensures we can init gsettings correctly
import virtManager.config
ignore = virtManager.config
except Exception as e:
# Don't just let the exception raise here. abrt reports bugs
# when users mess up su/sudo and DISPLAY isn't set. Printing
# it avoids the issue
display = os.environ.get("DISPLAY", "")
msg = str(e)
if display:
msg += ": Could not open display: %s" % display
logging.debug("".join(traceback.format_exc()))
print(msg)
sys.exit(1)
finally:
sys.argv = origargv
return leftovers
def drop_tty():
# We fork and setsid so that we drop the controlling
# tty. This prevents libvirt's SSH tunnels from prompting
# for user input if SSH keys/agent aren't configured.
if os.fork() != 0:
os._exit(0) # pylint: disable=protected-access
os.setsid()
def drop_stdio():
# This is part of the fork process described in drop_tty()
for fd in range(0, 2):
try:
os.close(fd)
except OSError:
pass
os.open(os.devnull, os.O_RDWR)
os.dup2(0, 1)
os.dup2(0, 2)
def parse_commandline():
epilog = ("Also accepts standard GTK arguments like --g-fatal-warnings")
parser = argparse.ArgumentParser(usage="virt-manager [options]",
epilog=epilog)
parser.add_argument('--version', action='version',
version=CLIConfig.version)
parser.set_defaults(domain=None)
# Trace every libvirt API call to debug output
parser.add_argument("--trace-libvirt",
help=argparse.SUPPRESS, action="store_true")
# Don't load any connections on startup to test first run
# PackageKit integration
parser.add_argument("--test-first-run",
help=argparse.SUPPRESS, action="store_true")
# Force use of old style libvirt polling APIs
parser.add_argument("--test-old-poll",
help=argparse.SUPPRESS, action="store_true")
# Force disable use of libvirt object events
parser.add_argument("--test-no-events",
help=argparse.SUPPRESS, action="store_true")
# Enabling this will tell us, at app exit time, which vmmGObjects were not
# garbage collected. This is caused by circular references to other objects,
# like a signal that wasn't disconnected. It's not a big deal, but if we
# have objects that can be created and destroyed a lot over the course of
# the app lifecycle, every non-garbage collected class is a memory leak.
# So it's nice to poke at this every now and then and try to track down
# what we need to add to class _cleanup handling.
parser.add_argument("--test-leak-debug",
help=argparse.SUPPRESS, action="store_true")
parser.add_argument("-c", "--connect", dest="uri",
help="Connect to hypervisor at URI", metavar="URI")
parser.add_argument("--debug", action="store_true",
2009-05-12 22:34:02 +08:00
help="Print debug output to stdout (implies --no-fork)",
default=False)
parser.add_argument("--no-fork", action="store_true",
2007-09-13 03:48:01 +08:00
help="Don't fork into background on startup")
parser.add_argument("--show-domain-creator", action="store_true",
help="Show 'New VM' wizard")
parser.add_argument("--show-domain-editor", metavar="NAME|ID|UUID",
help="Show domain details window")
parser.add_argument("--show-domain-performance", metavar="NAME|ID|UUID",
help="Show domain performance window")
parser.add_argument("--show-domain-console", metavar="NAME|ID|UUID",
help="Show domain graphical console window")
parser.add_argument("--show-host-summary", action="store_true",
help="Show connection details window")
return parser.parse_known_args()
2006-05-27 00:11:06 +08:00
2006-03-29 01:13:50 +08:00
def main():
(options, leftovers) = parse_commandline()
2013-07-06 03:14:11 +08:00
virtinstcli.setupLogging("virt-manager", options.debug, False, False)
import virtManager
logging.debug("virt-manager version: %s", CLIConfig.version)
logging.debug("virtManager import: %s", str(virtManager))
if options.trace_libvirt:
logging.debug("Libvirt tracing requested")
import virtManager.module_trace
import libvirt
virtManager.module_trace.wrap_module(libvirt, regex=None)
# With F27 gnome+wayland we need to set these before GTK import
os.environ["GSETTINGS_SCHEMA_DIR"] = CLIConfig.gsettings_dir
if options.test_first_run:
os.environ["GSETTINGS_BACKEND"] = "memory"
# Now we've got basic environment up & running we can fork
do_drop_stdio = False
if not options.no_fork and not options.debug:
drop_tty()
do_drop_stdio = True
# Ignore SIGHUP, otherwise a serial console closing drops the whole app
signal.signal(signal.SIGHUP, signal.SIG_IGN)
2010-04-13 03:54:36 +08:00
leftovers = _import_gtk(leftovers)
Gtk = globals()["Gtk"]
# Do this after the Gtk import so the user has a chance of seeing any error
if do_drop_stdio:
drop_stdio()
if leftovers:
raise RuntimeError("Unhandled command line options '%s'" % leftovers)
logging.debug("PyGObject version: %d.%d.%d",
gi.version_info[0],
gi.version_info[1],
gi.version_info[2])
Convert to use GTK3 and GObject Introspection bindings Switch over to use GObject introspection bindings for all python modules related to GObject/GTK3/etc. It is not possible to mix and match old pyggtk/pygobject manual bindings with new introspection based bindings so it must be all changed in one go. Imports like import gtk Change to from gi.repository import Gtk The vmmGObject class is changed to always inherit from GObject.GObject There is no compelling reason to avoid a GObject dep for the virt-manager TUI & it horribly messed up the code. Signal declarations are changed from vmmChooseCD.signal_new(vmmChooseCD, "cdrom-chosen", [object, str]) To __gsignals__ = { "cdrom-chosen": (GObject.SignalFlags.RUN_FIRST, None, [object, str]) } which is required by new GObject bindings Most of the rest of the change is simply dealing with renamed constants / classes. Alot of legacy compat code was removed - ie helpers which check to see if certain GTK2 methods are available are no longer required since we're mandating GTK3 only. The event loop is replaced with LibvirtGLib's event loop. Still todo - Rip out all DBus stuff & make vmmEngine class inherit GtkApplication which provides unique support & DBus method handling - Switch to use LibvirtGConfig & LibvirtGObject for libvirt interaction - Possibly switch to Python 3 too ? - Figure out why GNOME keyring is missing Introspection support My suggestion is that the standalone GIT repo for virt-install only live on as a support branch for legacy platforms. A stable-0.9 branch of virt-manager can be kept for legacy PyGtk2 based virt-manager releases. The virt-manager master branch should exclusively use GObject inspection and ideally Python3 and contain both the virt-manager and virt-install codebases in one since they are intimately related to each other & using separate GIT repos has needlessly complicated life for everyone. crobinso: Some locking fixes Misc cleanups and dropping now-useless code Fix dbus usage Fix graph cell renderer regression Fix a couple tooltip issues
2012-05-14 21:24:56 +08:00
logging.debug("GTK version: %d.%d.%d",
Gtk.get_major_version(),
Gtk.get_minor_version(),
Gtk.get_micro_version())
2018-03-14 00:13:11 +08:00
config = virtManager.config.vmmConfig.get_instance(CLIConfig,
options.test_first_run)
config.test_leak_debug = options.test_leak_debug
if not util.local_libvirt_version() >= 6000:
# We need this version for threaded virConnect access
_show_startup_error(
_("virt-manager requires libvirt 0.6.0 or later."), "")
return
# Add our icon dir to icon theme
2012-11-08 21:15:02 +08:00
icon_theme = Gtk.IconTheme.get_default()
icon_theme.prepend_search_path(CLIConfig.icon_dir)
from virtManager.engine import vmmEngine
Gtk.Window.set_default_icon_name("virt-manager")
import virtManager.connection
virtManager.connection.FORCE_DISABLE_EVENTS = bool(options.test_no_events)
import virtinst.pollhelpers
virtinst.pollhelpers.FORCE_OLD_POLL = bool(options.test_old_poll)
show_window = None
domain = None
if options.show_domain_creator:
show_window = vmmEngine.CLI_SHOW_DOMAIN_CREATOR
elif options.show_host_summary:
show_window = vmmEngine.CLI_SHOW_HOST_SUMMARY
elif options.show_domain_editor:
show_window = vmmEngine.CLI_SHOW_DOMAIN_EDITOR
domain = options.show_domain_editor
elif options.show_domain_performance:
show_window = vmmEngine.CLI_SHOW_DOMAIN_PERFORMANCE
domain = options.show_domain_performance
elif options.show_domain_console:
show_window = vmmEngine.CLI_SHOW_DOMAIN_CONSOLE
domain = options.show_domain_console
if show_window and options.uri is None:
raise RuntimeError("can't use --show-* options without --connect")
2006-10-27 00:35:30 +08:00
skip_autostart = False
if show_window:
skip_autostart = True
# Hook libvirt events into glib main loop
Convert to use GTK3 and GObject Introspection bindings Switch over to use GObject introspection bindings for all python modules related to GObject/GTK3/etc. It is not possible to mix and match old pyggtk/pygobject manual bindings with new introspection based bindings so it must be all changed in one go. Imports like import gtk Change to from gi.repository import Gtk The vmmGObject class is changed to always inherit from GObject.GObject There is no compelling reason to avoid a GObject dep for the virt-manager TUI & it horribly messed up the code. Signal declarations are changed from vmmChooseCD.signal_new(vmmChooseCD, "cdrom-chosen", [object, str]) To __gsignals__ = { "cdrom-chosen": (GObject.SignalFlags.RUN_FIRST, None, [object, str]) } which is required by new GObject bindings Most of the rest of the change is simply dealing with renamed constants / classes. Alot of legacy compat code was removed - ie helpers which check to see if certain GTK2 methods are available are no longer required since we're mandating GTK3 only. The event loop is replaced with LibvirtGLib's event loop. Still todo - Rip out all DBus stuff & make vmmEngine class inherit GtkApplication which provides unique support & DBus method handling - Switch to use LibvirtGConfig & LibvirtGObject for libvirt interaction - Possibly switch to Python 3 too ? - Figure out why GNOME keyring is missing Introspection support My suggestion is that the standalone GIT repo for virt-install only live on as a support branch for legacy platforms. A stable-0.9 branch of virt-manager can be kept for legacy PyGtk2 based virt-manager releases. The virt-manager master branch should exclusively use GObject inspection and ideally Python3 and contain both the virt-manager and virt-install codebases in one since they are intimately related to each other & using separate GIT repos has needlessly complicated life for everyone. crobinso: Some locking fixes Misc cleanups and dropping now-useless code Fix dbus usage Fix graph cell renderer regression Fix a couple tooltip issues
2012-05-14 21:24:56 +08:00
LibvirtGLib.init(None)
LibvirtGLib.event_register()
engine = vmmEngine.get_instance()
# Actually exit when we receive ctrl-c
from gi.repository import GLib
def _sigint_handler(user_data):
ignore = user_data
logging.debug("Received KeyboardInterrupt. Exiting application.")
engine.exit_app()
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT,
_sigint_handler, None)
engine.start(options.uri, show_window, domain, skip_autostart)
2006-03-29 01:13:50 +08:00
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
logging.debug("Received KeyboardInterrupt. Exiting application.")
except SystemExit:
raise
except Exception as run_e:
Convert to use GTK3 and GObject Introspection bindings Switch over to use GObject introspection bindings for all python modules related to GObject/GTK3/etc. It is not possible to mix and match old pyggtk/pygobject manual bindings with new introspection based bindings so it must be all changed in one go. Imports like import gtk Change to from gi.repository import Gtk The vmmGObject class is changed to always inherit from GObject.GObject There is no compelling reason to avoid a GObject dep for the virt-manager TUI & it horribly messed up the code. Signal declarations are changed from vmmChooseCD.signal_new(vmmChooseCD, "cdrom-chosen", [object, str]) To __gsignals__ = { "cdrom-chosen": (GObject.SignalFlags.RUN_FIRST, None, [object, str]) } which is required by new GObject bindings Most of the rest of the change is simply dealing with renamed constants / classes. Alot of legacy compat code was removed - ie helpers which check to see if certain GTK2 methods are available are no longer required since we're mandating GTK3 only. The event loop is replaced with LibvirtGLib's event loop. Still todo - Rip out all DBus stuff & make vmmEngine class inherit GtkApplication which provides unique support & DBus method handling - Switch to use LibvirtGConfig & LibvirtGObject for libvirt interaction - Possibly switch to Python 3 too ? - Figure out why GNOME keyring is missing Introspection support My suggestion is that the standalone GIT repo for virt-install only live on as a support branch for legacy platforms. A stable-0.9 branch of virt-manager can be kept for legacy PyGtk2 based virt-manager releases. The virt-manager master branch should exclusively use GObject inspection and ideally Python3 and contain both the virt-manager and virt-install codebases in one since they are intimately related to each other & using separate GIT repos has needlessly complicated life for everyone. crobinso: Some locking fixes Misc cleanups and dropping now-useless code Fix dbus usage Fix graph cell renderer regression Fix a couple tooltip issues
2012-05-14 21:24:56 +08:00
if "Gtk" not in globals():
raise
2008-11-19 06:01:22 +08:00
_show_startup_error(str(run_e), "".join(traceback.format_exc()))