diff options
author | Alejandro Sirgo Rica <asirgo@soleta.eu> | 2024-05-27 16:08:22 +0200 |
---|---|---|
committer | Alejandro Sirgo Rica <asirgo@soleta.eu> | 2024-05-30 17:22:23 +0200 |
commit | 34007857f6b96eca02c510a8a4d8fce6d37fa8df (patch) | |
tree | f46d720719a4076c07168cbcf67f6742b5aaacb2 /src/utils/legacy.py | |
parent | 9a5e83ea1abfd8e22d8531d343ffd2c85d95b351 (diff) |
src: rename legacy.py into image.py
legacy.py contais mostly functions related to system images.
Rename the file to better represent the contents in it.
Diffstat (limited to 'src/utils/legacy.py')
-rw-r--r-- | src/utils/legacy.py | 246 |
1 files changed, 0 insertions, 246 deletions
diff --git a/src/utils/legacy.py b/src/utils/legacy.py deleted file mode 100644 index cdc79c9..0000000 --- a/src/utils/legacy.py +++ /dev/null @@ -1,246 +0,0 @@ -# -# Copyright (C) 2023 Soleta Networks <info@soleta.eu> -# -# This program is free software: you can redistribute it and/or modify it under -# the terms of the GNU Affero General Public License as published by the -# Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. - -import ipaddress -import logging -import os -import subprocess -import shlex -import shutil - -from subprocess import PIPE, DEVNULL, STDOUT, CalledProcessError - -from src.utils.fs import umount -from src.log import OgError - - -class ImageInfo: - """ - Class that stores the OpenGnsys partition image information. - """ - def __init__(self, filesystem=None, datasize=None): - self.filesystem = filesystem - self.datasize = datasize - self.size = 0 - self.mtime = 0 - self.perms = 0 - self.clonator = 'PARTCLONE' - self.compressor = 'LZOP' - - -def human_to_kb(size, unit): - """ - Returns the KB conversion of a human readable string size and unit. - """ - size = float(size.replace(',', '.')) - if unit == 'GB': - return size * 1000000 - if unit == 'MB': - return size * 1000 - return 0 - - -def fill_imageinfo(line, image_info): - """ - Updates ImageInfo object with information processed from - a single partclone.info output line. - - ImageInfo object may not be updated if the line is invalid or does not - contain filesystem or device size information. - """ - if 'File system' in line: - filesystem = line.rstrip().split(' ')[-1] - image_info.filesystem = filesystem - elif 'Device size' in line: - l = [word for word in line.rstrip().split(' ') if word][2:4] - device_size = human_to_kb(*l) - image_info.datasize = device_size - - -def image_info_from_partclone(partclone_output): - """ - Return an ImageInfo object from partclone.info output. - """ - image_info = ImageInfo() - for n, line in enumerate(partclone_output.split('\n')): - # Ignore first two lines of partclone.info output - if n < 2: - continue - if image_info.datasize and image_info.filesystem: - break - fill_imageinfo(line, image_info) - - if not image_info.datasize: - raise OgError("Missing device size from partclone.info output") - elif not image_info.filesystem: - raise OgError("Missing filesystem from partclone.info output") - - return image_info - - -def run_lzop_partcloneinfo(image_path): - """ - Run lzop to decompress an OpenGnsys partition image, feed - lzop output to a partclone.info subprocess. - - Return the partclone.info subprocess output. - """ - cmd1 = f'{shutil.which("lzop")} -dc {image_path}' - cmd2 = f'{shutil.which("partclone.info")} -s -' - args1 = shlex.split(cmd1) - args2 = shlex.split(cmd2) - p1 = subprocess.Popen(args1, stdout=PIPE, stderr=DEVNULL) - p2 = subprocess.Popen(args2, stdout=PIPE, stdin=p1.stdout, - stderr=STDOUT, encoding='utf-8') - p1.stdout.close() - p2_out, p2_err = p2.communicate() - - if p2.returncode != 0: - raise OgError(f'Unable to process image {image_path}') - - return p2_out - - -def ogGetImageInfo(image_path): - """ - Obtain filesystem and device size information of an OpenGnsys partition - image. - - This method supports compressed images with lzop that have been created - with partclone. - - Returns an ImageInfo object. - - >>> image_info = ogGetImageInfo('/opt/opengnsys/images/foobar.img') - >>> image_info.filesystem - >>> 'NTFS' - >>> image_info.datasize - >>> 140000000 - >>> image_info.compressor - >>> 'LZOP' - >>> image_info.clonator - >>> 'PARTCLONE' - """ - partclone_output = run_lzop_partcloneinfo(image_path) - image_info = image_info_from_partclone(partclone_output) - return image_info - - -def change_access(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 0 if exit-code was 0. Return -1 otherwise. - """ - assert mode in ['rw', 'ro'], '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 0 if p.returncode == 0 else -1 - -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 OgError(f'Invalid IP address {ip} received') from e - - 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) - - err = 0 - cmd = f'mount.cifs -o {mode},username={smb_user},password={smb_pass} {new_name} /opt/opengnsys/images' - result = subprocess.run(shlex.split(cmd)) - if result.returncode != 0: - err = -1 - logging.error(f'Error mounting {new_name} in /opt/opengnsys/images with error {result.returncode}') - - cmd = f'mount.cifs -o {mode},username={smb_user},password={smb_pass} {orig_name} /opt/opengnsys/images' - subprocess.run(shlex.split(cmd)) - - return err - - -def restoreImageCustom(repo_ip, image_name, disk, partition, method): - """ - """ - if not shutil.which('restoreImageCustom'): - raise OgError('restoreImageCustom not found') - - 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, - check=True) - except OSError as e: - raise OgError(f'Error processing restoreImageCustom: {e}') from e - 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, - check=True) - out = proc.stdout - except OSError as e: - raise OgError(f'Error processing configureOsCustom: {e}') from e - - return out |