epoptes 5.46 KB
Newer Older
1
2
#!/usr/bin/python3

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Copyright (C) 2017 Centro de Computacao Cientifica e Software Livre
# Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
#
# This file is part of le-epoptes
#
# le-epoptes 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.
22

23

24
from subprocess import Popen, PIPE, STDOUT
Lucas's avatar
Lucas committed
25
26
from lelab.utils import call_error_dialog, check_if_user_is_in_group
from lelab.utils import FailedToConnectWithDbusException
27
28
import socket
import logging
29
import lelab.services as services
30
import psutil
31
import time
32
import sys
33
import signal
34

35

Lucas's avatar
Lucas committed
36
class LEEpoptes(object):
37
38
39
40
41
42
43

    epoptes_bin = '/usr/bin/epoptes.real'
    config_file = '/etc/default/epoptes-client'
    default_port = '789'

    def __init__(self):

44
45
        # Check if the current user is in the 'epoptes' group

Lucas's avatar
Lucas committed
46
        if(not check_if_user_is_in_group(psutil.users()[0].name, "epoptes")):
47
48
            call_error_dialog("The current user is not in the 'epoptes' "
                              "group. For more info, check the LE6 manual.")
Lucas's avatar
Lucas committed
49
            exit(1)
50
        try:
51
            self.conn = services.get_connection()
52
53
        except FailedToConnectWithDbusException as e:
            call_error_dialog(str(e))
Lucas's avatar
Lucas committed
54
            exit(1)
55
56
57
58
59
60
61
62
63
64
65
66
67
68

    def get_current_server(self):
        myhost = socket.gethostname() + ".local"
        myport = self.default_port

        with open(self.config_file) as conf:
            for line in conf:
                if line.startswith("PORT="):
                    myport = self.default_port
                    break

        return myhost + ':' + myport

    def run(self):
69

70
        my_server = self.get_current_server()
71
        current_server = self.conn.get_attribute('epoptes', '_server')
72
73
74
75
76

        logging.debug("Checking server my_server=%s, current_server=%s",
                      my_server, current_server)

        if my_server != current_server:
77

78
79
            if self.conn.get_attribute('epoptes', '_status') == 'disabled':

80
81
82
                call_error_dialog("Epoptes is disabled. Ask the system "
                                  "administrator to enable it using the "
                                  "control panel.")
83
84
85
86

            else:

                if current_server != '':
Lucas's avatar
Lucas committed
87
88
89
                    logging.info("The current server is %s. Changing "
                                 "server to local machine instead.",
                                 current_server)
90
                logging.info("Starting server %s", my_server)
Lucas's avatar
Lucas committed
91

92
                self.conn.advertise('epoptes')
93
94
                if self.wait_for_lelab():
                    self.open_epoptes()
95

Lucas's avatar
Lucas committed
96
                self.close_epoptes(my_server)
97
98

        else:
Lucas's avatar
Lucas committed
99
100
            call_error_dialog("This computer is already registered as an"
                              " epoptes server.")
101
102

    def open_epoptes(self):
103
104

        # Run real epoptes
105
106
107
108
        params = [self.epoptes_bin] + sys.argv[1:]
        p = Popen(params, stderr=STDOUT, stdout=PIPE)
        p.wait()

Lucas's avatar
Lucas committed
109
110
111
112
113
114
    def close_epoptes(self, server):

        # Remove service
        logging.info("Closing server %s", server)
        self.conn.remove('epoptes')
        logging.debug("Server %s closed", server)
115

116
117
118
119
120
    def wait_for_lelab(self):

        # Wait for le-lab to register the epoptes service
        timeout = 0
        while True:
121
            if self.conn.get_attribute('epoptes', '_status') == 'server':
122
123
124
125
                break

            timeout += 1
            if timeout == 10:
Lucas's avatar
Lucas committed
126
127
128
                call_error_dialog("Epoptes was unable to establish a "
                                  "connection with le-lab. Please check "
                                  "your internet connection.")
129
130
                return False

Lucas's avatar
Lucas committed
131
132
            logging.debug("Waiting for le-lab to detect the local epoptes "
                          "service...")
133
134
            time.sleep(1)
        return True
135
136


137
138
139
140
141
def get_lock(proc_name):
    get_lock._lock_socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    try:
        get_lock._lock_socket.bind('\0' + proc_name)
    except socket.error:
Lucas's avatar
Lucas committed
142
143
144
        proc = Popen("xdotool search --class epoptes.real",
                     shell=True, stdout=PIPE, stderr=PIPE)
        output, err = proc.communicate()
145
146
        eu = [int(x) for x in output.split()]
        for x in eu:
Lucas's avatar
Lucas committed
147
148
            Popen("xdotool windowactivate " + str(x), shell=True,
                  stdout=PIPE, stderr=PIPE)
149
        sys.exit()
Lucas's avatar
Lucas committed
150
151
152
153
154


def signal_handler(signal, frame):
    logging.info("Signal %s received, closing program|frame: %s",
                 str(signal), str(frame))
155
156
    return

157

158
if __name__ == "__main__":
Lucas's avatar
Lucas committed
159
160
161
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)
    signal.signal(signal.SIGABRT, signal_handler)
162
    get_lock("epoptes")
163
    # Setup log info
164
165
166
167
168
169
    loglevel = getattr(logging, 'DEBUG')
    logformat = '%(asctime)s:%(levelname)s:%(message)s'
    logging.basicConfig(level=loglevel, format=logformat)

    epoptes = LEEpoptes()
    epoptes.run()