import ipaddress import logging import os import subprocess import shlex import shutil from subprocess import PIPE, DEVNULL, CalledProcessError from src.utils.fs import umount def ogGetImageInfo(path): """ Bash function 'ogGetImageInfo' wrapper (client/engine/Image.lib) """ proc = subprocess.run(f'ogGetImageInfo {path}', stdout=PIPE, shell=True, encoding='utf-8') if proc.stdout.count(':') != 3: return '' image_info = {} (image_info['clonator'], image_info['compressor'], image_info['filesystem'], image_info['datasize']) = proc.stdout.rstrip().split(':', 4) image_info['clientname'] = os.getenv('HOSTNAME') return image_info def cambiar_acceso(mode='rw', user='opengnsys', pwd='og'): """ 'CambiarAcceso' (admin/Interface/CambiarAcceso) rewrite into native Python. Remount the (remote) samba directory that contains the OpenGnsys images. Specify access mode ('rw', or 'ro') with mode parameter (default 'rw'). Specify samba credentials with user and pwd parameter. Return True if exit-code was 0. Return False otherwise. """ if mode not in ['rw', 'ro']: raise ValueError('Invalid remount mode option') cmd = shlex.split(f'mount -o remount,{mode},username={user},password={pwd} /opt/opengnsys/images') p = subprocess.run(cmd, stdout=DEVNULL, stderr=DEVNULL) return p.returncode == 0 def ogChangeRepo(ip, smb_user='opengnsys', smb_pass='og'): """ Umount current Samba directory of OpenGnsys images and mount new Samba directory (preserving previous access mode). If the mount fails, fallback to the image directory that was mounted before calling this function. If there is no previous image directory mount, then simply try mounting the new Samba directory with readonly mode option. Any CalledProcessError raised by the fallback mount subprocess should be handled by the caller of this function. """ def fsopts_mode(fsopts): for opt in fsopts.split(','): if opt in ['rw', 'ro']: return opt def process_mntent(line): name, mntdir, fstype, opts, freq, passno = line.split(' ') mode = fsopts_mode(opts) return name, mntdir, fsopts_mode(opts) try: ipaddr = ipaddress.ip_address(ip) except ValueError as e: raise ValueError('Invalid ip address') mounted = False with open('/etc/mtab') as f: for line in f: if 'ogimages' in line: orig_name, mntdir, mode = process_mntent(line) mounted = True break new_name = f'//{ip}/ogimages' if not mounted: orig_name = new_name mntdir = '/opt/opengnsys/images' mode = 'ro' else: umount(mntdir) cmd = f'mount.cifs -o {mode},username={smb_user},password={smb_pass} {new_name} /opt/opengnsys/images' try: result = subprocess.run(shlex.split(cmd), check=True) except CalledProcessError as e: logging.error(f'Error mounting new image directory: {e}') cmd = f'mount.cifs -o {mode},username={smb_user},password={smb_pass} {orig_name} /opt/opengnsys/images' result = subprocess.run(shlex.split(cmd), check=True) finally: return result def restoreImageCustom(repo_ip, image_name, disk, partition, method): """ """ if not shutil.which('restoreImageCustom'): logging.error('Invalid restoreImageCustom invocation') raise ValueError('Error: restoreImageCustom not found') if ogChangeRepo(repo).returncode != 0: logging.error('ogChangeRepo could not change repository to %s', repo) raise ValueError(f'Error: Cannot change repository to {repo}') cmd = f'restoreImageCustom {repo_ip} {image_name} {disk} {partition} {method}' with open('/tmp/command.log', 'wb', 0) as logfile: try: proc = subprocess.run(cmd, stdout=logfile, encoding='utf-8', shell=True) except: logging.error('Exception when running restoreImageCustom subprocess') raise ValueError('Error: Incorrect command value') return proc.returncode def configureOs(disk, partition): """ """ if shutil.which('configureOsCustom'): cmd_configure = f"configureOsCustom {disk} {partition}" else: cmd_configure = f"configureOs {disk} {partition}" try: proc = subprocess.run(cmd_configure, stdout=PIPE, encoding='utf-8', shell=True) out = proc.stdout except: logging.error('Exception when running configureOs subprocess') raise ValueError('Error: Incorrect command value') return out def ogCopyEfiBootLoader(disk, partition): cmd = f'ogCopyEfiBootLoader {disk} {partition}' try: proc = subprocess.run(cmd, shell=True) except: logging.error('Exception when running ogCopyEfiBootLoader subprocess') raise ValueError('Subprocess error: ogCopyEfiBootloader')