source: OpenRLabs-Git/web2py/applications/rlabs/modules/prereserves.py

main
Last change on this file was 8406aaa, checked in by David Fuertes <dfuertes@…>, 4 years ago

arreglado gitignore

  • Property mode set to 100644
File size: 8.7 KB
Line 
1# -*- coding: utf-8 -*-
2#################################################################################
3# @file    prereserves.py
4# @brief   
5# @warning None
6# @note Use: None     
7# @license GNU GPLv3+
8# @author  David Fuertes, EUPT, University of Zaragoza.
9#          Opengnsys Api Rest support provided by Juan Carlos García, EUPT, University of Zaragoza.
10# @version 1.1.0 - First version
11# @date    2019-15-11
12#################################################################################
13
14from gluon.storage import Storage
15
16from datetime import datetime, timedelta
17
18from ognsys import Ognsys
19from client_lab import Client
20from ados import adoDB_reserves, adoDB_users, adoDB_openRlabs_setup, adoDB_services, adoDB_prereserves
21
22class Reserve:
23    def __init__(self, db, reserve_db, context_pre) -> None:         
24        self.TIME_TO_BOOT =  timedelta(seconds=adoDB_openRlabs_setup.get_seconds_to_wait_reserve(db))
25       
26
27        self.db = db     
28
29        self.context = Storage()
30       
31        # Rellenamos context
32        for k,v in context_pre.items():
33            self.context[k] = v       
34       
35
36        self.opengnsys = Ognsys(db)
37        self.opengnsys.set_apikey(self.context['ou_id'])       
38                       
39        self.__set_context()
40
41        if reserve_db:
42            self.__set_context_from_reserve_db(reserve_db)
43
44        self.client = Client(self.context)
45   
46    def __set_context_from_reserve_db(self, reserve_db):       
47        self.context['id'] = reserve_db['id']
48        self.context['pc_id'] = reserve_db['pc_id']
49        self.context['image_id'] = reserve_db['image_id']
50        self.context['ip'] = reserve_db['ip']       
51        self.context['reserved_init_time'] = reserve_db['reserved_init_time']       
52
53    def __set_context(self):
54        service = adoDB_services.get_service_by_id(self.db, self.context['protocol_id'])
55
56        self.context['maxtime'] = self.__get_maxtime()
57        self.context['is_assigned'] = False
58        self.context['is_running'] = False
59        self.context['reserved_init_time'] = datetime.now()       
60        self.context['protocol'] = service['name']
61        self.context['port'] = service['port']       
62        self.context['expiration_time'] = self.context['finish_time']       
63       
64
65    def __get_maxtime(self):
66        time_to_finish = self.context['finish_time'] - datetime.now()
67        time_to_finish_hours = round(time_to_finish.total_seconds() / 3600)
68        if time_to_finish_hours == 0:
69            time_to_finish_hours = 1
70        return time_to_finish_hours
71
72    def set_host_is_running(self):
73        adoDB_reserves.set_is_running_true(self.db, self.context['pc_id'])
74
75    def host_is_not_booting(self):       
76        if (datetime.now() - self.context['reserved_init_time']) > self.TIME_TO_BOOT:
77            return True
78        else:
79            return False
80
81    def remove(self):
82        self.client.unreserve_remote_pc()       
83
84
85    def hosts_reserve_estropeado(self):
86        hosts_status = self.client.get_status_client()
87        if hosts_status == "off" or 'error' in hosts_status:
88            return True
89        else:
90            self.set_host_is_running()
91            return False
92
93    def do_host_reserve(self):
94        print("reservo hosts")
95           
96        host = self.client.reserve_remote_pc()       
97
98        if 'id' in host:
99            # Rellenamos context pues
100            # no existe reserva previa.
101            for k,v in host.items():
102                self.context[k] = v       
103           
104            print('insert reserva')                   
105            adoDB_reserves.insert(self.context)
106                           
107
108            self.client.update_context(self.context)
109           
110            print('eventos redirigidos')           
111            self.client.redirect_events()           
112            print('register timeout')           
113            self.client.register_session_timeout()
114
115           
116
117class PreReserve:
118
119    def __init__(self, db ,prereserve_in_db) -> None:
120        self.TIME_TO_DECREASE = timedelta(minutes=20)
121        self.MAX_ATTENPTED_BOOTS = 1
122
123        self.db = db
124
125        self.prereserve_in_db = prereserve_in_db
126
127        self.context = Storage()
128       
129        self.__set_context(prereserve_in_db)
130
131        self.reserves = []
132        self.__populate_reserves()
133
134    def __set_context(self, prereserve_in_db):
135        self.context['db'] = self.db
136        self.context['user_id'] = adoDB_users.get_admin_id(self.db)
137        self.context['ou_id'] = prereserve_in_db['ou_id']
138        self.context['lab_id'] = prereserve_in_db['lab_id']
139        self.context['prereserve_id'] = prereserve_in_db['id'] 
140        self.context['image_id'] = prereserve_in_db['image_id']
141        self.context['num_reserves'] = prereserve_in_db['num_reserves']       
142        self.context['init_time'] = prereserve_in_db['init_time']
143        self.context['finish_time'] = prereserve_in_db['finish_time']
144        self.context['last_decreased_time'] = prereserve_in_db['last_decreased_time']
145        self.context['attempted_boots'] = prereserve_in_db['attempted_boots']
146        self.context['protocol_id'] = prereserve_in_db['protocol']
147       
148
149    def __increase_num_attempted(self):       
150        self.prereserve_in_db.update_record(attempted_boots=self.prereserve_in_db['attempted_boots'] + 1)
151        self.db.commit()
152       
153        self.context['attempted_boots'] = self.prereserve_in_db['attempted_boots']
154
155    def __decrease_num_hosts(self):
156        if datetime.now() - self.context['last_decreased_time'] > self.TIME_TO_DECREASE:
157            print('decremento yes')
158            self.prereserve_in_db.update_record(num_reserves=self.prereserve_in_db['num_reserves'] - 1,
159                            last_decreased_time=datetime.now(),
160                            attempted_boots=0)
161
162            self.db.commit()
163            self.context['last_decreased_time'] = self.prereserve_in_db['last_decreased_time']
164
165
166        return self.prereserve_in_db['num_reserves']
167
168    ##
169    #  NOTA: Podriamos obtener reservas NO ASIGNADAS, en cuyo caso
170    #        la app SIEMPRE ofrecería n hosts disponibles. Es decir,
171    #        al ocuparse un hosts, se levantaría otro.
172    ##
173    def __populate_reserves(self):
174        reserves_by_lab_db = adoDB_reserves.get_by_lab_PreR(self.db, self.context['prereserve_id'], self.context['lab_id'])
175       
176        for reserve_db in reserves_by_lab_db:           
177            reserve = Reserve(self.db, reserve_db, self.context)
178            self.reserves.append(reserve)
179
180
181    def get_reserves(self):
182        return self.reserves
183
184    def expired(self):
185        if self.context['finish_time'] < datetime.now():
186            return True
187        else:
188            return False
189    def is_in_time(self):
190        if self.context['init_time'] < datetime.now() < self.context['finish_time']:
191            return True
192        else:
193            return False
194   
195    def remove(self):       
196        for reserve in self.reserves:         
197            reserve.remove()
198        adoDB_prereserves.remove_by_id(self.db, self.context['prereserve_id'])
199
200    def __remove_n_reserves(self, n):               
201        for reserve in self.reserves:
202            if reserve.context['is_assigned'] == False and n < 0:               
203                reserve.remove()
204                n = n + 1
205
206
207    def do_reserves(self):       
208        num_hosts_desired = self.context['num_reserves']
209        num_hosts_up = 0
210        for reserve in self.reserves:
211            if reserve.host_is_not_booting():               
212                if reserve.hosts_reserve_estropeado():
213                    print('estropeado')         
214                    reserve.remove()
215                    if ( datetime.now()  - self.context['last_decreased_time']) > self.TIME_TO_DECREASE:
216                        print('timepo decremento pasado')
217                        if self.context['attempted_boots'] > self.MAX_ATTENPTED_BOOTS:
218                            print('decremento host')
219                            num_hosts_desired = self.__decrease_num_hosts()
220                        else:
221                            print('incrmento num intentos')
222                            self.__increase_num_attempted()
223
224                else:
225                    reserve.set_host_is_running()                   
226                    num_hosts_up = num_hosts_up + 1
227            else:
228                num_hosts_up = num_hosts_up + 1
229               
230        if num_hosts_desired - num_hosts_up > 0:
231            for i in range(num_hosts_desired - num_hosts_up):
232                reserve = Reserve(self.db, None, self.context)
233                self.reserves.append(reserve)
234                reserve.do_host_reserve()
235       
236        if num_hosts_desired - num_hosts_up < 0:
237            self.__remove_n_reserves(num_hosts_desired - num_hosts_up)
Note: See TracBrowser for help on using the repository browser.