source: ogClient-Git/src/live/ogOperations.py @ fa0e48a

Last change on this file since fa0e48a was b5c3f58, checked in by OpenGnSys Support Team <soporte-og@…>, 4 years ago

#1037 Add disk type

Add ogClient support to receive, parse and send disk type data from the cloning
engine when refreshing disks configuration.

See also commits with #1037 in ogServer and WebConsole? repo.

  • Property mode set to 100644
File size: 10.9 KB
Line 
1#
2# Copyright (C) 2020-2021 Soleta Networks <info@soleta.eu>
3#
4# This program is free software: you can redistribute it and/or modify it under
5# the terms of the GNU Affero General Public License as published by the
6# Free Software Foundation; either version 3 of the License, or
7# (at your option) any later version.
8
9import os
10import json
11import subprocess
12import fcntl, socket, array, struct
13from src.ogClient import ogClient
14from src.ogRest import ThreadState
15
16OG_SHELL = '/bin/bash'
17
18class OgLiveOperations:
19    def __init__(self, config):
20        self._url = config['opengnsys']['url']
21        self._url_log = config['opengnsys']['url_log']
22
23    def _restartBrowser(self, url):
24        try:
25            proc = subprocess.call(["pkill", "-9", "browser"])
26            proc = subprocess.Popen(["browser", "-qws", url])
27        except:
28            raise ValueError('Error: cannot restart browser')
29
30    def parseGetConf(self, out):
31        parsed = {'serial_number': '',
32              'disk_setup': list(),
33              'partition_setup': list()}
34        configs = out.split('\n')
35        for line in configs[:-1]:
36            if 'ser=' in line:
37                parsed['serial_number'] = line.partition('ser=')[2]
38            else:
39                part_setup = {}
40                params = dict(param.split('=') for param in line.split('\t'))
41                # Parse partition configuration.
42                part_setup['disk'] = params['disk']
43                part_setup['disk_type'] = params.get('dtype', '')
44                part_setup['partition'] = params['par']
45                part_setup['code'] = params['cpt']
46                part_setup['filesystem'] = params['fsi']
47                part_setup['os'] = params['soi']
48                part_setup['size'] = params['tam']
49                part_setup['used_size'] = params['uso']
50                if part_setup['partition'] == '0':
51                    parsed['disk_setup'].append(part_setup)
52                else:
53                    parsed['partition_setup'].append(part_setup)
54        return parsed
55
56    def poweroff(self):
57        if os.path.exists('/scripts/oginit'):
58            cmd = f'source {ogClient.OG_PATH}etc/preinit/loadenviron.sh; ' \
59                  f'{ogClient.OG_PATH}scripts/poweroff'
60            subprocess.call([cmd], shell=True, executable=OG_SHELL)
61        else:
62            subprocess.call(['/sbin/poweroff'])
63
64    def reboot(self):
65        if os.path.exists('/scripts/oginit'):
66            cmd = f'source {ogClient.OG_PATH}etc/preinit/loadenviron.sh; ' \
67                  f'{ogClient.OG_PATH}scripts/reboot'
68            subprocess.call([cmd], shell=True, executable=OG_SHELL)
69        else:
70            subprocess.call(['/sbin/reboot'])
71
72    def shellrun(self, request, ogRest):
73        cmd = request.getrun()
74        cmds = cmd.split(";|\n\r")
75
76        self._restartBrowser(self._url_log)
77
78        try:
79            ogRest.proc = subprocess.Popen(cmds,
80                               stdout=subprocess.PIPE,
81                               shell=True,
82                               executable=OG_SHELL)
83            (output, error) = ogRest.proc.communicate()
84        except:
85            raise ValueError('Error: Incorrect command value')
86
87        cmd_get_conf = f'{ogClient.OG_PATH}interfaceAdm/getConfiguration'
88        result = subprocess.check_output([cmd_get_conf], shell=True)
89        self._restartBrowser(self._url)
90
91        return output.decode('utf-8')
92
93    def session(self, request, ogRest):
94        disk = request.getDisk()
95        partition = request.getPartition()
96        cmd = f'{ogClient.OG_PATH}interfaceAdm/IniciarSesion {disk} {partition}'
97
98        try:
99            ogRest.proc = subprocess.Popen([cmd],
100                               stdout=subprocess.PIPE,
101                               shell=True,
102                               executable=OG_SHELL)
103            (output, error) = ogRest.proc.communicate()
104        except:
105            raise ValueError('Error: Incorrect command value')
106
107        return output.decode('utf-8')
108
109    def software(self, request, path, ogRest):
110        disk = request.getDisk()
111        partition = request.getPartition()
112
113        self._restartBrowser(self._url_log)
114
115        try:
116            cmd = f'{ogClient.OG_PATH}interfaceAdm/InventarioSoftware {disk} ' \
117                  f'{partition} {path}'
118
119            ogRest.proc = subprocess.Popen([cmd],
120                               stdout=subprocess.PIPE,
121                               shell=True,
122                               executable=OG_SHELL)
123            (output, error) = ogRest.proc.communicate()
124        except:
125            raise ValueError('Error: Incorrect command value')
126
127        self._restartBrowser(self._url)
128
129        software = ''
130        with open(path, 'r') as f:
131            software = f.read()
132        return software
133
134    def hardware(self, path, ogRest):
135        self._restartBrowser(self._url_log)
136
137        try:
138            cmd = f'{ogClient.OG_PATH}interfaceAdm/InventarioHardware {path}'
139            ogRest.proc = subprocess.Popen([cmd],
140                               stdout=subprocess.PIPE,
141                               shell=True,
142                               executable=OG_SHELL)
143            (output, error) = ogRest.proc.communicate()
144        except:
145            raise ValueError('Error: Incorrect command value')
146
147        self._restartBrowser(self._url)
148
149        return output.decode('utf-8')
150
151    def setup(self, request, ogRest):
152        table_type = request.getType()
153        disk = request.getDisk()
154        cache = request.getCache()
155        cache_size = request.getCacheSize()
156        partlist = request.getPartitionSetup()
157        cfg = f'dis={disk}*che={cache}*tch={cache_size}!'
158
159        for part in partlist:
160            cfg += f'par={part["partition"]}*cpt={part["code"]}*' \
161                   f'sfi={part["filesystem"]}*tam={part["size"]}*' \
162                   f'ope={part["format"]}%'
163
164            if ogRest.terminated:
165                break
166
167        cmd = f'{ogClient.OG_PATH}interfaceAdm/Configurar {table_type} {cfg}'
168        try:
169            ogRest.proc = subprocess.Popen([cmd],
170                               stdout=subprocess.PIPE,
171                               shell=True,
172                               executable=OG_SHELL)
173            (output, error) = ogRest.proc.communicate()
174        except:
175            raise ValueError('Error: Incorrect command value')
176
177        cmd_get_conf = f'{ogClient.OG_PATH}interfaceAdm/getConfiguration'
178        result = subprocess.check_output([cmd_get_conf], shell=True)
179        self._restartBrowser(self._url)
180
181        return self.parseGetConf(result.decode('utf-8'))
182
183    def image_restore(self, request, ogRest):
184        disk = request.getDisk()
185        partition = request.getPartition()
186        name = request.getName()
187        repo = request.getRepo()
188        ctype = request.getType()
189        profile = request.getProfile()
190        cid = request.getId()
191        cmd = f'{ogClient.OG_PATH}interfaceAdm/RestaurarImagen {disk} {partition} ' \
192              f'{name} {repo} {ctype}'
193
194        self._restartBrowser(self._url_log)
195
196        try:
197            ogRest.proc = subprocess.Popen([cmd],
198                               stdout=subprocess.PIPE,
199                               shell=True,
200                               executable=OG_SHELL)
201            (output, error) = ogRest.proc.communicate()
202            if (ogRest.proc.returncode):
203                raise Exception
204        except:
205            raise ValueError('Error: Incorrect command value')
206
207        cmd_get_conf = f'{ogClient.OG_PATH}interfaceAdm/getConfiguration'
208        result = subprocess.check_output([cmd_get_conf], shell=True)
209        self._restartBrowser(self._url)
210
211        return output.decode('utf-8')
212
213    def image_create(self, path, request, ogRest):
214        disk = request.getDisk()
215        partition = request.getPartition()
216        name = request.getName()
217        repo = request.getRepo()
218        cmd_software = f'{ogClient.OG_PATH}interfaceAdm/InventarioSoftware {disk} ' \
219                   f'{partition} {path}'
220        cmd_create_image = f'{ogClient.OG_PATH}interfaceAdm/CrearImagen {disk} ' \
221                   f'{partition} {name} {repo}'
222
223        self._restartBrowser(self._url_log)
224
225        try:
226            ogRest.proc = subprocess.Popen([cmd_software],
227                               stdout=subprocess.PIPE,
228                               shell=True,
229                               executable=OG_SHELL)
230            (output, error) = ogRest.proc.communicate()
231        except:
232            raise ValueError('Error: Incorrect command value')
233
234        if ogRest.terminated:
235            return
236
237        try:
238            ogRest.proc = subprocess.Popen([cmd_create_image],
239                               stdout=subprocess.PIPE,
240                               shell=True,
241                               executable=OG_SHELL)
242            ogRest.proc.communicate()
243        except:
244            raise ValueError('Error: Incorrect command value')
245
246        if ogRest.proc.returncode != 0:
247            raise ValueError('Error: Image creation failed')
248
249        with open('/tmp/image.info') as file_info:
250            line = file_info.readline().rstrip()
251
252        image_info = {}
253
254        (image_info['clonator'],
255         image_info['compressor'],
256         image_info['filesystem'],
257         image_info['datasize'],
258         image_info['clientname']) = line.split(':', 5)
259
260        os.remove('/tmp/image.info')
261
262        self._restartBrowser(self._url)
263
264        return image_info
265
266    def refresh(self, ogRest):
267        self._restartBrowser(self._url_log)
268
269        try:
270            cmd = f'{ogClient.OG_PATH}interfaceAdm/getConfiguration'
271            ogRest.proc = subprocess.Popen([cmd],
272                               stdout=subprocess.PIPE,
273                               shell=True,
274                               executable=OG_SHELL)
275            (output, error) = ogRest.proc.communicate()
276        except:
277            raise ValueError('Error: Incorrect command value')
278
279        self._restartBrowser(self._url)
280
281        return self.parseGetConf(output.decode('utf-8'))
282
283    def probe(self, ogRest):
284        def ethtool(interface):
285            try:
286                ETHTOOL_GSET = 0x00000001
287                SIOCETHTOOL = 0x8946
288                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
289                sockfd = sock.fileno()
290                ecmd = array.array(
291                        "B", struct.pack("I39s", ETHTOOL_GSET, b"\x00" * 39)
292                       )
293                interface = interface.encode("utf-8")
294                ifreq = struct.pack("16sP", interface, ecmd.buffer_info()[0])
295                fcntl.ioctl(sockfd, SIOCETHTOOL, ifreq)
296                res = ecmd.tobytes()
297                speed = struct.unpack("12xH29x", res)[0]
298            except IOError:
299                speed = 0
300            finally:
301                sock.close()
302            return speed
303
304        interface = os.environ['DEVICE']
305        speed = ethtool(interface)
306
307        return {'status': 'OPG' if ogRest.state != ThreadState.BUSY else 'BSY',
308                'speed': speed}
Note: See TracBrowser for help on using the repository browser.