~libertine-team/libertine/trunk

« back to all changes in this revision

Viewing changes to tools/libertine-session-bridge

  • Committer: Bileto Bot
  • Date: 2016-09-14 14:45:48 UTC
  • mfrom: (161.1.2 libertine.1.4.1-release)
  • Revision ID: ci-train-bot@canonical.com-20160914144548-ajgnaxcmfq3bwpxp
* Refactor the libertine-session-bus to be a class, so we will be on the
  same process and we can actually test LSB more then just running it and
  checking exit code.
* Add a get_logger function to the libertine utils. This function will get
  the logger __libertiner_logger__ which will only be setup once, with one
  handler.
* Switch libertine-lxc-manager to be a DBus service and activate it on demand
  via DBus. (LP: #1591350)
* Add check for special LIBERTINE_JENKAAS_TESTING environment variable for
  the smoke testing harness.
* Bump version to 1.4.1.
* Return user to homepage when container has been destroyed from under them.
  (LP: #1604015)
* Introduce a method in ContainersConfig to refresh the database depending 
  on an md5 checksum.
* Creating the first container moves user to ContainersView screen.
  (LP: #1615697)
* Inject a ContainersConfig instance when creating containers.
* Fix crash in ContainersConfig when getting host arch by using HostInfo
  object.
* Create a signal to indicate that container creation has begun.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/python3
2
 
 
3
 
import dbus 
4
 
import libertine.utils
5
 
import os
6
 
import select
7
 
import signal
8
 
import sys
9
 
 
10
 
from socket import *
11
 
 
12
 
 
13
 
def accept_new_connection(host_adder, container_sock):
14
 
    newconn = container_sock.accept()[0]
15
 
    descriptors.append(newconn)
16
 
 
17
 
    host_sock = socket(AF_UNIX, SOCK_STREAM)
18
 
    host_sock.connect(host_adder)
19
 
    descriptors.append(host_sock)
20
 
 
21
 
    socket_pairs.append([newconn, host_sock])
22
 
 
23
 
 
24
 
def get_socket_pair(socket):
25
 
    for i in range(len(socket_pairs)):
26
 
        if socket in socket_pairs[i]:
27
 
            return socket_pairs[i]
28
 
 
29
 
 
30
 
def get_socket_partner(socket):
31
 
    socket_pair = get_socket_pair(socket)
32
 
 
33
 
    for i in range(len(socket_pair)):
34
 
        if socket != socket_pair[i]:
35
 
            return socket_pair[i]
36
 
 
37
 
 
38
 
def close_connections(remove_socket):
39
 
    partner_socket = get_socket_partner(remove_socket)
40
 
 
41
 
    socket_pair = get_socket_pair(remove_socket)
42
 
    socket_pairs.remove(socket_pair)
43
 
 
44
 
    descriptors.remove(remove_socket)
45
 
    remove_socket.shutdown(SHUT_RDWR)
46
 
    remove_socket.close()
47
 
 
48
 
    descriptors.remove(partner_socket)
49
 
    partner_socket.shutdown(SHUT_RDWR)
50
 
    partner_socket.close()
51
 
 
52
 
 
53
 
def close_all_connections():
54
 
    for i, j in socket_pairs:
55
 
        i.shutdown(SHUT_RDWR)
56
 
        i.close()
57
 
        j.shutdown(SHUT_RDWR)
58
 
        j.close()
59
 
 
60
 
 
61
 
def get_host_maliit_socket():
62
 
    address_bus_name    = "org.maliit.server"
63
 
    address_object_path = "/org/maliit/server/address"
64
 
    address_interface   = "org.maliit.Server.Address"
65
 
    address_property    = "address"
66
 
    
67
 
    session_bus = dbus.SessionBus()
68
 
    maliit_object = session_bus.get_object('org.maliit.server', '/org/maliit/server/address')
69
 
 
70
 
    interface = dbus.Interface(maliit_object, dbus.PROPERTIES_IFACE)
71
 
    address = interface.Get('org.maliit.Server.Address', 'address')
72
 
 
73
 
    partition_key = 'unix:abstract='
74
 
    address = address.split(',')[0]
75
 
    address = address.partition(partition_key)[2]
76
 
    address = "\0%s" % address
77
 
 
78
 
    return address
79
 
 
80
 
 
81
 
def get_host_dbus_socket():
82
 
    host_dbus_socket = ''
83
 
 
84
 
    with open(os.path.join(libertine.utils.get_user_runtime_dir(), 'dbus-session'), 'r') as fd:
85
 
        dbus_session_str = fd.read()
86
 
 
87
 
    fd.close()
88
 
 
89
 
    dbus_session_split = dbus_session_str.rsplit('=', 1)
90
 
    if len(dbus_session_split) > 1:
91
 
        host_dbus_socket = dbus_session_split[1].rstrip('\n')
92
 
        # We need to add a \0 to the start of an abstract socket path to connect to it
93
 
        if dbus_session_str.find('abstract') >= 0:
94
 
            host_dbus_socket = "\0%s" % host_dbus_socket
95
 
 
96
 
    return host_dbus_socket
97
 
 
98
 
 
99
 
def socket_cleanup(signum, frame):
100
 
    for socket in descriptors:
101
 
        socket.close()
102
 
 
103
 
    close_all_connections()
104
 
 
105
 
    for socket_path in session_socket_paths:
106
 
        os.remove(socket_path)
107
 
 
108
 
 
109
 
def main_loop():
110
 
    signal.signal(signal.SIGTERM, socket_cleanup)
111
 
    signal.signal(signal.SIGINT, socket_cleanup)
112
 
 
113
 
    while 1:
114
 
        try:
115
 
            rlist, wlist, elist = select.select(descriptors, [], [])
116
 
        except InterruptedError:
117
 
            continue
118
 
        except:
119
 
            break
120
 
 
121
 
        for sock in rlist:
122
 
            if sock.fileno() == -1:
123
 
                continue
124
 
 
125
 
            if sock in host_session_socket_path_map:
126
 
                accept_new_connection(host_session_socket_path_map[sock], sock)
127
 
 
128
 
            else:
129
 
                try:
130
 
                    data = sock.recv(4096)
131
 
                except:
132
 
                    close_connections(sock)
133
 
                    continue
134
 
 
135
 
                if len(data) == 0:
136
 
                    close_connections(sock)
137
 
                    continue
138
 
 
139
 
                send_sock = get_socket_partner(sock)
140
 
 
141
 
                if send_sock.fileno() < 0:
142
 
                    continue
143
 
 
144
 
                totalsent = 0
145
 
                while totalsent < len(data):
146
 
                    sent = send_sock.send(data)
147
 
 
148
 
                    if sent == 0:
149
 
                        close_connections(sock)
150
 
                        break
151
 
                    totalsent = totalsent + sent
152
 
 
153
 
 
154
 
def create_socket(session_socket_path):
155
 
    try:
156
 
        sock = socket(AF_UNIX, SOCK_STREAM)
157
 
    except:
158
 
        sock = None
159
 
    else:
160
 
        try:
161
 
            sock.bind(session_socket_path)
162
 
            sock.listen(5)
163
 
        except:
164
 
            sock.close()
165
 
            sock = None
166
 
        else:
167
 
            return sock
168
 
 
169
 
    return None
170
 
    
171
 
 
172
 
def create_container_socket(session_socket_path, get_host_session_path_function):
173
 
    container_session_sock = create_socket(session_socket_path)
174
 
 
175
 
    if container_session_sock is not None:
176
 
        try:
177
 
            host_session_path = get_host_session_path_function()
178
 
        except:
179
 
            container_session_sock.close()
180
 
            container_session_sock = None
181
 
            os.remove(session_socket_path)
182
 
            raise
183
 
        else:
184
 
            host_session_socket_path_map.update({container_session_sock:host_session_path})
185
 
 
186
 
            session_socket_paths.append(session_socket_path)
187
 
            descriptors.append(container_session_sock)
188
 
 
189
 
 
190
 
descriptors = []
191
 
host_session_socket_path_map = {}
192
 
session_socket_paths = []
193
 
 
194
 
# Required sockets:
195
 
create_container_socket(sys.argv[1], get_host_dbus_socket)
196
 
 
197
 
# Optional sockets:
198
 
try:
199
 
    create_container_socket(sys.argv[2], get_host_maliit_socket)
200
 
except:
201
 
    pass
202
 
 
203
 
socket_pairs = []
204
 
 
205
 
main_loop()