| 1 | # |
|---|
| 2 | # Copyright (C) 2020 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, version 3. |
|---|
| 7 | # |
|---|
| 8 | |
|---|
| 9 | import os |
|---|
| 10 | import json |
|---|
| 11 | import subprocess |
|---|
| 12 | from src.ogClient import ogClient |
|---|
| 13 | |
|---|
| 14 | OG_SHELL = '/bin/bash' |
|---|
| 15 | |
|---|
| 16 | class OgLinuxOperations: |
|---|
| 17 | def __init__(self, config): |
|---|
| 18 | self._url = config['opengnsys']['url'] |
|---|
| 19 | self._url_log = config['opengnsys']['url_log'] |
|---|
| 20 | |
|---|
| 21 | def _restartBrowser(self, url): |
|---|
| 22 | try: |
|---|
| 23 | proc = subprocess.call(["pkill", "-9", "browser"]) |
|---|
| 24 | proc = subprocess.Popen(["browser", "-qws", url]) |
|---|
| 25 | except: |
|---|
| 26 | raise ValueError('Error: cannot restart browser') |
|---|
| 27 | |
|---|
| 28 | def parseGetConf(self, out): |
|---|
| 29 | parsed = {'serial_number': '', |
|---|
| 30 | 'disk_setup': list(), |
|---|
| 31 | 'partition_setup': list()} |
|---|
| 32 | configs = out.split('\n') |
|---|
| 33 | for line in configs[:-1]: |
|---|
| 34 | if 'ser=' in line: |
|---|
| 35 | parsed['serial_number'] = line.partition('ser=')[2] |
|---|
| 36 | else: |
|---|
| 37 | part_setup = {} |
|---|
| 38 | params = dict(param.split('=') for param in line.split('\t')) |
|---|
| 39 | # Parse partition configuration. |
|---|
| 40 | part_setup['disk'] = params['disk'] |
|---|
| 41 | part_setup['partition'] = params['par'] |
|---|
| 42 | part_setup['code'] = params['cpt'] |
|---|
| 43 | part_setup['filesystem'] = params['fsi'] |
|---|
| 44 | part_setup['os'] = params['soi'] |
|---|
| 45 | part_setup['size'] = params['tam'] |
|---|
| 46 | part_setup['used_size'] = params['uso'] |
|---|
| 47 | if part_setup['partition'] == '0': |
|---|
| 48 | parsed['disk_setup'].append(part_setup) |
|---|
| 49 | else: |
|---|
| 50 | parsed['partition_setup'].append(part_setup) |
|---|
| 51 | return parsed |
|---|
| 52 | |
|---|
| 53 | def poweroff(self): |
|---|
| 54 | if os.path.exists('/scripts/oginit'): |
|---|
| 55 | cmd = f'source {ogClient.OG_PATH}etc/preinit/loadenviron.sh; ' \ |
|---|
| 56 | f'{ogClient.OG_PATH}scripts/poweroff' |
|---|
| 57 | subprocess.call([cmd], shell=True, executable=OG_SHELL) |
|---|
| 58 | else: |
|---|
| 59 | subprocess.call(['/sbin/poweroff']) |
|---|
| 60 | |
|---|
| 61 | def reboot(self): |
|---|
| 62 | if os.path.exists('/scripts/oginit'): |
|---|
| 63 | cmd = f'source {ogClient.OG_PATH}etc/preinit/loadenviron.sh; ' \ |
|---|
| 64 | f'{ogClient.OG_PATH}scripts/reboot' |
|---|
| 65 | subprocess.call([cmd], shell=True, executable=OG_SHELL) |
|---|
| 66 | else: |
|---|
| 67 | subprocess.call(['/sbin/reboot']) |
|---|
| 68 | |
|---|
| 69 | def shellrun(self, request, ogRest): |
|---|
| 70 | cmd = request.getrun() |
|---|
| 71 | cmds = cmd.split(";|\n\r") |
|---|
| 72 | |
|---|
| 73 | self._restartBrowser(self._url_log) |
|---|
| 74 | |
|---|
| 75 | try: |
|---|
| 76 | ogRest.proc = subprocess.Popen(cmds, |
|---|
| 77 | stdout=subprocess.PIPE, |
|---|
| 78 | shell=True, |
|---|
| 79 | executable=OG_SHELL) |
|---|
| 80 | (output, error) = ogRest.proc.communicate() |
|---|
| 81 | except: |
|---|
| 82 | raise ValueError('Error: Incorrect command value') |
|---|
| 83 | |
|---|
| 84 | cmd_get_conf = f'{ogClient.OG_PATH}interfaceAdm/getConfiguration' |
|---|
| 85 | result = subprocess.check_output([cmd_get_conf], shell=True) |
|---|
| 86 | self._restartBrowser(self._url) |
|---|
| 87 | |
|---|
| 88 | return output.decode('utf-8') |
|---|
| 89 | |
|---|
| 90 | def session(self, request, ogRest): |
|---|
| 91 | disk = request.getDisk() |
|---|
| 92 | partition = request.getPartition() |
|---|
| 93 | cmd = f'{ogClient.OG_PATH}interfaceAdm/IniciarSesion {disk} {partition}' |
|---|
| 94 | |
|---|
| 95 | try: |
|---|
| 96 | ogRest.proc = subprocess.Popen([cmd], |
|---|
| 97 | stdout=subprocess.PIPE, |
|---|
| 98 | shell=True, |
|---|
| 99 | executable=OG_SHELL) |
|---|
| 100 | (output, error) = ogRest.proc.communicate() |
|---|
| 101 | except: |
|---|
| 102 | raise ValueError('Error: Incorrect command value') |
|---|
| 103 | |
|---|
| 104 | return output.decode('utf-8') |
|---|
| 105 | |
|---|
| 106 | def software(self, request, path, ogRest): |
|---|
| 107 | disk = request.getDisk() |
|---|
| 108 | partition = request.getPartition() |
|---|
| 109 | |
|---|
| 110 | self._restartBrowser(self._url_log) |
|---|
| 111 | |
|---|
| 112 | try: |
|---|
| 113 | cmd = f'{ogClient.OG_PATH}interfaceAdm/InventarioSoftware {disk} ' \ |
|---|
| 114 | f'{partition} {path}' |
|---|
| 115 | |
|---|
| 116 | ogRest.proc = subprocess.Popen([cmd], |
|---|
| 117 | stdout=subprocess.PIPE, |
|---|
| 118 | shell=True, |
|---|
| 119 | executable=OG_SHELL) |
|---|
| 120 | (output, error) = ogRest.proc.communicate() |
|---|
| 121 | except: |
|---|
| 122 | raise ValueError('Error: Incorrect command value') |
|---|
| 123 | |
|---|
| 124 | self._restartBrowser(self._url) |
|---|
| 125 | |
|---|
| 126 | software = '' |
|---|
| 127 | with open(path, 'r') as f: |
|---|
| 128 | software = f.read() |
|---|
| 129 | return software |
|---|
| 130 | |
|---|
| 131 | def hardware(self, path, ogRest): |
|---|
| 132 | self._restartBrowser(self._url_log) |
|---|
| 133 | |
|---|
| 134 | try: |
|---|
| 135 | cmd = f'{ogClient.OG_PATH}interfaceAdm/InventarioHardware {path}' |
|---|
| 136 | ogRest.proc = subprocess.Popen([cmd], |
|---|
| 137 | stdout=subprocess.PIPE, |
|---|
| 138 | shell=True, |
|---|
| 139 | executable=OG_SHELL) |
|---|
| 140 | (output, error) = ogRest.proc.communicate() |
|---|
| 141 | except: |
|---|
| 142 | raise ValueError('Error: Incorrect command value') |
|---|
| 143 | |
|---|
| 144 | self._restartBrowser(self._url) |
|---|
| 145 | |
|---|
| 146 | return output.decode('utf-8') |
|---|
| 147 | |
|---|
| 148 | def setup(self, request, ogRest): |
|---|
| 149 | table_type = request.getType() |
|---|
| 150 | disk = request.getDisk() |
|---|
| 151 | cache = request.getCache() |
|---|
| 152 | cache_size = request.getCacheSize() |
|---|
| 153 | partlist = request.getPartitionSetup() |
|---|
| 154 | cfg = f'dis={disk}*che={cache}*tch={cache_size}!' |
|---|
| 155 | |
|---|
| 156 | for part in partlist: |
|---|
| 157 | cfg += f'par={part["partition"]}*cpt={part["code"]}*' \ |
|---|
| 158 | f'sfi={part["filesystem"]}*tam={part["size"]}*' \ |
|---|
| 159 | f'ope={part["format"]}%' |
|---|
| 160 | |
|---|
| 161 | if ogRest.terminated: |
|---|
| 162 | break |
|---|
| 163 | |
|---|
| 164 | cmd = f'{ogClient.OG_PATH}interfaceAdm/Configurar {table_type} {cfg}' |
|---|
| 165 | try: |
|---|
| 166 | ogRest.proc = subprocess.Popen([cmd], |
|---|
| 167 | stdout=subprocess.PIPE, |
|---|
| 168 | shell=True, |
|---|
| 169 | executable=OG_SHELL) |
|---|
| 170 | (output, error) = ogRest.proc.communicate() |
|---|
| 171 | except: |
|---|
| 172 | raise ValueError('Error: Incorrect command value') |
|---|
| 173 | |
|---|
| 174 | cmd_get_conf = f'{ogClient.OG_PATH}interfaceAdm/getConfiguration' |
|---|
| 175 | result = subprocess.check_output([cmd_get_conf], shell=True) |
|---|
| 176 | self._restartBrowser(self._url) |
|---|
| 177 | |
|---|
| 178 | return self.parseGetConf(result.decode('utf-8')) |
|---|
| 179 | |
|---|
| 180 | def image_restore(self, request, ogRest): |
|---|
| 181 | disk = request.getDisk() |
|---|
| 182 | partition = request.getPartition() |
|---|
| 183 | name = request.getName() |
|---|
| 184 | repo = request.getRepo() |
|---|
| 185 | ctype = request.getType() |
|---|
| 186 | profile = request.getProfile() |
|---|
| 187 | cid = request.getId() |
|---|
| 188 | cmd = f'{ogClient.OG_PATH}interfaceAdm/RestaurarImagen {disk} {partition} ' \ |
|---|
| 189 | f'{name} {repo} {ctype}' |
|---|
| 190 | |
|---|
| 191 | self._restartBrowser(self._url_log) |
|---|
| 192 | |
|---|
| 193 | try: |
|---|
| 194 | ogRest.proc = subprocess.Popen([cmd], |
|---|
| 195 | stdout=subprocess.PIPE, |
|---|
| 196 | shell=True, |
|---|
| 197 | executable=OG_SHELL) |
|---|
| 198 | (output, error) = ogRest.proc.communicate() |
|---|
| 199 | if (ogRest.proc.returncode): |
|---|
| 200 | raise Exception |
|---|
| 201 | except: |
|---|
| 202 | raise ValueError('Error: Incorrect command value') |
|---|
| 203 | |
|---|
| 204 | cmd_get_conf = f'{ogClient.OG_PATH}interfaceAdm/getConfiguration' |
|---|
| 205 | result = subprocess.check_output([cmd_get_conf], shell=True) |
|---|
| 206 | self._restartBrowser(self._url) |
|---|
| 207 | |
|---|
| 208 | return output.decode('utf-8') |
|---|
| 209 | |
|---|
| 210 | def image_create(self, path, request, ogRest): |
|---|
| 211 | disk = request.getDisk() |
|---|
| 212 | partition = request.getPartition() |
|---|
| 213 | name = request.getName() |
|---|
| 214 | repo = request.getRepo() |
|---|
| 215 | cmd_software = f'{ogClient.OG_PATH}interfaceAdm/InventarioSoftware {disk} ' \ |
|---|
| 216 | f'{partition} {path}' |
|---|
| 217 | cmd_create_image = f'{ogClient.OG_PATH}interfaceAdm/CrearImagen {disk} ' \ |
|---|
| 218 | f'{partition} {name} {repo}' |
|---|
| 219 | |
|---|
| 220 | self._restartBrowser(self._url_log) |
|---|
| 221 | |
|---|
| 222 | try: |
|---|
| 223 | ogRest.proc = subprocess.Popen([cmd_software], |
|---|
| 224 | stdout=subprocess.PIPE, |
|---|
| 225 | shell=True, |
|---|
| 226 | executable=OG_SHELL) |
|---|
| 227 | (output, error) = ogRest.proc.communicate() |
|---|
| 228 | except: |
|---|
| 229 | raise ValueError('Error: Incorrect command value') |
|---|
| 230 | |
|---|
| 231 | if ogRest.terminated: |
|---|
| 232 | return |
|---|
| 233 | |
|---|
| 234 | try: |
|---|
| 235 | ogRest.proc = subprocess.Popen([cmd_create_image], |
|---|
| 236 | stdout=subprocess.PIPE, |
|---|
| 237 | shell=True, |
|---|
| 238 | executable=OG_SHELL) |
|---|
| 239 | ogRest.proc.communicate() |
|---|
| 240 | except: |
|---|
| 241 | raise ValueError('Error: Incorrect command value') |
|---|
| 242 | |
|---|
| 243 | with open('/tmp/image.info') as file_info: |
|---|
| 244 | line = file_info.readline().rstrip() |
|---|
| 245 | |
|---|
| 246 | image_info = {} |
|---|
| 247 | |
|---|
| 248 | (image_info['clonator'], |
|---|
| 249 | image_info['compressor'], |
|---|
| 250 | image_info['filesystem'], |
|---|
| 251 | image_info['datasize'], |
|---|
| 252 | image_info['clientname']) = line.split(':', 5) |
|---|
| 253 | |
|---|
| 254 | os.remove('/tmp/image.info') |
|---|
| 255 | |
|---|
| 256 | self._restartBrowser(self._url) |
|---|
| 257 | |
|---|
| 258 | return image_info |
|---|
| 259 | |
|---|
| 260 | def refresh(self, ogRest): |
|---|
| 261 | self._restartBrowser(self._url_log) |
|---|
| 262 | |
|---|
| 263 | try: |
|---|
| 264 | cmd = f'{ogClient.OG_PATH}interfaceAdm/getConfiguration' |
|---|
| 265 | ogRest.proc = subprocess.Popen([cmd], |
|---|
| 266 | stdout=subprocess.PIPE, |
|---|
| 267 | shell=True, |
|---|
| 268 | executable=OG_SHELL) |
|---|
| 269 | (output, error) = ogRest.proc.communicate() |
|---|
| 270 | except: |
|---|
| 271 | raise ValueError('Error: Incorrect command value') |
|---|
| 272 | |
|---|
| 273 | self._restartBrowser(self._url) |
|---|
| 274 | |
|---|
| 275 | return self.parseGetConf(output.decode('utf-8')) |
|---|