File: nx3.py

package info (click to toggle)
python-x2go 0.6.1.4-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 1,660 kB
  • sloc: python: 10,018; makefile: 217
file content (159 lines) | stat: -rw-r--r-- 6,181 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# -*- coding: utf-8 -*-

# Copyright (C) 2010-2023 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
#
# Python X2Go is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Python X2Go 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

"""\
X2GoProxy class - proxying your graphical connection through NX3.

"""
__NAME__ = 'x2goproxynx3-pylib'

__package__ = 'x2go.backends.proxy'
__name__    = 'x2go.backends.proxy.nx3'

# modules
import os

# Python X2Go modules
import x2go.log as log
import x2go.backends.proxy.base as base

from x2go.defaults import X2GOCLIENT_OS as _X2GOCLIENT_OS

class X2GoProxy(base.X2GoProxy):
    """\
    This :class:`x2go.backends.proxy.nx3.X2GoProxy` class is a NX version 3 based X2Go proxy connection class.

    It basically fills :class:`x2go.backends.proxy.base.X2GoProxy` variables with sensible content. Its
    methods mostly wrap around the corresponding methods of the parent class.


    """
    def __init__(self, *args, **kwargs):
        """\
        For available parameters refer to :class:`x2go.backends.proxy.base.X2GoProxy` class documentation.

        """
        base.X2GoProxy.__init__(self, *args, **kwargs)
        self.subsystem = 'NX Proxy'

        # setting some default environment variables, nxproxy paths etc.
        if _X2GOCLIENT_OS == "Windows":
            _nxproxy_paths = [
                os.path.join(os.environ["ProgramFiles"], os.path.normpath("PyHoca-GUI/nxproxy/nxproxy.exe")),
                os.path.join(os.environ["ProgramFiles"], os.path.normpath("x2goclient/nxproxy.exe")),
                os.path.join(os.environ["ProgramFiles"], os.path.normpath("NX Client for Windows/bin/nxproxy.exe")),
                os.path.normpath("../pyhoca-contrib/mswin/nxproxy-mswin/nxproxy-3.5.0.27_cygwin-2015-10-18/nxproxy.exe"),
            ]
            if 'NXPROXY_BINARY' in os.environ:
                _nxproxy_paths.insert(0, os.environ['NXPROXY_BINARY'])
            for _nxproxy_cmd in _nxproxy_paths:
                if os.path.exists(_nxproxy_cmd):
                    break
            self.PROXY_CMD = _nxproxy_cmd
        elif 'NXPROXY_BINARY' in os.environ:
            self.PROXY_CMD = os.environ['NXPROXY_BINARY']
        else:
            self.PROXY_CMD = "/usr/bin/nxproxy"
        self.PROXY_ENV.update({
            "NX_CLIENT": "/bin/true",
            "NX_ROOT": self.sessions_rootdir
        })
        self.PROXY_MODE = '-S'
        if _X2GOCLIENT_OS == "Windows":
            self.PROXY_OPTIONS = [
                "nx/nx" ,
                "retry=5",
                "composite=1",
                "connect=127.0.0.1",
                "clipboard=1",
                "cookie=%s" % self.session_info.cookie,
                "port=%s" % self.session_info.graphics_port,
                "errors=%s" % os.path.join(".", "..", "S-%s" % self.session_info.name, self.session_errors, ),
            ]
        else:
            self.PROXY_OPTIONS = [
                "nx/nx" ,
                "retry=5",
                "composite=1",
                "connect=127.0.0.1",
                "clipboard=1",
                "cookie=%s" % self.session_info.cookie,
                "port=%s" % self.session_info.graphics_port,
                "errors=%s" % os.path.join(self.session_info.local_container, self.session_errors, ),
            ]

        self.PROXY_DISPLAY = self.session_info.display

    def _update_local_proxy_socket(self, port):
        """\
        Update the local proxy socket on port changes due to already-bound-to local TCP/IP port sockets.

        :param port: new local TCP/IP socket port
        :type port: ``int``

        """

        for idx, a in enumerate(self.PROXY_OPTIONS):
            if a.startswith('port='):
                self.PROXY_OPTIONS[idx] = 'port=%s' % port

    def _generate_cmdline(self):
        """\
        Generate the NX proxy command line for execution.


        """
        if _X2GOCLIENT_OS == "Windows":
            _options_filename = os.path.join(self.session_info.local_container, 'options')
            options = open(_options_filename, 'w')
            options.write(u'%s:%s' % (','.join(self.PROXY_OPTIONS), self.PROXY_DISPLAY))
            options.close()
            self.PROXY_OPTIONS= [ 'nx/nx', 'options=%s' % os.path.join(".", "..", "S-%s" % self.session_info.name, 'options'), ]

        cmd_line = [ self.PROXY_CMD, ]
        cmd_line.append(self.PROXY_MODE)
        _proxy_options = "%s:%s" % (",".join(self.PROXY_OPTIONS), self.PROXY_DISPLAY)
        cmd_line.append(_proxy_options)
        return cmd_line

    def process_proxy_options(self):
        base.X2GoProxy.process_proxy_options(self)

    def start_proxy(self):
        """\
        Start the thread runner and wait for the proxy to come up.


        :returns: a subprocess instance that knows about the externally started proxy command.

        :rtype: ``obj``

        """
        self.logger('starting local NX3 proxy...', loglevel=log.loglevel_INFO)
        self.logger('NX3 Proxy mode is server, cookie=%s, host=127.0.0.1, port=%s.' % (self.session_info.cookie, self.session_info.graphics_port,), loglevel=log.loglevel_DEBUG)
        self.logger('NX3 proxy writes session log to %s.' % os.path.join(self.session_info.local_container, 'session.log'), loglevel=log.loglevel_DEBUG)

        p, p_ok = base.X2GoProxy.start_proxy(self)

        if self.ok():
            self.logger('NX3 proxy is up and running.', loglevel=log.loglevel_INFO)
        else:
            self.logger('Bringing up NX3 proxy failed.', loglevel=log.loglevel_ERROR)

        return p, self.ok()