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

Last change on this file since cc0d987 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
RevLine 
[05b1088]1#
[cb9edc8]2# Copyright (C) 2020-2021 Soleta Networks <info@soleta.eu>
[05b1088]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
[cb9edc8]6# Free Software Foundation; either version 3 of the License, or
7# (at your option) any later version.
[05b1088]8
[62a8ca4]9import os
[621fb7a]10import json
[62a8ca4]11import subprocess
[bd98dd1]12import fcntl, socket, array, struct
[d7b7b0b]13from src.ogClient import ogClient
[bd98dd1]14from src.ogRest import ThreadState
[62a8ca4]15
[54c0ebf]16OG_SHELL = '/bin/bash'
[2997952]17
[f0aa3df]18class OgLiveOperations:
[621fb7a]19    def __init__(self, config):
[147c890]20        self._url = config['opengnsys']['url']
21        self._url_log = config['opengnsys']['url_log']
[f0c550e]22
[0807ec7]23    def _restartBrowser(self, url):
[f0c550e]24        try:
25            proc = subprocess.call(["pkill", "-9", "browser"])
[0807ec7]26            proc = subprocess.Popen(["browser", "-qws", url])
[f0c550e]27        except:
28            raise ValueError('Error: cannot restart browser')
29
[99ae598]30    def parseGetConf(self, out):
31        parsed = {'serial_number': '',
[91f034e]32              'disk_setup': list(),
[99ae598]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']
[b5c3f58]43                part_setup['disk_type'] = params.get('dtype', '')
[99ae598]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':
[91f034e]51                    parsed['disk_setup'].append(part_setup)
[99ae598]52                else:
53                    parsed['partition_setup'].append(part_setup)
54        return parsed
55
56    def poweroff(self):
57        if os.path.exists('/scripts/oginit'):
[d7b7b0b]58            cmd = f'source {ogClient.OG_PATH}etc/preinit/loadenviron.sh; ' \
59                  f'{ogClient.OG_PATH}scripts/poweroff'
[99ae598]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'):
[d7b7b0b]66            cmd = f'source {ogClient.OG_PATH}etc/preinit/loadenviron.sh; ' \
67                  f'{ogClient.OG_PATH}scripts/reboot'
[99ae598]68            subprocess.call([cmd], shell=True, executable=OG_SHELL)
69        else:
70            subprocess.call(['/sbin/reboot'])
71
[32b73c5]72    def shellrun(self, request, ogRest):
[99ae598]73        cmd = request.getrun()
74        cmds = cmd.split(";|\n\r")
[0807ec7]75
[147c890]76        self._restartBrowser(self._url_log)
[0807ec7]77
[99ae598]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
[d7b7b0b]87        cmd_get_conf = f'{ogClient.OG_PATH}interfaceAdm/getConfiguration'
[eec50f7]88        result = subprocess.check_output([cmd_get_conf], shell=True)
[147c890]89        self._restartBrowser(self._url)
[f0c550e]90
[99ae598]91        return output.decode('utf-8')
92
93    def session(self, request, ogRest):
94        disk = request.getDisk()
95        partition = request.getPartition()
[d7b7b0b]96        cmd = f'{ogClient.OG_PATH}interfaceAdm/IniciarSesion {disk} {partition}'
[99ae598]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
[147c890]113        self._restartBrowser(self._url_log)
[0807ec7]114
[99ae598]115        try:
[d7b7b0b]116            cmd = f'{ogClient.OG_PATH}interfaceAdm/InventarioSoftware {disk} ' \
[99ae598]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
[147c890]127        self._restartBrowser(self._url)
[0807ec7]128
[2e3d47b]129        software = ''
130        with open(path, 'r') as f:
131            software = f.read()
132        return software
[99ae598]133
134    def hardware(self, path, ogRest):
[147c890]135        self._restartBrowser(self._url_log)
[0807ec7]136
[99ae598]137        try:
[d7b7b0b]138            cmd = f'{ogClient.OG_PATH}interfaceAdm/InventarioHardware {path}'
[99ae598]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
[147c890]147        self._restartBrowser(self._url)
[0807ec7]148
[99ae598]149        return output.decode('utf-8')
150
151    def setup(self, request, ogRest):
[a11224d]152        table_type = request.getType()
[99ae598]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
[a11224d]167        cmd = f'{ogClient.OG_PATH}interfaceAdm/Configurar {table_type} {cfg}'
[99ae598]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
[d7b7b0b]177        cmd_get_conf = f'{ogClient.OG_PATH}interfaceAdm/getConfiguration'
[99ae598]178        result = subprocess.check_output([cmd_get_conf], shell=True)
[147c890]179        self._restartBrowser(self._url)
[f0c550e]180
[99ae598]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()
[d7b7b0b]191        cmd = f'{ogClient.OG_PATH}interfaceAdm/RestaurarImagen {disk} {partition} ' \
[99ae598]192              f'{name} {repo} {ctype}'
193
[147c890]194        self._restartBrowser(self._url_log)
[0807ec7]195
[99ae598]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()
[ffbcf7e]202            if (ogRest.proc.returncode):
203                raise Exception
[99ae598]204        except:
205            raise ValueError('Error: Incorrect command value')
206
[d7b7b0b]207        cmd_get_conf = f'{ogClient.OG_PATH}interfaceAdm/getConfiguration'
[eec50f7]208        result = subprocess.check_output([cmd_get_conf], shell=True)
[147c890]209        self._restartBrowser(self._url)
[f0c550e]210
[99ae598]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()
[d7b7b0b]218        cmd_software = f'{ogClient.OG_PATH}interfaceAdm/InventarioSoftware {disk} ' \
[99ae598]219                   f'{partition} {path}'
[d7b7b0b]220        cmd_create_image = f'{ogClient.OG_PATH}interfaceAdm/CrearImagen {disk} ' \
[99ae598]221                   f'{partition} {name} {repo}'
222
[147c890]223        self._restartBrowser(self._url_log)
[0807ec7]224
[99ae598]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
[baa03de]246        if ogRest.proc.returncode != 0:
247            raise ValueError('Error: Image creation failed')
248
[c86eae4]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
[147c890]262        self._restartBrowser(self._url)
[0807ec7]263
[c86eae4]264        return image_info
[99ae598]265
266    def refresh(self, ogRest):
[147c890]267        self._restartBrowser(self._url_log)
[0807ec7]268
[99ae598]269        try:
[d7b7b0b]270            cmd = f'{ogClient.OG_PATH}interfaceAdm/getConfiguration'
[99ae598]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
[147c890]279        self._restartBrowser(self._url)
[f0c550e]280
[99ae598]281        return self.parseGetConf(output.decode('utf-8'))
[bd98dd1]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.