def run(self, *args): if len(args) == 1 and args[0] == "status": from xpra.log import get_all_loggers return "logging is enabled for: %s" % str( list([ str(x) for x in get_all_loggers() if x.is_debug_enabled() ])) if len(args) < 2: self.raise_error("not enough arguments") log_cmd = args[0] if log_cmd not in ("enable", "disable"): self.raise_error("only 'enable' and 'disable' verbs are supported") #support both separate arguments and csv: categories = [] for x in args[1:]: categories += [v.strip() for v in x.split(",")] from xpra.log import add_debug_category, add_disabled_category, enable_debug_for, disable_debug_for if log_cmd == "enable": add_debug_category(*categories) loggers = enable_debug_for(*categories) else: assert log_cmd == "disable" add_disabled_category(*categories) loggers = disable_debug_for(*categories) if not loggers: log.info("no loggers matching: %s", csv(categories)) else: log.info("%sd debugging for: %s", log_cmd, csv(loggers)) return "logging %sd for %s" % (log_cmd, csv(loggers))
def main(): from xpra.platform import init as platform_init, clean from xpra.util import nonl from xpra.log import enable_color try: platform_init("GUI-Properties") enable_color() init() verbose = "-v" in sys.argv or "--verbose" in sys.argv if verbose: from xpra.log import get_all_loggers for x in get_all_loggers(): x.enable_debug() # naughty, but how else can I hook this up? import os if os.name == "posix": try: from xpra.x11.bindings import posix_display_source # @UnusedImport except: pass # maybe running on OSX? hope for the best.. i = get_info() for k in sorted(i.keys()): v = i[k] print("* %s : %s" % (k.ljust(32), nonl(v))) finally: clean()
def main(): from xpra.platform import init as platform_init, clean from xpra.util import nonl from xpra.log import enable_color try: platform_init("GUI-Properties") enable_color() init() verbose = "-v" in sys.argv or "--verbose" in sys.argv if verbose: from xpra.log import get_all_loggers for x in get_all_loggers(): x.enable_debug() #naughty, but how else can I hook this up? import os if os.name == "posix": try: from xpra.x11.bindings import posix_display_source #@UnusedImport except: pass #maybe running on OSX? hope for the best.. i = get_info() for k in sorted(i.keys()): v = i[k] print("* %s : %s" % (k.ljust(32), nonl(v))) finally: clean()
def main(): from xpra.platform import program_context from xpra.util import print_nested_dict from xpra.log import enable_color with program_context("GUI-Properties"): enable_color() init() verbose = "-v" in sys.argv or "--verbose" in sys.argv if verbose: from xpra.log import get_all_loggers for x in get_all_loggers(): x.enable_debug() # naughty, but how else can I hook this up? import os if os.name == "posix": try: from xpra.x11.bindings import posix_display_source # @UnusedImport except: pass # maybe running on OSX? hope for the best.. i = get_info() print_nested_dict(i)
def show_encoding_help(opts): #avoid errors and warnings: opts.encoding = "" opts.clipboard = False opts.notifications = False print("xpra server supports the following encodings:") print("(please wait, encoder initialization may take a few seconds)") #disable info logging which would be confusing here from xpra.log import get_all_loggers, set_default_level import logging set_default_level(logging.WARN) logging.root.setLevel(logging.WARN) for x in get_all_loggers(): if x.logger.getEffectiveLevel() == logging.INFO: x.logger.setLevel(logging.WARN) from xpra.server.server_base import ServerBase sb = ServerBase() sb.init(opts) from xpra.codecs.codec_constants import PREFERRED_ENCODING_ORDER, HELP_ORDER if "help" in opts.encodings: sb.allowed_encodings = PREFERRED_ENCODING_ORDER from xpra.server.mixins.encoding_server import EncodingServer assert isinstance(sb, EncodingServer) EncodingServer.threaded_setup(sb) from xpra.codecs.loader import encoding_help for e in (x for x in HELP_ORDER if x in sb.encodings): print(" * %s" % encoding_help(e)) return 0
def main(): from xpra.platform.gui import init as gui_init from xpra.platform import program_context from xpra.gtk_common.error import xsync with program_context("XSettings"): gui_init() verbose = "-v" in sys.argv or "--verbose" in sys.argv if verbose: from xpra.log import get_all_loggers for x in get_all_loggers(): x.enable_debug() #naughty, but how else can I hook this up? if os.name != "posix": print("xsettings require a posix OS") return 1 with xsync: from xpra.x11.bindings.posix_display_source import init_posix_display_source #@UnresolvedImport init_posix_display_source() from xpra.x11.bindings.window_bindings import X11WindowBindings #@UnresolvedImport window_bindings = X11WindowBindings() selection = "_XSETTINGS_S0" owner = window_bindings.XGetSelectionOwner(selection) print("owner(%s)=%#x" % (selection, owner)) XSETTINGS = "_XSETTINGS_SETTINGS" if owner: data = window_bindings.XGetWindowProperty( owner, XSETTINGS, XSETTINGS) serial, settings = get_settings(None, data) print("serial=%s" % serial) print("%s settings:" % len(settings)) for s in settings: print(s) return 0
def run(self, *args): if len(args)==1 and args[0]=="status": from xpra.log import get_all_loggers return "logging is enabled for: %s" % str(list([str(x) for x in get_all_loggers() if x.is_debug_enabled()])) if len(args)<2: self.raise_error("not enough arguments") log_cmd = args[0] if log_cmd not in ("enable", "disable"): self.raise_error("only 'enable' and 'disable' verbs are supported") #support both separate arguments and csv: categories = [] for x in args[1:]: categories += [v.strip() for v in x.split(",")] from xpra.log import add_debug_category, add_disabled_category, enable_debug_for, disable_debug_for if log_cmd=="enable": add_debug_category(*categories) loggers = enable_debug_for(*categories) else: assert log_cmd=="disable" add_disabled_category(*categories) loggers = disable_debug_for(*categories) if not loggers: log.info("no loggers matching: %s", csv(categories)) else: log.info("%sd debugging for: %s", log_cmd, csv(loggers)) return "logging %sd for %s" % (log_cmd, csv(loggers))
def main(): from xpra.platform.gui import init as gui_init from xpra.platform import program_context with program_context("XSettings"): gui_init() verbose = "-v" in sys.argv or "--verbose" in sys.argv if verbose: from xpra.log import get_all_loggers for x in get_all_loggers(): x.enable_debug() #naughty, but how else can I hook this up? if os.name!="posix": print("xsettings require a posix OS") return 1 from xpra.x11.bindings import posix_display_source #@UnresolvedImport - takes care of hooking up the display assert posix_display_source from xpra.x11.bindings.window_bindings import X11WindowBindings #@UnresolvedImport window_bindings = X11WindowBindings() selection = "_XSETTINGS_S0" owner = window_bindings.XGetSelectionOwner(selection) print("owner(%s)=%#x" % (selection, owner)) XSETTINGS = "_XSETTINGS_SETTINGS" data = window_bindings.XGetWindowProperty(owner, XSETTINGS, XSETTINGS) serial, settings = get_settings(None, data) print("serial=%s" % serial) print("%s settings:" % len(settings)) for s in settings: print(s) return 0
def main(): from xpra.platform.gui import init as gui_init from xpra.platform import init as platform_init,clean try: platform_init("XSettings") gui_init() verbose = "-v" in sys.argv or "--verbose" in sys.argv if verbose: from xpra.log import get_all_loggers for x in get_all_loggers(): x.enable_debug() #naughty, but how else can I hook this up? import os if os.name!="posix": print("xsettings require a posix OS") return 1 from xpra.x11.bindings import posix_display_source #@UnresolvedImport - takes care of hooking up the display assert posix_display_source from xpra.x11.bindings.window_bindings import X11WindowBindings #@UnresolvedImport window_bindings = X11WindowBindings() selection = "_XSETTINGS_S0" owner = window_bindings.XGetSelectionOwner(selection) print("owner(%s)=%#x" % (selection, owner)) XSETTINGS = "_XSETTINGS_SETTINGS" data = window_bindings.XGetWindowProperty(owner, XSETTINGS, XSETTINGS) serial, settings = get_settings(None, data) print("serial=%s" % serial) print("%s settings:" % len(settings)) for s in settings: print(s) return 0 finally: clean()
def show_encoding_help(opts): #avoid errors and warnings: opts.encoding = "" opts.clipboard = False opts.notifications = False print("xpra server supports the following encodings:") print("(please wait, encoder initialization may take a few seconds)") #disable info logging which would be confusing here from xpra.log import get_all_loggers, set_default_level import logging set_default_level(logging.WARN) logging.root.setLevel(logging.WARN) for x in get_all_loggers(): x.logger.setLevel(logging.WARN) from xpra.server.server_base import ServerBase sb = ServerBase() sb.init_options(opts) from xpra.codecs.loader import PREFERED_ENCODING_ORDER, HELP_ORDER if "help" in opts.encodings: sb.allowed_encodings = PREFERED_ENCODING_ORDER from xpra.codecs.video_helper import getVideoHelper getVideoHelper().init() sb.init_encodings() from xpra.codecs.loader import encoding_help for e in (x for x in HELP_ORDER if x in sb.encodings): print(" * %s" % encoding_help(e)) return 0
def run(self, *args): if len(args) == 1 and args[0] == "status": from xpra.log import get_all_loggers return "logging is enabled for: %s" % str( list([ str(x) for x in get_all_loggers() if x.is_debug_enabled() ])) log_cmd = args[0] if log_cmd == "mark": for _ in range(10): log.info("*" * 80) if len(args) > 1: log.info("mark: %s", " ".join(args[1:])) else: log.info("mark") for _ in range(10): log.info("*" * 80) return "mark inserted into logfile" if len(args) < 2: self.raise_error("not enough arguments") if log_cmd not in ("enable", "disable"): self.raise_error("only 'enable' and 'disable' verbs are supported") from xpra.log import add_debug_category, add_disabled_category, enable_debug_for, disable_debug_for #each argument is a group loggers = [] groups = args[1:] for group in groups: #and each group is a list of categories #preferably separated by "+", #but we support "," for backwards compatibility: categories = [ v.strip() for v in group.replace("+", ",").split(",") ] if log_cmd == "enable": add_debug_category(*categories) loggers += enable_debug_for(*categories) else: assert log_cmd == "disable" add_disabled_category(*categories) loggers += disable_debug_for(*categories) if not loggers: log.info("%s debugging, no new loggers matching: %s", log_cmd, csv(groups)) else: log.info("%sd debugging for:", log_cmd) for l in loggers: log.info(" - %s", l) return "logging %sd for %s" % (log_cmd, csv(loggers) or "<no match found")
def main(): from xpra.platform import program_context from xpra.util import print_nested_dict from xpra.log import enable_color with program_context("GUI-Properties"): enable_color() init() verbose = "-v" in sys.argv or "--verbose" in sys.argv if verbose: from xpra.log import get_all_loggers for x in get_all_loggers(): x.enable_debug() #naughty, but how else can I hook this up? if os.name == "posix": try: from xpra.x11.bindings import posix_display_source #@UnusedImport except: pass #maybe running on OSX? hope for the best.. i = get_info() print_nested_dict(i, hex_keys=("data", "icc-data", "icc-profile"))
def main(): from xpra.platform import program_context from xpra.util import print_nested_dict from xpra.os_util import OSX, POSIX from xpra.log import enable_color with program_context("GUI-Properties"): enable_color() init() verbose = "-v" in sys.argv or "--verbose" in sys.argv if verbose: from xpra.log import get_all_loggers for x in get_all_loggers(): x.enable_debug() #naughty, but how else can I hook this up? if POSIX and not OSX: from xpra.x11.bindings.posix_display_source import init_posix_display_source #@UnresolvedImport init_posix_display_source() i = get_info() print_nested_dict(i, hex_keys=("data", "icc-data", "icc-profile")) return 0
def run_server(parser, opts, mode, xpra_file, extra_args): if opts.encoding and opts.encoding == "help": #avoid errors and warnings: opts.encoding = "" opts.clipboard = False opts.notifications = False print("xpra server supports the following encodings:") print("(please wait, encoder initialization may take a few seconds)") #disable info logging which would be confusing here from xpra.log import get_all_loggers, set_default_level import logging set_default_level(logging.WARN) logging.root.setLevel(logging.WARN) for x in get_all_loggers(): x.logger.setLevel(logging.WARN) from xpra.server.server_base import ServerBase sb = ServerBase() sb.init(opts) #ensures that the threaded video helper init has completed #(by running it again, which will block on the init lock) from xpra.codecs.video_helper import getVideoHelper getVideoHelper().init() sb.init_encodings() from xpra.codecs.loader import encoding_help for e in sb.encodings: print(" * %s" % encoding_help(e)) return 0 assert mode in ("start", "upgrade", "shadow", "proxy") starting = mode == "start" upgrading = mode == "upgrade" shadowing = mode == "shadow" proxying = mode == "proxy" clobber = upgrading or opts.use_display #get the display name: if shadowing and len(extra_args) == 0: from xpra.scripts.main import guess_X11_display display_name = guess_X11_display() else: if len(extra_args) != 1: parser.error("need exactly 1 extra argument") display_name = extra_args.pop(0) if not shadowing and not proxying: display_name_check(display_name) if not shadowing and not proxying and not upgrading and opts.exit_with_children and not opts.start_child: sys.stderr.write( "--exit-with-children specified without any children to spawn; exiting immediately" ) return 1 atexit.register(run_cleanups) #the server class will usually override those: signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) dotxpra = DotXpra(opts.socket_dir) # Generate the script text now, because os.getcwd() will # change if/when we daemonize: script = xpra_runner_shell_script(xpra_file, os.getcwd(), opts.socket_dir) # Daemonize: if opts.daemon: #daemonize will chdir to "/", so try to use an absolute path: if opts.password_file: opts.password_file = os.path.abspath(opts.password_file) logfd = open_log_file(dotxpra, opts.log_file, display_name) assert logfd > 2 daemonize(logfd) # Write out a shell-script so that we can start our proxy in a clean # environment: write_runner_shell_script(dotxpra, script) from xpra.log import Logger log = Logger("server") try: # Initialize the sockets before the display, # That way, errors won't make us kill the Xvfb # (which may not be ours to kill at that point) bind_tcp = parse_bind_tcp(opts.bind_tcp) sockets = [] mdns_info = {"display": display_name, "username": getpass.getuser()} if opts.session_name: mdns_info["session"] = opts.session_name #tcp: for host, iport in bind_tcp: socket = setup_tcp_socket(host, iport) sockets.append(socket) #unix: socket, cleanup_socket = setup_local_socket(dotxpra, display_name, clobber, opts.mmap_group) if socket: #win32 returns None! sockets.append(socket) if opts.mdns: ssh_port = get_ssh_port() if ssh_port: mdns_publish(display_name, "ssh", [("", ssh_port)], mdns_info) if opts.mdns: mdns_publish(display_name, "tcp", bind_tcp, mdns_info) except Exception, e: log.error("cannot start server: failed to setup sockets: %s", e) return 1
def run_server(error_cb, opts, mode, xpra_file, extra_args): try: cwd = os.getcwd() except: cwd = os.path.expanduser("~") sys.stderr.write("current working directory does not exist, using '%s'\n" % cwd) if opts.encoding and opts.encoding=="help": #avoid errors and warnings: opts.encoding = "" opts.clipboard = False opts.notifications = False print("xpra server supports the following encodings:") print("(please wait, encoder initialization may take a few seconds)") #disable info logging which would be confusing here from xpra.log import get_all_loggers, set_default_level import logging set_default_level(logging.WARN) logging.root.setLevel(logging.WARN) for x in get_all_loggers(): x.logger.setLevel(logging.WARN) from xpra.server.server_base import ServerBase sb = ServerBase() sb.init(opts) #ensures that the threaded video helper init has completed #(by running it again, which will block on the init lock) from xpra.codecs.video_helper import getVideoHelper getVideoHelper().init() sb.init_encodings() from xpra.codecs.loader import encoding_help for e in sb.encodings: print(" * %s" % encoding_help(e)) return 0 assert mode in ("start", "upgrade", "shadow", "proxy") starting = mode == "start" upgrading = mode == "upgrade" shadowing = mode == "shadow" proxying = mode == "proxy" clobber = upgrading or opts.use_display if upgrading or shadowing: #there should already be one running opts.pulseaudio = False #get the display name: if shadowing and len(extra_args)==0: if sys.platform.startswith("win") or sys.platform.startswith("darwin"): #just a virtual name for the only display available: display_name = ":0" else: from xpra.scripts.main import guess_X11_display display_name = guess_X11_display(opts.socket_dir) elif upgrading and len(extra_args)==0: from xpra.scripts.main import guess_xpra_display display_name = guess_xpra_display(opts.socket_dir) else: if len(extra_args) > 1: error_cb("too many extra arguments: only expected a display number") if len(extra_args) == 1: display_name = extra_args[0] if not shadowing and not proxying: display_name_check(display_name) else: if proxying: error_cb("you must specify a free virtual display name to use with the proxy server") if not opts.displayfd: error_cb("displayfd support is not enabled on this system, you must specify the display to use") if opts.use_display: #only use automatic guess for xpra displays and not X11 displays: from xpra.scripts.main import guess_xpra_display #@Reimport display_name = guess_xpra_display(opts.socket_dir) else: # We will try to find one automaticaly # Use the temporary magic value 'S' as marker: display_name = 'S' + str(os.getpid()) if not shadowing and not proxying and not upgrading and opts.exit_with_children and not opts.start_child: error_cb("--exit-with-children specified without any children to spawn; exiting immediately") atexit.register(run_cleanups) #the server class will usually override those: signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) dotxpra = DotXpra(opts.socket_dir) # Generate the script text now, because os.getcwd() will # change if/when we daemonize: script = xpra_runner_shell_script(xpra_file, os.getcwd(), opts.socket_dir) stdout = sys.stdout stderr = sys.stderr # Daemonize: if opts.daemon: #daemonize will chdir to "/", so try to use an absolute path: if opts.password_file: opts.password_file = os.path.abspath(opts.password_file) # At this point we may not know the display name, # so log_filename0 may point to a temporary file which we will rename later log_filename0 = select_log_file(dotxpra, opts.log_file, display_name) logfd = open_log_file(log_filename0) assert logfd > 2 stdout, stderr = daemonize(logfd) try: stderr.write("Entering daemon mode; " + "any further errors will be reported to:\n" + (" %s\n" % log_filename0)) except: #this can happen if stderr is closed by the caller already pass if os.name=="posix": # Write out a shell-script so that we can start our proxy in a clean # environment: write_runner_shell_script(dotxpra, script) from xpra.log import Logger log = Logger("server") mdns_recs = [] sockets = [] try: # Initialize the TCP sockets before the display, # That way, errors won't make us kill the Xvfb # (which may not be ours to kill at that point) bind_tcp = parse_bind_tcp(opts.bind_tcp) for host, iport in bind_tcp: socket = setup_tcp_socket(host, iport) sockets.append(socket) if opts.mdns: mdns_recs.append(("tcp", bind_tcp)) except Exception as e: log.error("cannot start server: failed to setup sockets: %s", e) return 1 # Do this after writing out the shell script: if display_name[0] != 'S': os.environ["DISPLAY"] = display_name sanitize_env() configure_imsettings_env(opts.input_method) # Start the Xvfb server first to get the display_name if needed xvfb = None xvfb_pid = None if not shadowing and not proxying and not clobber: try: xvfb, display_name = start_Xvfb(opts.xvfb, display_name) except OSError as e: log.error("Error starting Xvfb: %s\n", e) return 1 xvfb_pid = xvfb.pid #always update as we may now have the "real" display name: os.environ["DISPLAY"] = display_name if opts.daemon: log_filename1 = select_log_file(dotxpra, opts.log_file, display_name) if log_filename0 != log_filename1: # we now have the correct log filename, so use it: os.rename(log_filename0, log_filename1) stderr.write("Actual log file name is now: %s\n" % log_filename1) stdout.close() stderr.close() if not check_xvfb_process(xvfb): #xvfb problem: exit now return 1 #setup unix domain socket: socket, cleanup_socket = setup_local_socket(dotxpra, display_name, clobber, opts.mmap_group, opts.socket_permissions) if socket: #win32 returns None! sockets.append(socket) if opts.mdns: ssh_port = get_ssh_port() if ssh_port: mdns_recs.append(("ssh", [("", ssh_port)])) #publish mdns records: if opts.mdns: from xpra.platform.info import get_username mdns_info = {"display" : display_name, "username": get_username()} if opts.session_name: mdns_info["session"] = opts.session_name for mode, listen_on in mdns_recs: mdns_publish(display_name, mode, listen_on, mdns_info) if not check_xvfb_process(xvfb): #xvfb problem: exit now return 1 display = None if not sys.platform.startswith("win") and not sys.platform.startswith("darwin") and not proxying: display = verify_display_ready(xvfb, display_name, shadowing) if not display: return 1 elif not proxying: assert "gtk" not in sys.modules import gtk #@Reimport assert gtk if shadowing: from xpra.platform.shadow_server import ShadowServer app = ShadowServer() info = "shadow" elif proxying: from xpra.server.proxy_server import ProxyServer app = ProxyServer() info = "proxy" else: assert starting or upgrading from xpra.x11.gtk_x11 import gdk_display_source assert gdk_display_source #(now we can access the X11 server) if clobber: #get the saved pid (there should be one): xvfb_pid = get_xvfb_pid() elif xvfb_pid is not None: #save the new pid (we should have one): save_xvfb_pid(xvfb_pid) #check for an existing window manager: from xpra.x11.gtk_x11.wm import wm_check if not wm_check(display, opts.wm_name, upgrading): return 1 try: # This import is delayed because the module depends on gtk: from xpra.x11.server import XpraServer from xpra.x11.bindings.window_bindings import X11WindowBindings #@UnresolvedImport X11Window = X11WindowBindings() except ImportError as e: log.error("Failed to load Xpra server components, check your installation: %s" % e) return 1 if not X11Window.displayHasXComposite(): log.error("Xpra is a compositing manager, it cannot use a display which lacks the XComposite extension!") return 1 app = XpraServer(clobber) info = "xpra" try: app.exec_cwd = cwd app.init(opts) except Exception as e: log.error("Error: cannot start the %s server", info, exc_info=True) log.error(str(e)) log.info("") return 1 #honour start child, html webserver, and setup child reaper if os.name=="posix" and not proxying and not upgrading and not shadowing: # start websockify? try: start_websockify(app.child_reaper, opts, bind_tcp) #websockify overrides the tcp proxy, so we must re-set it: app._tcp_proxy = opts.tcp_proxy except Exception as e: error_cb("failed to setup websockify html server: %s" % e) if opts.exit_with_children: assert opts.start_child, "exit-with-children was specified but start-child is missing!" if opts.start: for x in opts.start: if x: app.start_child(x, x, True) if opts.start_child: for x in opts.start_child: if x: app.start_child(x, x, False) log("%s(%s)", app.init_sockets, sockets) app.init_sockets(sockets) log("%s(%s)", app.init_when_ready, _when_ready) app.init_when_ready(_when_ready) #we got this far so the sockets have initialized and #the server should be able to manage the display #from now on, if we exit without upgrading we will also kill the Xvfb def kill_xvfb(): # Close our display(s) first, so the server dying won't kill us. log.info("killing xvfb with pid %s" % xvfb_pid) import gtk #@Reimport for display in gtk.gdk.display_manager_get().list_displays(): display.close() os.kill(xvfb_pid, signal.SIGTERM) if xvfb_pid is not None and not opts.use_display and not shadowing: _cleanups.append(kill_xvfb) try: log("running %s", app.run) e = app.run() log("%s()=%s", app.run, e) except KeyboardInterrupt: log.info("stopping on KeyboardInterrupt") e = 0 except Exception as e: log.error("server error", exc_info=True) e = -128 if e>0: # Upgrading/exiting, so leave X server running if kill_xvfb in _cleanups: _cleanups.remove(kill_xvfb) from xpra.server.server_core import ServerCore if e==ServerCore.EXITING_CODE: log.info("exiting: not cleaning up Xvfb") elif cleanup_socket in _cleanups: log.info("upgrading: not cleaning up Xvfb or socket") # don't delete the new socket (not ours) _cleanups.remove(cleanup_socket) log("cleanups=%s", _cleanups) e = 0 return e
def run_server(error_cb, opts, mode, xpra_file, extra_args): try: cwd = os.getcwd() except: cwd = os.path.expanduser("~") sys.stderr.write( "current working directory does not exist, using '%s'\n" % cwd) if opts.encoding and opts.encoding == "help": #avoid errors and warnings: opts.encoding = "" opts.clipboard = False opts.notifications = False print("xpra server supports the following encodings:") print("(please wait, encoder initialization may take a few seconds)") #disable info logging which would be confusing here from xpra.log import get_all_loggers, set_default_level import logging set_default_level(logging.WARN) logging.root.setLevel(logging.WARN) for x in get_all_loggers(): x.logger.setLevel(logging.WARN) from xpra.server.server_base import ServerBase sb = ServerBase() sb.init(opts) #ensures that the threaded video helper init has completed #(by running it again, which will block on the init lock) from xpra.codecs.video_helper import getVideoHelper getVideoHelper().init() sb.init_encodings() from xpra.codecs.loader import encoding_help for e in sb.encodings: print(" * %s" % encoding_help(e)) return 0 assert mode in ("start", "upgrade", "shadow", "proxy") starting = mode == "start" upgrading = mode == "upgrade" shadowing = mode == "shadow" proxying = mode == "proxy" clobber = upgrading or opts.use_display start_vfb = not shadowing and not proxying and not clobber if upgrading or shadowing: #there should already be one running opts.pulseaudio = False #get the display name: if shadowing and len(extra_args) == 0: if sys.platform.startswith("win") or sys.platform.startswith("darwin"): #just a virtual name for the only display available: display_name = ":0" else: from xpra.scripts.main import guess_X11_display display_name = guess_X11_display(opts.socket_dir, opts.socket_dirs) elif upgrading and len(extra_args) == 0: display_name = guess_xpra_display(opts.socket_dir, opts.socket_dirs) else: if len(extra_args) > 1: error_cb( "too many extra arguments: only expected a display number") if len(extra_args) == 1: display_name = extra_args[0] if not shadowing and not proxying: display_name_check(display_name) else: if proxying: error_cb( "you must specify a free virtual display name to use with the proxy server" ) if not opts.displayfd: error_cb( "displayfd support is not enabled on this system, you must specify the display to use" ) if opts.use_display: #only use automatic guess for xpra displays and not X11 displays: display_name = guess_xpra_display(opts.socket_dir, opts.socket_dirs) else: # We will try to find one automaticaly # Use the temporary magic value 'S' as marker: display_name = 'S' + str(os.getpid()) if not shadowing and not proxying and not upgrading and opts.exit_with_children and not opts.start_child: error_cb( "--exit-with-children specified without any children to spawn; exiting immediately" ) atexit.register(run_cleanups) #the server class will usually override those: #SIGINT breaks GTK3.. (but there are no py3k servers!) signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) # Generate the script text now, because os.getcwd() will # change if/when we daemonize: script = xpra_runner_shell_script(xpra_file, os.getcwd(), opts.socket_dir) if start_vfb or opts.daemon: #we will probably need a log dir #either for the vfb, or for our own log file log_dir = os.path.expanduser(opts.log_dir) if not os.path.exists(log_dir): try: os.mkdir(log_dir, 0o700) except OSError as e: raise InitException( "failed to create the Xorg log directory '%s': %s" % (xorg_log_dir, e)) stdout = sys.stdout stderr = sys.stderr # Daemonize: if opts.daemon: #daemonize will chdir to "/", so try to use an absolute path: if opts.password_file: opts.password_file = os.path.abspath(opts.password_file) # At this point we may not know the display name, # so log_filename0 may point to a temporary file which we will rename later log_filename0 = select_log_file(log_dir, opts.log_file, display_name) logfd = open_log_file(log_filename0) assert logfd > 2 stdout, stderr = daemonize(logfd) try: stderr.write("Entering daemon mode; " + "any further errors will be reported to:\n" + (" %s\n" % log_filename0)) except: #this can happen if stderr is closed by the caller already pass if os.name == "posix": # Write out a shell-script so that we can start our proxy in a clean # environment: write_runner_shell_script(script) from xpra.log import Logger log = Logger("server") #warn early about this: if starting: de = os.environ.get("XDG_SESSION_DESKTOP") or os.environ.get( "SESSION_DESKTOP") if de and (opts.pulseaudio or opts.notifications): log.warn( "Warning: xpra start from an existing '%s' desktop session", de) log.warn(" pulseaudio and notifications forwarding may not work") log.warn( " try using a clean environment, a dedicated user, or turn off those options" ) mdns_recs = [] sockets = [] # Initialize the TCP sockets before the display, # That way, errors won't make us kill the Xvfb # (which may not be ours to kill at that point) bind_tcp = parse_bind_tcp(opts.bind_tcp) for host, iport in bind_tcp: socket = setup_tcp_socket(host, iport) sockets.append(socket) if opts.mdns: rec = "tcp", [(host, iport)] mdns_recs.append(rec) # Do this after writing out the shell script: if display_name[0] != 'S': os.environ["DISPLAY"] = display_name sanitize_env() configure_imsettings_env(opts.input_method) # Start the Xvfb server first to get the display_name if needed xvfb = None xvfb_pid = None if start_vfb: try: xvfb, display_name = start_Xvfb(opts.xvfb, display_name) except OSError as e: log.error("Error starting Xvfb: %s\n", e) return 1 xvfb_pid = xvfb.pid #always update as we may now have the "real" display name: os.environ["DISPLAY"] = display_name if opts.daemon: log_filename1 = select_log_file(log_dir, opts.log_file, display_name) if log_filename0 != log_filename1: # we now have the correct log filename, so use it: os.rename(log_filename0, log_filename1) stderr.write("Actual log file name is now: %s\n" % log_filename1) stdout.close() stderr.close() if not check_xvfb_process(xvfb): #xvfb problem: exit now return 1 #setup unix domain socket: socket, cleanup_socket = setup_local_socket(opts.socket_dir, opts.socket_dirs, display_name, clobber, opts.mmap_group, opts.socket_permissions) if socket: #win32 returns None! sockets.append(socket) if opts.mdns: ssh_port = get_ssh_port() if ssh_port: mdns_recs.append(("ssh", [("", ssh_port)])) #publish mdns records: if opts.mdns: from xpra.platform.info import get_username mdns_info = {"display": display_name, "username": get_username()} if opts.session_name: mdns_info["session"] = opts.session_name for mode, listen_on in mdns_recs: mdns_publish(display_name, mode, listen_on, mdns_info) if not check_xvfb_process(xvfb): #xvfb problem: exit now return 1 display = None if not sys.platform.startswith("win") and not sys.platform.startswith( "darwin") and not proxying: display = verify_display_ready(xvfb, display_name, shadowing) if not display: return 1 elif not proxying: no_gtk() import gtk #@Reimport assert gtk if shadowing: from xpra.platform.shadow_server import ShadowServer app = ShadowServer() info = "shadow" elif proxying: from xpra.server.proxy.proxy_server import ProxyServer app = ProxyServer() info = "proxy" else: assert starting or upgrading from xpra.x11.gtk2 import gdk_display_source assert gdk_display_source #(now we can access the X11 server) if clobber: #get the saved pid (there should be one): xvfb_pid = get_xvfb_pid() elif xvfb_pid is not None: #save the new pid (we should have one): save_xvfb_pid(xvfb_pid) #check for an existing window manager: from xpra.x11.gtk2.wm import wm_check if not wm_check(display, opts.wm_name, upgrading): return 1 try: # This import is delayed because the module depends on gtk: from xpra.x11.server import XpraServer from xpra.x11.bindings.window_bindings import X11WindowBindings #@UnresolvedImport X11Window = X11WindowBindings() except ImportError as e: log.error( "Failed to load Xpra server components, check your installation: %s" % e) return 1 if not X11Window.displayHasXComposite(): log.error( "Xpra is a compositing manager, it cannot use a display which lacks the XComposite extension!" ) return 1 log("XShape=%s", X11Window.displayHasXShape()) app = XpraServer(clobber) info = "xpra" #we got this far so the sockets have initialized and #the server should be able to manage the display #from now on, if we exit without upgrading we will also kill the Xvfb def kill_xvfb(): # Close our display(s) first, so the server dying won't kill us. log.info("killing xvfb with pid %s" % xvfb_pid) import gtk #@Reimport for display in gtk.gdk.display_manager_get().list_displays(): display.close() os.kill(xvfb_pid, signal.SIGTERM) if xvfb_pid is not None and not opts.use_display and not shadowing: _cleanups.append(kill_xvfb) try: app.exec_cwd = cwd app.init(opts) except InitException as e: log.error("xpra server initialization error:") log.error(" %s", e) return 1 except Exception as e: log.error("Error: cannot start the %s server", info, exc_info=True) log.error(str(e)) log.info("") return 1 #honour start child, html webserver, and setup child reaper if os.name == "posix" and not proxying and not upgrading and not shadowing: # start websockify? try: start_websockify(app.child_reaper, opts, bind_tcp) #websockify overrides the tcp proxy, so we must re-set it: app._tcp_proxy = opts.tcp_proxy except Exception as e: error_cb("failed to setup websockify html server: %s" % e) if opts.exit_with_children: assert opts.start_child, "exit-with-children was specified but start-child is missing!" if opts.start: for x in opts.start: if x: app.start_child(x, x, True) if opts.start_child: for x in opts.start_child: if x: app.start_child(x, x, False) log("%s(%s)", app.init_sockets, sockets) app.init_sockets(sockets) log("%s(%s)", app.init_when_ready, _when_ready) app.init_when_ready(_when_ready) try: log("running %s", app.run) e = app.run() log("%s()=%s", app.run, e) except KeyboardInterrupt: log.info("stopping on KeyboardInterrupt") e = 0 except Exception as e: log.error("server error", exc_info=True) e = -128 if e > 0: # Upgrading/exiting, so leave X server running if kill_xvfb in _cleanups: _cleanups.remove(kill_xvfb) from xpra.server.server_core import ServerCore if e == ServerCore.EXITING_CODE: log.info("exiting: not cleaning up Xvfb") elif cleanup_socket in _cleanups: log.info("upgrading: not cleaning up Xvfb or socket") # don't delete the new socket (not ours) _cleanups.remove(cleanup_socket) log("cleanups=%s", _cleanups) e = 0 return e
def run_server(error_cb, opts, mode, xpra_file, extra_args): try: cwd = os.getcwd() except: cwd = os.path.expanduser("~") sys.stderr.write("current working directory does not exist, using '%s'\n" % cwd) if opts.encoding and opts.encoding == "help": # avoid errors and warnings: opts.encoding = "" opts.clipboard = False opts.notifications = False print("xpra server supports the following encodings:") print("(please wait, encoder initialization may take a few seconds)") # disable info logging which would be confusing here from xpra.log import get_all_loggers, set_default_level import logging set_default_level(logging.WARN) logging.root.setLevel(logging.WARN) for x in get_all_loggers(): x.logger.setLevel(logging.WARN) from xpra.server.server_base import ServerBase sb = ServerBase() sb.init(opts) # ensures that the threaded video helper init has completed # (by running it again, which will block on the init lock) from xpra.codecs.video_helper import getVideoHelper getVideoHelper().init() sb.init_encodings() from xpra.codecs.loader import encoding_help for e in sb.encodings: print(" * %s" % encoding_help(e)) return 0 assert mode in ("start", "upgrade", "shadow", "proxy") starting = mode == "start" upgrading = mode == "upgrade" shadowing = mode == "shadow" proxying = mode == "proxy" clobber = upgrading or opts.use_display # get the display name: if shadowing and len(extra_args) == 0: if sys.platform.startswith("win") or sys.platform.startswith("darwin"): # just a virtual name for the only display available: display_name = ":0" else: from xpra.scripts.main import guess_X11_display display_name = guess_X11_display(opts.socket_dir) elif upgrading and len(extra_args) == 0: from xpra.scripts.main import guess_xpra_display display_name = guess_xpra_display(opts.socket_dir) else: if len(extra_args) > 1: error_cb("too many extra arguments: only expected a display number") if len(extra_args) == 1: display_name = extra_args[0] if not shadowing and not proxying: display_name_check(display_name) else: if proxying: error_cb("you must specify a free virtual display name to use with the proxy server") if not opts.displayfd: error_cb("displayfd support is not enabled on this system, you must specify the display to use") if opts.use_display: # only use automatic guess for xpra displays and not X11 displays: from xpra.scripts.main import guess_xpra_display # @Reimport display_name = guess_xpra_display(opts.socket_dir) else: # We will try to find one automaticaly # Use the temporary magic value 'S' as marker: display_name = "S" + str(os.getpid()) if not shadowing and not proxying and not upgrading and opts.exit_with_children and not opts.start_child: error_cb("--exit-with-children specified without any children to spawn; exiting immediately") atexit.register(run_cleanups) # the server class will usually override those: signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) dotxpra = DotXpra(opts.socket_dir) # Generate the script text now, because os.getcwd() will # change if/when we daemonize: script = xpra_runner_shell_script(xpra_file, os.getcwd(), opts.socket_dir) stdout = sys.stdout stderr = sys.stderr # Daemonize: if opts.daemon: # daemonize will chdir to "/", so try to use an absolute path: if opts.password_file: opts.password_file = os.path.abspath(opts.password_file) # At this point we may not know the display name, # so log_filename0 may point to a temporary file which we will rename later log_filename0 = select_log_file(dotxpra, opts.log_file, display_name) logfd = open_log_file(log_filename0) assert logfd > 2 stdout, stderr = daemonize(logfd) try: stderr.write( "Entering daemon mode; " + "any further errors will be reported to:\n" + (" %s\n" % log_filename0) ) except: # this can happen if stderr is closed by the caller already pass # Write out a shell-script so that we can start our proxy in a clean # environment: write_runner_shell_script(dotxpra, script) from xpra.log import Logger log = Logger("server") mdns_recs = [] sockets = [] try: # Initialize the TCP sockets before the display, # That way, errors won't make us kill the Xvfb # (which may not be ours to kill at that point) bind_tcp = parse_bind_tcp(opts.bind_tcp) for host, iport in bind_tcp: socket = setup_tcp_socket(host, iport) sockets.append(socket) if opts.mdns: mdns_recs.append(("tcp", bind_tcp)) except Exception, e: log.error("cannot start server: failed to setup sockets: %s", e) return 1
def run_server(error_cb, opts, mode, xpra_file, extra_args): try: cwd = os.getcwd() except: cwd = os.path.expanduser("~") sys.stderr.write( "current working directory does not exist, using '%s'\n" % cwd) if opts.encoding and opts.encoding == "help": #avoid errors and warnings: opts.encoding = "" opts.clipboard = False opts.notifications = False print("xpra server supports the following encodings:") print("(please wait, encoder initialization may take a few seconds)") #disable info logging which would be confusing here from xpra.log import get_all_loggers, set_default_level import logging set_default_level(logging.WARN) logging.root.setLevel(logging.WARN) for x in get_all_loggers(): x.logger.setLevel(logging.WARN) from xpra.server.server_base import ServerBase sb = ServerBase() sb.init(opts) #ensures that the threaded video helper init has completed #(by running it again, which will block on the init lock) from xpra.codecs.video_helper import getVideoHelper getVideoHelper().init() sb.init_encodings() from xpra.codecs.loader import encoding_help for e in sb.encodings: print(" * %s" % encoding_help(e)) return 0 assert mode in ("start", "upgrade", "shadow", "proxy") starting = mode == "start" upgrading = mode == "upgrade" shadowing = mode == "shadow" proxying = mode == "proxy" clobber = upgrading or opts.use_display #get the display name: if shadowing and len(extra_args) == 0: if sys.platform.startswith("win") or sys.platform.startswith("darwin"): #just a virtual name for the only display available: display_name = ":0" else: from xpra.scripts.main import guess_X11_display display_name = guess_X11_display(opts.socket_dir) elif upgrading and len(extra_args) == 0: from xpra.scripts.main import guess_xpra_display display_name = guess_xpra_display(opts.socket_dir) else: if len(extra_args) > 1: error_cb( "too many extra arguments: only expected a display number") if len(extra_args) == 1: display_name = extra_args[0] if not shadowing and not proxying: display_name_check(display_name) else: if proxying: error_cb( "you must specify a free virtual display name to use with the proxy server" ) if not opts.displayfd: error_cb( "displayfd support is not enabled on this system, you must specify the display to use" ) if opts.use_display: #only use automatic guess for xpra displays and not X11 displays: from xpra.scripts.main import guess_xpra_display #@Reimport display_name = guess_xpra_display(opts.socket_dir) else: # We will try to find one automaticaly # Use the temporary magic value 'S' as marker: display_name = 'S' + str(os.getpid()) if not shadowing and not proxying and not upgrading and opts.exit_with_children and not opts.start_child: error_cb( "--exit-with-children specified without any children to spawn; exiting immediately" ) atexit.register(run_cleanups) #the server class will usually override those: signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) dotxpra = DotXpra(opts.socket_dir) # Generate the script text now, because os.getcwd() will # change if/when we daemonize: script = xpra_runner_shell_script(xpra_file, os.getcwd(), opts.socket_dir) stdout = sys.stdout stderr = sys.stderr # Daemonize: if opts.daemon: #daemonize will chdir to "/", so try to use an absolute path: if opts.password_file: opts.password_file = os.path.abspath(opts.password_file) # At this point we may not know the display name, # so log_filename0 may point to a temporary file which we will rename later log_filename0 = select_log_file(dotxpra, opts.log_file, display_name) logfd = open_log_file(log_filename0) assert logfd > 2 stdout, stderr = daemonize(logfd) try: stderr.write("Entering daemon mode; " + "any further errors will be reported to:\n" + (" %s\n" % log_filename0)) except: #this can happen if stderr is closed by the caller already pass # Write out a shell-script so that we can start our proxy in a clean # environment: write_runner_shell_script(dotxpra, script) from xpra.log import Logger log = Logger("server") mdns_recs = [] sockets = [] try: # Initialize the TCP sockets before the display, # That way, errors won't make us kill the Xvfb # (which may not be ours to kill at that point) bind_tcp = parse_bind_tcp(opts.bind_tcp) for host, iport in bind_tcp: socket = setup_tcp_socket(host, iport) sockets.append(socket) if opts.mdns: mdns_recs.append(("tcp", bind_tcp)) except Exception, e: log.error("cannot start server: failed to setup sockets: %s", e) return 1
def run_server(parser, opts, mode, xpra_file, extra_args): if opts.encoding and opts.encoding=="help": #avoid errors and warnings: opts.encoding = "" opts.clipboard = False opts.notifications = False print("xpra server supports the following encodings:") print("(please wait, encoder initialization may take a few seconds)") #disable info logging which would be confusing here from xpra.log import get_all_loggers, set_default_level import logging set_default_level(logging.WARN) logging.root.setLevel(logging.WARN) for x in get_all_loggers(): x.logger.setLevel(logging.WARN) from xpra.server.server_base import ServerBase sb = ServerBase() sb.init(opts) #ensures that the threaded video helper init has completed #(by running it again, which will block on the init lock) from xpra.codecs.video_helper import getVideoHelper getVideoHelper().init() sb.init_encodings() from xpra.codecs.loader import encoding_help for e in sb.encodings: print(" * %s" % encoding_help(e)) return 0 assert mode in ("start", "upgrade", "shadow", "proxy") starting = mode == "start" upgrading = mode == "upgrade" shadowing = mode == "shadow" proxying = mode == "proxy" clobber = upgrading or opts.use_display #get the display name: if shadowing and len(extra_args)==0: from xpra.scripts.main import guess_X11_display display_name = guess_X11_display() else: if len(extra_args) != 1: parser.error("need exactly 1 extra argument") display_name = extra_args.pop(0) if not shadowing and not proxying: display_name_check(display_name) if not shadowing and not proxying and not upgrading and opts.exit_with_children and not opts.start_child: sys.stderr.write("--exit-with-children specified without any children to spawn; exiting immediately") return 1 atexit.register(run_cleanups) #the server class will usually override those: signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) dotxpra = DotXpra(opts.socket_dir) # Generate the script text now, because os.getcwd() will # change if/when we daemonize: script = xpra_runner_shell_script(xpra_file, os.getcwd(), opts.socket_dir) # Daemonize: if opts.daemon: #daemonize will chdir to "/", so try to use an absolute path: if opts.password_file: opts.password_file = os.path.abspath(opts.password_file) logfd = open_log_file(dotxpra, opts.log_file, display_name) assert logfd > 2 daemonize(logfd) # Write out a shell-script so that we can start our proxy in a clean # environment: write_runner_shell_script(dotxpra, script) from xpra.log import Logger log = Logger("server") try: # Initialize the sockets before the display, # That way, errors won't make us kill the Xvfb # (which may not be ours to kill at that point) bind_tcp = parse_bind_tcp(opts.bind_tcp) sockets = [] mdns_info = {"display" : display_name, "username": getpass.getuser()} if opts.session_name: mdns_info["session"] = opts.session_name #tcp: for host, iport in bind_tcp: socket = setup_tcp_socket(host, iport) sockets.append(socket) #unix: socket, cleanup_socket = setup_local_socket(dotxpra, display_name, clobber, opts.mmap_group) if socket: #win32 returns None! sockets.append(socket) if opts.mdns: ssh_port = get_ssh_port() if ssh_port: mdns_publish(display_name, "ssh", [("", ssh_port)], mdns_info) if opts.mdns: mdns_publish(display_name, "tcp", bind_tcp, mdns_info) except Exception, e: log.error("cannot start server: failed to setup sockets: %s", e) return 1
def _process_control(self, packet): command = bytestostr(packet[1]) if command == "show_session_info": args = packet[2:] log("calling %s%s on server request", self.show_session_info, args) self.show_session_info(*args) elif command == "show_bug_report": self.show_bug_report() elif command in ("enable_%s" % x for x in compression.get_enabled_compressors()): compressor = command.split("_")[1] log.info("switching to %s on server request", compressor) self._protocol.enable_compressor(compressor) elif command in ("enable_%s" % x for x in packet_encoding.get_enabled_encoders()): pe = command.split("_")[1] log.info("switching to %s on server request", pe) self._protocol.enable_encoder(pe) elif command == "name": assert len(args) >= 3 self.server_session_name = args[2] log.info("session name updated from server: %s", self.server_session_name) #TODO: reset tray tooltip, session info title, etc.. elif command == "debug": args = packet[2:] if not args: log.warn("not enough arguments for debug control command") return from xpra.log import ( add_debug_category, add_disabled_category, enable_debug_for, disable_debug_for, get_all_loggers, ) log_cmd = bytestostr(args[0]) if log_cmd == "status": dloggers = [ x for x in get_all_loggers() if x.is_debug_enabled() ] if dloggers: log.info("logging is enabled for:") for l in dloggers: log.info(" - %s", l) else: log.info("logging is not enabled for any loggers") return log_cmd = bytestostr(args[0]) if log_cmd not in ("enable", "disable"): log.warn( "invalid debug control mode: '%s' (must be 'enable' or 'disable')", log_cmd) return if len(args) < 2: log.warn( "not enough arguments for '%s' debug control command" % log_cmd) return loggers = [] #each argument is a group groups = [bytestostr(x) for x in args[1:]] for group in groups: #and each group is a list of categories #preferably separated by "+", #but we support "," for backwards compatibility: categories = [ v.strip() for v in group.replace("+", ",").split(",") ] if log_cmd == "enable": add_debug_category(*categories) loggers += enable_debug_for(*categories) else: assert log_cmd == "disable" add_disabled_category(*categories) loggers += disable_debug_for(*categories) if not loggers: log.info("%s debugging, no new loggers matching: %s", log_cmd, csv(groups)) else: log.info("%sd debugging for:", log_cmd) for l in loggers: log.info(" - %s", l) else: log.warn("received invalid control command from server: %s", command)