mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-01-12 09:18:00 +03:00
1726505fd6
GConf got replaced by GSettings but some methods kept the old name
288 lines
9.6 KiB
Python
Executable File
288 lines
9.6 KiB
Python
Executable File
#!/usr/bin/python2 -tt
|
|
#
|
|
# Copyright (C) 2006, 2014 Red Hat, Inc.
|
|
# Copyright (C) 2006 Daniel P. Berrange <berrange@redhat.com>
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# 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.
|
|
#
|
|
|
|
import argparse
|
|
import logging
|
|
import os
|
|
import signal
|
|
import sys
|
|
import traceback
|
|
|
|
from gi.repository import GObject
|
|
from gi.repository import LibvirtGLib
|
|
|
|
from virtinst import util as util
|
|
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
|
|
import warnings
|
|
warnings.simplefilter("ignore")
|
|
|
|
try:
|
|
# Avoid a deprecation warning about threads_init
|
|
import gi
|
|
gi.check_version("3.9.1")
|
|
except (ValueError, AttributeError):
|
|
GObject.threads_init()
|
|
|
|
|
|
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()
|
|
title = _("Error starting Virtual Machine Manager")
|
|
err.show_err(title + ": " + msg,
|
|
details=details,
|
|
title=title,
|
|
modal=True,
|
|
debug=False)
|
|
|
|
|
|
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(uuid=None)
|
|
|
|
# Trace every libvirt API call to debug output
|
|
parser.add_argument("--trace-libvirt", dest="tracelibvirt",
|
|
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", dest="testfirstrun",
|
|
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", dest="debug",
|
|
help="Print debug output to stdout (implies --no-fork)",
|
|
default=False)
|
|
parser.add_argument("--no-fork", action="store_true", dest="nofork",
|
|
help="Don't fork into background on startup")
|
|
parser.add_argument("--no-conn-autostart", action="store_true",
|
|
dest="no_conn_auto", help="Do not autostart connections")
|
|
parser.add_argument("--spice-disable-auto-usbredir", action="store_true",
|
|
dest="usbredir", help="Disable Auto USB redirection support")
|
|
|
|
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()
|
|
|
|
|
|
def launch_specific_window(engine, show, uri, clistr):
|
|
if not show:
|
|
return
|
|
|
|
logging.debug("Launching requested window '%s'", show)
|
|
if show == 'creator':
|
|
engine.show_domain_creator(uri)
|
|
elif show == 'editor':
|
|
engine.show_domain_editor(uri, clistr)
|
|
elif show == 'performance':
|
|
engine.show_domain_performance(uri, clistr)
|
|
elif show == 'console':
|
|
engine.show_domain_console(uri, clistr)
|
|
elif show == 'summary':
|
|
engine.show_host_summary(uri)
|
|
|
|
|
|
def main():
|
|
(options, leftovers) = parse_commandline()
|
|
|
|
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.tracelibvirt:
|
|
logging.debug("Libvirt tracing requested")
|
|
import virtManager.module_trace
|
|
import libvirt
|
|
virtManager.module_trace.wrap_module(libvirt, regex=None)
|
|
|
|
# Now we've got basic environment up & running we can fork
|
|
do_drop_stdio = False
|
|
if not options.nofork 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)
|
|
|
|
# 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[:]
|
|
from gi.repository import Gtk
|
|
leftovers = sys.argv[1:]
|
|
|
|
# This will error if Gtk wasn't correctly initialized
|
|
Gtk.Window()
|
|
|
|
globals()["Gtk"] = Gtk
|
|
import virtManager.config
|
|
except Exception, 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
|
|
return 1
|
|
finally:
|
|
sys.argv = origargv
|
|
|
|
# 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("GTK version: %d.%d.%d",
|
|
Gtk.get_major_version(),
|
|
Gtk.get_minor_version(),
|
|
Gtk.get_micro_version())
|
|
|
|
config = virtManager.config.vmmConfig(
|
|
"virt-manager", cliconfig, options.testfirstrun)
|
|
|
|
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
|
|
|
|
|
|
if options.usbredir and config.get_auto_redirection():
|
|
config.cli_usbredir = False
|
|
|
|
# Add our icon dir to icon theme
|
|
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")
|
|
|
|
show = None
|
|
if options.show_domain_creator:
|
|
show = "creator"
|
|
elif options.show_domain_editor:
|
|
show = "editor"
|
|
elif options.show_domain_performance:
|
|
show = "performance"
|
|
elif options.show_domain_console:
|
|
show = "console"
|
|
elif options.show_host_summary:
|
|
show = "summary"
|
|
|
|
if show and options.uri is None:
|
|
raise RuntimeError("can't use --show-* options without --connect")
|
|
if show:
|
|
options.uuid = (options.uuid or options.show_domain_creator or
|
|
options.show_domain_editor or
|
|
options.show_domain_performance or
|
|
options.show_domain_console or
|
|
options.show_host_summary)
|
|
|
|
# Hook libvirt events into glib main loop
|
|
LibvirtGLib.init(None)
|
|
LibvirtGLib.event_register()
|
|
|
|
engine = vmmEngine()
|
|
engine.skip_autostart = options.no_conn_auto
|
|
engine.uri_at_startup = options.uri
|
|
|
|
if show:
|
|
def cb(conn):
|
|
ignore = conn
|
|
launch_specific_window(engine, show, options.uri, options.uuid)
|
|
return True
|
|
engine.uri_cb = cb
|
|
engine.show_manager_window = False
|
|
engine.skip_autostart = True
|
|
|
|
# Finally start the app for real
|
|
engine.application.run(None)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
main()
|
|
except KeyboardInterrupt:
|
|
logging.debug("Received KeyboardInterrupt. Exiting application.")
|
|
except SystemExit:
|
|
raise
|
|
except Exception, run_e:
|
|
if "Gtk" not in globals():
|
|
raise
|
|
_show_startup_error(str(run_e), "".join(traceback.format_exc()))
|