summaryrefslogtreecommitdiffstats
path: root/src/utils/legacy.py
diff options
context:
space:
mode:
authorAlejandro Sirgo Rica <asirgo@soleta.eu>2024-05-27 16:08:22 +0200
committerAlejandro Sirgo Rica <asirgo@soleta.eu>2024-05-30 17:22:23 +0200
commit34007857f6b96eca02c510a8a4d8fce6d37fa8df (patch)
treef46d720719a4076c07168cbcf67f6742b5aaacb2 /src/utils/legacy.py
parent9a5e83ea1abfd8e22d8531d343ffd2c85d95b351 (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.py246
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