refs #1150 add restoreImage.py
parent
b755de21be
commit
b71e631fb1
|
@ -8,6 +8,7 @@ from pathlib import Path
|
||||||
import ogGlobals
|
import ogGlobals
|
||||||
import SystemLib
|
import SystemLib
|
||||||
import CacheLib
|
import CacheLib
|
||||||
|
import FileSystemLib
|
||||||
|
|
||||||
def parted(*args):
|
def parted(*args):
|
||||||
parted_path = shutil.which("parted")
|
parted_path = shutil.which("parted")
|
||||||
|
@ -707,32 +708,28 @@ def ogGetPartitionId(*args):
|
||||||
print(ID)
|
print(ID)
|
||||||
return
|
return
|
||||||
|
|
||||||
def ogGetPartitionSize(*args):
|
|
||||||
# Variables locales
|
|
||||||
PART = None
|
|
||||||
SIZE = None
|
|
||||||
|
|
||||||
# Si se solicita, mostrar ayuda.
|
#/**
|
||||||
if len(args) == 1 and args[0] == "help":
|
# ogGetPartitionSize int_ndisk int_npartition
|
||||||
SystemLib.ogHelp('ogGetPartitionSize', 'ogGetPartitionSize int_ndisk int_npartition', 'ogGetPartitionSize 1 1 => 10000000')
|
#@brief Muestra el tamano en KB de una particion determinada.
|
||||||
return
|
#@param int_ndisk nº de orden del disco
|
||||||
|
#@param int_npartition nº de orden de la partición
|
||||||
|
#@return int_partsize - Tamaño en KB de la partición.
|
||||||
|
#@exception OG_ERR_FORMAT formato incorrecto.
|
||||||
|
#@exception OG_ERR_NOTFOUND disco o particion no detectado (no es un dispositivo).
|
||||||
|
#@note Requisitos: sfdisk, awk
|
||||||
|
#*/ ##
|
||||||
|
def ogGetPartitionSize (disk, par):
|
||||||
|
PART = ogDiskToDev (disk, par)
|
||||||
|
if PART is None: return
|
||||||
|
|
||||||
# Error si no se reciben 2 parámetros.
|
sz = subprocess.run (['partx', '-gbo', 'SIZE', PART], capture_output=True, text=True).stdout.strip()
|
||||||
if len(args) != 2:
|
if sz: return int (int (sz) / 1024)
|
||||||
SystemLib.ogRaiseError(OG_ERR_FORMAT)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Devolver tamaño de partición, del volumen lógico o del sistema de archivos (para ZFS).
|
sz = subprocess.run (['lvs', '--noheadings', '-o', 'lv_size', '--units', 'k', PART], capture_output=True, text=True).stdout.strip
|
||||||
PART = ogDiskToDev(args[0], args[1])
|
if sz: return int (sz)
|
||||||
if PART is None:
|
|
||||||
return
|
return FileSystemLib.ogGetFsSize (disk, par)
|
||||||
SIZE = subprocess.getoutput(f"partx -gbo SIZE {PART} 2>/dev/null | awk '{{print int($1/1024)}}'")
|
|
||||||
if not SIZE:
|
|
||||||
SIZE = subprocess.getoutput(f"lvs --noheadings -o lv_size --units k {PART} | awk '{{printf \"%d\",$0}}'")
|
|
||||||
if not SIZE:
|
|
||||||
SIZE = ogGetFsSize(args[0], args[1])
|
|
||||||
print(SIZE or 0)
|
|
||||||
return
|
|
||||||
|
|
||||||
def ogGetPartitionsNumber(*args):
|
def ogGetPartitionsNumber(*args):
|
||||||
# Variables locales
|
# Variables locales
|
||||||
|
|
|
@ -6,6 +6,7 @@ import ogGlobals
|
||||||
import SystemLib
|
import SystemLib
|
||||||
import DiskLib
|
import DiskLib
|
||||||
import CacheLib
|
import CacheLib
|
||||||
|
import FileSystemLib
|
||||||
|
|
||||||
def ogCheckFs(int_ndisk, int_nfilesys):
|
def ogCheckFs(int_ndisk, int_nfilesys):
|
||||||
# Si se solicita, mostrar ayuda.
|
# Si se solicita, mostrar ayuda.
|
||||||
|
@ -171,170 +172,144 @@ def ogExtendFs():
|
||||||
ogUnlock(int(sys.argv[1]), int(sys.argv[2]))
|
ogUnlock(int(sys.argv[1]), int(sys.argv[2]))
|
||||||
return ERRCODE
|
return ERRCODE
|
||||||
|
|
||||||
def ogFormat(int_ndisk, int_nfilesys):
|
|
||||||
if int_nfilesys.lower() == "cache":
|
#/**
|
||||||
ogFormatCache()
|
# ogFormat int_ndisk int_nfilesys | CACHE
|
||||||
|
#@see ogFormatFs ogFormatCache
|
||||||
|
#*/ ##
|
||||||
|
|
||||||
|
def ogFormat (disk, par=None, fs=None, label=None):
|
||||||
|
if disk.lower() == "cache":
|
||||||
|
return CacheLib.ogFormatCache()
|
||||||
else:
|
else:
|
||||||
ogFormatFs(int_ndisk, int_nfilesys)
|
return ogFormatFs (disk, par)
|
||||||
|
|
||||||
def ogFormatFs(int_ndisk, int_nfilesys, str_label=None):
|
|
||||||
# Si se solicita, mostrar ayuda.
|
#/**
|
||||||
if str_label == "help":
|
# ogFormatFs int_ndisk int_nfilesys [type_fstype] [str_label]
|
||||||
ogHelp("ogFormatFs", "ogFormatFs int_ndisk int_nfilesys [str_label]", "ogFormatFs 1 1", "ogFormatFs 1 1 EXT4", "ogFormatFs 1 1 \"DATA\"", "ogFormatFs 1 1 EXT4 \"DATA\"")
|
#@brief Formatea un sistema de ficheros según el tipo de su partición.
|
||||||
|
#@param int_ndisk nº de orden del disco
|
||||||
|
#@param int_nfilesys nº de orden del sistema de archivos
|
||||||
|
#@param type_fstype mnemónico de sistema de ficheros a formatear (opcional al reformatear)
|
||||||
|
#@param str_label etiqueta de volumen (opcional)
|
||||||
|
#@return (por determinar)
|
||||||
|
#@exception OG_ERR_FORMAT Formato de ejecución incorrecto.
|
||||||
|
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
|
||||||
|
#@exception OG_ERR_PARTITION Partición no accesible o desconocida.
|
||||||
|
#@note Requisitos: mkfs*
|
||||||
|
#@warning No formatea particiones montadas ni bloqueadas.
|
||||||
|
#@todo Definir salidas.
|
||||||
|
#*/ ##
|
||||||
|
def ogFormatFs (disk, par, type=None, label=None):
|
||||||
|
PART = DiskLib.ogDiskToDev (disk, par)
|
||||||
|
if not PART: return
|
||||||
|
|
||||||
|
if ogIsMounted (disk, par):
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_DONTFORMAT, f'{ogGlobals.lang.MSG_MOUNT}: {disk} {par}')
|
||||||
|
return None
|
||||||
|
if ogIsLocked (disk, par):
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f"{disk} {par}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
if not type:
|
||||||
|
type = ogGetFsType (disk, par)
|
||||||
|
|
||||||
|
if not type:
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f"{disk} {par} ...")
|
||||||
|
return None
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'EXT2': { 'PROG': 'mkfs.ext2', 'PARAMS': '-F' },
|
||||||
|
'EXT3': { 'PROG': 'mkfs.ext3', 'PARAMS': '-F' },
|
||||||
|
'EXT4': { 'PROG': 'mkfs.ext4', 'PARAMS': '-F' },
|
||||||
|
'BTRFS': { 'PROG': 'mkfs.btrfs', 'PARAMS': '-f' },
|
||||||
|
'REISERFS': { 'PROG': 'mkfs.reiserfs', 'PARAMS': '-f', 'LABELPARAM': '-l' },
|
||||||
|
'REISER4': { 'PROG': 'mkfs.reiser4', 'PARAMS': '-f', 'INPUT': 'y\n' },
|
||||||
|
'XFS': { 'PROG': 'mkfs.xfs', 'PARAMS': '-f' },
|
||||||
|
'JFS': { 'PROG': 'mkfs.jfs', 'INPUT': 'y\n' },
|
||||||
|
'F2FS': { 'PROG': 'mkfs.f2fs', 'LABELPARAM': '-l' },
|
||||||
|
'NILFS2': { 'PROG': 'mkfs.nilfs2', 'PARAMS': '-f' },
|
||||||
|
'LINUX-SWAP': { 'PROG': 'mkswap' },
|
||||||
|
'NTFS': { 'PROG': 'mkntfs', 'PARAMS': '-f' },
|
||||||
|
'EXFAT': { 'PROG': 'mkfs.exfat', 'LABELPARAM': '-n' },
|
||||||
|
'FAT32': { 'PROG': 'mkdosfs', 'PARAMS': '-F 32', 'LABELPARAM': '-n' },
|
||||||
|
'FAT16': { 'PROG': 'mkdosfs', 'PARAMS': '-F 16', 'LABELPARAM': '-n' },
|
||||||
|
'FAT12': { 'PROG': 'mkdosfs', 'PARAMS': '-F 12', 'LABELPARAM': '-n' },
|
||||||
|
'HFS': { 'PROG': 'mkfs.hfs' },
|
||||||
|
'HFSPLUS': { 'PROG': 'mkfs.hfsplus', 'LABELPARAM': '-v' },
|
||||||
|
'UFS': { 'PROG': 'mkfs.ufs', 'PARAMS': '-O 2' },
|
||||||
|
}
|
||||||
|
if type not in data:
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk} {par} {type}")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Error si no se reciben entre 2 y 4 parámetros.
|
d = data[type]
|
||||||
if not (2 <= len(sys.argv) <= 4):
|
prog = d['PROG']
|
||||||
ogRaiseError(OG_ERR_FORMAT)
|
params = d['PARAMS'] if 'PARAMS' in d else ''
|
||||||
return
|
labelparam = d['LABELPARAM'] if 'LABELPARAM' in d else ''
|
||||||
|
input = d['INPUT'] if 'INPUT' in d else ''
|
||||||
|
|
||||||
# Obtener fichero de dispositivo.
|
if label == "CACHE":
|
||||||
PART = ogDiskToDev(int_ndisk, int_nfilesys)
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f"{ogGlobals.lang.MSG_RESERVEDVALUE}: CACHE")
|
||||||
if not PART:
|
|
||||||
return
|
return
|
||||||
|
if label:
|
||||||
|
params = f"{params} {labelparam or '-L'} {label}"
|
||||||
|
|
||||||
# Error si la partición está montada o bloqueada.
|
ogLock (disk, par)
|
||||||
if ogIsMounted(int_ndisk, int_nfilesys):
|
subprocess.run (['umount', PART])
|
||||||
ogRaiseError(OG_ERR_DONTFORMAT, f"{MSG_MOUNT}: {int_ndisk} {int_nfilesys}")
|
|
||||||
return
|
|
||||||
if ogIsLocked(int_ndisk, int_nfilesys):
|
|
||||||
ogRaiseError(OG_ERR_LOCKED, f"{int_ndisk} {int_nfilesys}")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Si no se indica el tipo de sistema de archivos, intentar obtenerlo.
|
|
||||||
TYPE = ogGetFsType(int_ndisk, int_nfilesys)
|
|
||||||
if not TYPE:
|
|
||||||
TYPE = sys.argv[3]
|
|
||||||
|
|
||||||
# Error, si no especifica el tipo de sistema de archivos a formatear.
|
|
||||||
if not TYPE:
|
|
||||||
ogRaiseError(OG_ERR_FORMAT, f"{int_ndisk} {int_nfilesys} ...")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Elegir tipo de formato.
|
|
||||||
if TYPE == "EXT2":
|
|
||||||
PROG = "mkfs.ext2"
|
|
||||||
PARAMS = "-F"
|
|
||||||
elif TYPE == "EXT3":
|
|
||||||
PROG = "mkfs.ext3"
|
|
||||||
PARAMS = "-F"
|
|
||||||
elif TYPE == "EXT4":
|
|
||||||
PROG = "mkfs.ext4"
|
|
||||||
PARAMS = "-F"
|
|
||||||
elif TYPE == "BTRFS":
|
|
||||||
PROG = "mkfs.btrfs"
|
|
||||||
PARAMS = "-f"
|
|
||||||
elif TYPE == "REISERFS":
|
|
||||||
PROG = "mkfs.reiserfs"
|
|
||||||
PARAMS = "-f"
|
|
||||||
LABELPARAM = "-l"
|
|
||||||
elif TYPE == "REISER4":
|
|
||||||
PROG = "mkfs.reiser4"
|
|
||||||
PARAMS = "-f <<<\"y\""
|
|
||||||
elif TYPE == "XFS":
|
|
||||||
PROG = "mkfs.xfs"
|
|
||||||
PARAMS = "-f"
|
|
||||||
elif TYPE == "JFS":
|
|
||||||
PROG = "mkfs.jfs"
|
|
||||||
PARAMS = "<<<\"y\""
|
|
||||||
elif TYPE == "F2FS":
|
|
||||||
PROG = "mkfs.f2fs"
|
|
||||||
LABELPARAM = "-l"
|
|
||||||
elif TYPE == "NILFS2":
|
|
||||||
PROG = "mkfs.nilfs2"
|
|
||||||
PARAMS = "-f"
|
|
||||||
elif TYPE == "LINUX-SWAP":
|
|
||||||
PROG = "mkswap"
|
|
||||||
elif TYPE == "NTFS":
|
|
||||||
PROG = "mkntfs"
|
|
||||||
PARAMS = "-f"
|
|
||||||
elif TYPE == "EXFAT":
|
|
||||||
PROG = "mkfs.exfat"
|
|
||||||
LABELPARAM = "-n"
|
|
||||||
elif TYPE == "FAT32":
|
|
||||||
PROG = "mkdosfs"
|
|
||||||
PARAMS = "-F 32"
|
|
||||||
LABELPARAM = "-n"
|
|
||||||
elif TYPE == "FAT16":
|
|
||||||
PROG = "mkdosfs"
|
|
||||||
PARAMS = "-F 16"
|
|
||||||
LABELPARAM = "-n"
|
|
||||||
elif TYPE == "FAT12":
|
|
||||||
PROG = "mkdosfs"
|
|
||||||
PARAMS = "-F 12"
|
|
||||||
LABELPARAM = "-n"
|
|
||||||
elif TYPE == "HFS":
|
|
||||||
PROG = "mkfs.hfs"
|
|
||||||
elif TYPE == "HFSPLUS":
|
|
||||||
PROG = "mkfs.hfsplus"
|
|
||||||
LABELPARAM = "-v"
|
|
||||||
elif TYPE == "UFS":
|
|
||||||
PROG = "mkfs.ufs"
|
|
||||||
PARAMS = "-O 2"
|
|
||||||
else:
|
|
||||||
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk} {int_nfilesys} {TYPE}")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Etiquetas de particion.
|
|
||||||
if not str_label:
|
|
||||||
if sys.argv[4] == "CACHE":
|
|
||||||
ogRaiseError(OG_ERR_FORMAT, f"{MSG_RESERVEDVALUE}: CACHE")
|
|
||||||
return
|
|
||||||
if len(sys.argv) >= 4:
|
|
||||||
PARAMS = f"{PARAMS} {LABELPARAM or '-L'} {sys.argv[4]}"
|
|
||||||
else:
|
|
||||||
PARAMS = f"{PARAMS} {LABELPARAM or '-L'} {str_label}"
|
|
||||||
|
|
||||||
# Formatear en modo uso exclusivo (desmontar siempre).
|
|
||||||
ogLock(int_ndisk, int_nfilesys)
|
|
||||||
try:
|
try:
|
||||||
subprocess.run([PROG, PARAMS, PART], capture_output=True)
|
if input:
|
||||||
ERRCODE = 0
|
errcode = subprocess.run ([prog, params, PART])
|
||||||
|
else:
|
||||||
|
errcode = subprocess.run ([prog, params, PART], input=input, text=True)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
ogRaiseError(OG_ERR_NOTEXEC, PROG)
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTEXEC, prog)
|
||||||
ERRCODE = OG_ERR_NOTEXEC
|
errcode = ogGlobals.OG_ERR_NOTEXEC
|
||||||
except:
|
except:
|
||||||
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk} {int_nfilesys}")
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk} {par}")
|
||||||
ERRCODE = OG_ERR_PARTITION
|
errcode = ogGlobals.OG_ERR_PARTITION
|
||||||
|
|
||||||
ogUnlock(int_ndisk, int_nfilesys)
|
ogUnlock (disk, par)
|
||||||
return ERRCODE
|
return errcode
|
||||||
|
|
||||||
def ogGetFsSize(int_ndisk, int_npartition, str_unit=None):
|
|
||||||
# Si se solicita, mostrar ayuda.
|
|
||||||
if str_unit == "help":
|
|
||||||
ogHelp("ogGetFsSize", "ogGetFsSize int_ndisk int_npartition [str_unit]", "ogGetFsSize 1 1", "ogGetFsSize 1 1 KB")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Error si no se reciben 2 o 3 parámetros.
|
#/**
|
||||||
if not (2 <= len(sys.argv) <= 3):
|
# ogGetFsSize int_ndisk int_npartition [str_unit]
|
||||||
ogRaiseError(OG_ERR_FORMAT)
|
#@brief Muestra el tamanio del sistema de archivos indicado, permite definir la unidad de medida, por defecto GB
|
||||||
return
|
#@param int_ndisk nº de orden del disco
|
||||||
|
#@param int_npartition nº de orden de la partición
|
||||||
|
#@param str_unit unidad (opcional, por defecto: KB)
|
||||||
|
#@return float_size - Tamaño del sistema de archivos
|
||||||
|
#@note str_unit = { KB, MB, GB, TB }
|
||||||
|
#@exception OG_ERR_FORMAT Formato incorrecto.
|
||||||
|
#@exception OG_ERR_NOTFOUND Disco o partición no corresponden con un dispositivo.
|
||||||
|
#*/ ##
|
||||||
|
|
||||||
# Obtener unidad y factor de medida.
|
def ogGetFsSize (disk, par, unit=None):
|
||||||
UNIT = str_unit or "KB"
|
u = unit or "KB"
|
||||||
FACTOR = 1
|
factor = 1
|
||||||
if UNIT.upper() == "MB":
|
if u.upper() == "MB":
|
||||||
FACTOR = 1024
|
factor = 1024
|
||||||
elif UNIT.upper() == "GB":
|
elif u.upper() == "GB":
|
||||||
FACTOR = 1024 * 1024
|
factor = 1024 * 1024
|
||||||
elif UNIT.upper() == "TB":
|
elif u.upper() == "TB":
|
||||||
FACTOR = 1024 * 1024 * 1024
|
factor = 1024 * 1024 * 1024
|
||||||
elif UNIT.upper() != "KB":
|
elif u.upper() != "KB":
|
||||||
ogRaiseError(OG_ERR_FORMAT, f"{UNIT} != {{ KB, MB, GB, TB }}")
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f"{unit} != {{ KB, MB, GB, TB }}")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Obtener el tamaño del sistema de archivo (si no está formateado; tamaño = 0).
|
# Obtener el tamaño del sistema de archivo (si no está formateado; tamaño = 0).
|
||||||
MNTDIR = ogMount(int_ndisk, int_npartition)
|
mnt = FileSystemLib.ogMount (disk, par)
|
||||||
if MNTDIR:
|
if mnt:
|
||||||
result = subprocess.run(["df", "-BK", MNTDIR], capture_output=True, text=True)
|
result = subprocess.run(["df", "-BK", mnt], capture_output=True, text=True)
|
||||||
VALUE = result.stdout.split("\n")[1].split()[1]
|
val = result.stdout.split("\n")[1].split()[1]
|
||||||
SIZE = float(VALUE) / FACTOR
|
val = val.replace ('K', '')
|
||||||
|
sz = int (val) / factor
|
||||||
else:
|
else:
|
||||||
SIZE = 0
|
sz = 0
|
||||||
|
|
||||||
|
return int (sz)
|
||||||
|
|
||||||
# Devolver el tamaño (quitar decimales si son 0).
|
|
||||||
return int(SIZE) if SIZE.is_integer() else SIZE
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
# ogGetFsType int_ndisk int_nfilesys
|
# ogGetFsType int_ndisk int_nfilesys
|
||||||
|
@ -461,26 +436,24 @@ def ogIsLocked(disk, par):
|
||||||
def ogIsPartitionLocked(disk, par):
|
def ogIsPartitionLocked(disk, par):
|
||||||
DISK = DiskLib.ogDiskToDev(disk)
|
DISK = DiskLib.ogDiskToDev(disk)
|
||||||
PART = DiskLib.ogDiskToDev(disk, par)
|
PART = DiskLib.ogDiskToDev(disk, par)
|
||||||
|
print (f'nati: ogIsPartitionLocked: DISK ({DISK}) PART ({PART})')
|
||||||
if not PART: return
|
if not PART: return
|
||||||
|
|
||||||
LOCKDISK = f"/var/lock/lock{DISK.replace('/', '-')}"
|
LOCKDISK = f"/var/lock/lock{DISK.replace('/', '-')}"
|
||||||
LOCKPART = f"/var/lock/lock{PART.replace('/', '-')}"
|
LOCKPART = f"/var/lock/lock{PART.replace('/', '-')}"
|
||||||
return os.path.isfile(LOCKDISK) or os.path.isfile(LOCKPART)
|
rc = os.path.isfile(LOCKDISK) or os.path.isfile(LOCKPART)
|
||||||
|
print (f'nati: ogIsPartitionLocked: LOCKDISK ({LOCKDISK}) LOCKPART ({LOCKPART}) rc ({rc})')
|
||||||
|
return rc
|
||||||
|
|
||||||
def ogIsMounted(int_ndisk, int_nfilesys):
|
#/**
|
||||||
# Si se solicita, mostrar ayuda.
|
# ogIsMounted int_ndisk int_nfilesys
|
||||||
if len(sys.argv) == 3 and sys.argv[2] == "help":
|
#@brief Comprueba si un sistema de archivos está montado.
|
||||||
ogHelp("ogIsMounted", "ogIsMounted int_ndisk int_nfilesys", "ogIsMounted 1 1")
|
#@param int_ndisk nº de orden del disco
|
||||||
return
|
#@param int_nfilesys nº de orden del sistema de archivos
|
||||||
|
#@return Código de salida: 0 - montado, 1 - sin montar o error.
|
||||||
# Error si no se reciben 2 parámetros.
|
#*/ ##
|
||||||
if len(sys.argv) != 3:
|
def ogIsMounted (disk, par):
|
||||||
ogRaiseError(OG_ERR_FORMAT)
|
return bool (ogGetMountPoint (disk, par))
|
||||||
return
|
|
||||||
|
|
||||||
# Obtener punto de montaje.
|
|
||||||
MNTDIR = ogGetMountPoint(int_ndisk, int_nfilesys)
|
|
||||||
return bool(MNTDIR)
|
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
|
@ -523,28 +496,31 @@ def ogIsWritable(int_ndisk, int_nfilesys):
|
||||||
options = result.stdout.strip().split(",")
|
options = result.stdout.strip().split(",")
|
||||||
return "rw" in options
|
return "rw" in options
|
||||||
|
|
||||||
def ogLock(int_ndisk, int_nfilesys):
|
|
||||||
ogLockPartition(int_ndisk, int_nfilesys)
|
|
||||||
|
|
||||||
def ogLockPartition(int_ndisk, int_npartition):
|
#/**
|
||||||
# Si se solicita, mostrar ayuda.
|
# ogLock int_ndisk int_npartition
|
||||||
if len(sys.argv) == 3 and sys.argv[2] == "help":
|
#@see ogLockPartition
|
||||||
ogHelp("ogLockPartition", "ogLockPartition int_ndisk int_npartition", "ogLockPartition 1 1")
|
#*/
|
||||||
return
|
def ogLock(disk, par):
|
||||||
|
return ogLockPartition(disk, par)
|
||||||
|
|
||||||
# Error si no se reciben 2 parámetros.
|
#/**
|
||||||
if len(sys.argv) != 3:
|
# ogLockPartition int_ndisk int_npartition
|
||||||
ogRaiseError(OG_ERR_FORMAT)
|
#@brief Genera un fichero de bloqueo para una partición en uso exlusivo.
|
||||||
return
|
#@param int_ndisk nº de orden del disco
|
||||||
|
#@param int_npartition nº de orden de la partición
|
||||||
|
#@return (nada)
|
||||||
|
#@exception OG_ERR_FORMAT Formato incorrecto.
|
||||||
|
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
|
||||||
|
#@note El fichero de bloqueo se localiza en \c /var/lock/part, siendo \c part el dispositivo de la partición, sustituyendo el carácter "/" por "-".
|
||||||
|
#*/ ##
|
||||||
|
def ogLockPartition (disk, par):
|
||||||
|
PART = DiskLib.ogDiskToDev (disk, par)
|
||||||
|
if not PART: return
|
||||||
|
|
||||||
# Obtener partición.
|
|
||||||
PART = ogDiskToDev(int_ndisk, int_npartition)
|
|
||||||
if not PART:
|
|
||||||
return
|
|
||||||
|
|
||||||
# Crear archivo de bloqueo exclusivo.
|
|
||||||
LOCKFILE = f"/var/lock/lock{PART.replace('/', '-')}"
|
LOCKFILE = f"/var/lock/lock{PART.replace('/', '-')}"
|
||||||
open(LOCKFILE, 'a').close()
|
open(LOCKFILE, 'w').close()
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
|
@ -580,7 +556,6 @@ def ogMountFirstFs(int_ndisk):
|
||||||
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
|
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
|
||||||
#@exception OG_ERR_PARTITION Tipo de particion desconocido o no se puede montar.
|
#@exception OG_ERR_PARTITION Tipo de particion desconocido o no se puede montar.
|
||||||
#*/ ##
|
#*/ ##
|
||||||
|
|
||||||
def ogMountFs (disk, par):
|
def ogMountFs (disk, par):
|
||||||
dev = DiskLib.ogDiskToDev (disk, par)
|
dev = DiskLib.ogDiskToDev (disk, par)
|
||||||
if not dev: return
|
if not dev: return
|
||||||
|
@ -589,6 +564,7 @@ def ogMountFs (disk, par):
|
||||||
if mntdir: return mntdir
|
if mntdir: return mntdir
|
||||||
|
|
||||||
if ogIsLocked (disk, par):
|
if ogIsLocked (disk, par):
|
||||||
|
print (f'nati: ogMountFs: is locked disk ({disk}) par ({par})')
|
||||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f"{ogGlobals.lang.MSG_PARTITION}, {disk} {par}")
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f"{ogGlobals.lang.MSG_PARTITION}, {disk} {par}")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -727,26 +703,28 @@ def ogReduceFs(int_ndisk, int_nfilesys):
|
||||||
# Devuelve tamaño del sistema de ficheros.
|
# Devuelve tamaño del sistema de ficheros.
|
||||||
return ogGetFsSize(int_ndisk, int_nfilesys)
|
return ogGetFsSize(int_ndisk, int_nfilesys)
|
||||||
|
|
||||||
def ogUnlock(int_ndisk, int_npartition):
|
|
||||||
ogUnlockPartition(int_ndisk, int_npartition)
|
|
||||||
|
|
||||||
def ogUnlockPartition(int_ndisk, int_npartition):
|
#/**
|
||||||
# Si se solicita, mostrar ayuda.
|
# ogUnlock int_ndisk int_npartition
|
||||||
if len(sys.argv) == 3 and sys.argv[2] == "help":
|
#@see ogUnlockPartition
|
||||||
ogHelp("ogUnlockPartition", "ogUnlockPartition int_ndisk int_npartition", "ogUnlockPartition 1 1")
|
#*/ ##
|
||||||
return
|
def ogUnlock (disk, par):
|
||||||
|
return ogUnlockPartition (disk, par)
|
||||||
|
|
||||||
# Error si no se reciben 2 parámetros.
|
#/**
|
||||||
if len(sys.argv) != 3:
|
# ogUnlockPartition int_ndisk int_npartition
|
||||||
ogRaiseError(OG_ERR_FORMAT)
|
#@brief Elimina el fichero de bloqueo para una particion.
|
||||||
return
|
#@param int_ndisk nº de orden del disco
|
||||||
|
#@param int_npartition nº de orden de la partición
|
||||||
|
#@return (nada)
|
||||||
|
#@exception OG_ERR_FORMAT Formato incorrecto.
|
||||||
|
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
|
||||||
|
#@note El fichero de bloqueo se localiza en \c /var/lock/part, siendo \c part el dispositivo de la partición, sustituyendo el carácter "/" por "-".
|
||||||
|
#*/ ##
|
||||||
|
def ogUnlockPartition (disk, par):
|
||||||
|
PART = DiskLib.ogDiskToDev (disk, par)
|
||||||
|
if not PART: return
|
||||||
|
|
||||||
# Obtener partición.
|
|
||||||
PART = ogDiskToDev(int_ndisk, int_npartition)
|
|
||||||
if not PART:
|
|
||||||
return
|
|
||||||
|
|
||||||
# Borrar archivo de bloqueo exclusivo.
|
|
||||||
LOCKFILE = f"/var/lock/lock{PART.replace('/', '-')}"
|
LOCKFILE = f"/var/lock/lock{PART.replace('/', '-')}"
|
||||||
os.remove(LOCKFILE)
|
os.remove(LOCKFILE)
|
||||||
|
|
||||||
|
@ -756,7 +734,7 @@ def ogUnlockPartition(int_ndisk, int_npartition):
|
||||||
#@see ogUnmountFs
|
#@see ogUnmountFs
|
||||||
#*/ ##
|
#*/ ##
|
||||||
def ogUnmount (disk, par):
|
def ogUnmount (disk, par):
|
||||||
ogUnmountFs (disk, par)
|
return ogUnmountFs (disk, par)
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
# ogUnmountFs int_ndisk int_nfilesys
|
# ogUnmountFs int_ndisk int_nfilesys
|
||||||
|
@ -793,8 +771,10 @@ def ogUnmountFs(disk, par):
|
||||||
os.remove(MNTDIR)
|
os.remove(MNTDIR)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
return True
|
||||||
else:
|
else:
|
||||||
SystemLib.ogEcho ([], "warning", f'{ogGlobals.lang.MSG_DONTMOUNT}: "{disk},{par}"')
|
SystemLib.ogEcho ([], "warning", f'{ogGlobals.lang.MSG_DONTMOUNT}: "{disk},{par}"')
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
|
|
|
@ -267,6 +267,17 @@ def ogRestoreImageSyntax (imgfile, part, tool=None, level=None):
|
||||||
#@note repo = { REPO, CACHE }
|
#@note repo = { REPO, CACHE }
|
||||||
#@exception OG_ERR_FORMAT formato incorrecto.
|
#@exception OG_ERR_FORMAT formato incorrecto.
|
||||||
#*/ ##
|
#*/ ##
|
||||||
|
#ogIsImageLocked ('/opt/opengnsys/images/aula1/win7.img')
|
||||||
|
#ogIsImageLocked ('REPO', '/aula1/win7.img')
|
||||||
|
def ogIsImageLocked (container=None, imgfile=None):
|
||||||
|
if container and imgfile:
|
||||||
|
p = FileLib.ogGetPath (src=container, file=f'{imgfile}.lock')
|
||||||
|
elif imgfile:
|
||||||
|
p = FileLib.ogGetPath (file=f'{imgfile}.lock')
|
||||||
|
else:
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'{container} {imgfile}')
|
||||||
|
return
|
||||||
|
return os.path.exists (p)
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
|
@ -315,6 +326,68 @@ def ogRestoreImageSyntax (imgfile, part, tool=None, level=None):
|
||||||
#@exception OG_ERR_IMGSIZEPARTITION 30 Tamaño de la particion es menor al tamaño de la imagen.
|
#@exception OG_ERR_IMGSIZEPARTITION 30 Tamaño de la particion es menor al tamaño de la imagen.
|
||||||
#@todo Comprobar incongruencias partición-imagen, control de errores, definir parámetros, caché/repositorio, etc.
|
#@todo Comprobar incongruencias partición-imagen, control de errores, definir parámetros, caché/repositorio, etc.
|
||||||
#*/ ##
|
#*/ ##
|
||||||
|
#ogRestoreImage ('REPO', '/aula1/win7', '1', '1')
|
||||||
|
def ogRestoreImage (repo, imgpath, disk, par):
|
||||||
|
PART = DiskLib.ogDiskToDev (disk, par)
|
||||||
|
if not PART:
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f' {disk} {par}')
|
||||||
|
return None
|
||||||
|
|
||||||
|
imgtype = 'img'
|
||||||
|
imgfile = FileLib.ogGetPath (repo, f'{imgpath}.{imgtype}')
|
||||||
|
if not os.path.exists (imgfile):
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f' {disk} {par}')
|
||||||
|
return None
|
||||||
|
|
||||||
|
if not ogGetImageInfo (imgfile):
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f' {repo} {imgpath}')
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Error si la imagen no cabe en la particion.
|
||||||
|
imgsize = ogGetImageSize (repo, imgpath)
|
||||||
|
if not imgsize:
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f' {repo} {imgpath}')
|
||||||
|
return None
|
||||||
|
if not FileSystemLib.ogMount (disk, par):
|
||||||
|
FileSystemLib.ogFormat (disk, par)
|
||||||
|
partsize = DiskLib.ogGetPartitionSize (disk, par)
|
||||||
|
if float (imgsize) > float (partsize):
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMGSIZEPARTITION, f' {partsize} < {imgsize}')
|
||||||
|
return None
|
||||||
|
|
||||||
|
if ogIsImageLocked (container=None, imgfile=imgfile):
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_IMAGE} {repo}, {imgpath}.{imgtype}')
|
||||||
|
return None
|
||||||
|
|
||||||
|
if FileSystemLib.ogIsLocked (disk, par):
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_PARTITION} {disk}, {par}')
|
||||||
|
return None
|
||||||
|
|
||||||
|
program = ogRestoreImageSyntax (imgfile, PART)
|
||||||
|
|
||||||
|
if not FileSystemLib.ogUnmount (disk, par):
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f' {disk} {par}')
|
||||||
|
return None
|
||||||
|
|
||||||
|
if not FileSystemLib.ogLock (disk, par):
|
||||||
|
print (f'not FileSystemLib.ogLock()')
|
||||||
|
return None
|
||||||
|
|
||||||
|
rc = None
|
||||||
|
try:
|
||||||
|
print (f'nati: ogRestoreImage: running ({program})')
|
||||||
|
p = subprocess.run (program, shell=True, capture_output=True, text=True)
|
||||||
|
rc = p.returncode
|
||||||
|
print (f'nati: ogRestoreImage: rc ({rc}) stdout ({p.stdout}) stderr ({p.stderr})')
|
||||||
|
if not rc:
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobalsOG_ERR_IMAGE, f'{imgfile}, {disk}, {par}')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
FileSystemLib.ogUnlock (disk, par)
|
||||||
|
|
||||||
|
return rc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
|
@ -516,6 +589,14 @@ def ogGetImageInfo (imgfile):
|
||||||
#@note ogGetImageProgram REPO imagenA -> partclone
|
#@note ogGetImageProgram REPO imagenA -> partclone
|
||||||
#*/ ##
|
#*/ ##
|
||||||
|
|
||||||
|
#ogGetImageProgram ('REPO', 'prueba') ==> 'PARTCLONE'
|
||||||
|
def ogGetImageProgram (container, filename):
|
||||||
|
imgfile = FileLib.ogGetPath (container, f'{filename}.img')
|
||||||
|
if not os.path.exists (imgfile):
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
|
||||||
|
return None
|
||||||
|
i = ogGetImageInfo (imgfile)
|
||||||
|
return i.split (':')[0]
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
# ogGetImageCompressor str_REPO str_imagen
|
# ogGetImageCompressor str_REPO str_imagen
|
||||||
|
@ -529,6 +610,15 @@ def ogGetImageInfo (imgfile):
|
||||||
#@note ogGetImageCompressor REPO imagenA -> lzop
|
#@note ogGetImageCompressor REPO imagenA -> lzop
|
||||||
#*/ ##
|
#*/ ##
|
||||||
|
|
||||||
|
#ogGetImageCompressor ('REPO', 'prueba') ==> 'LZOP'
|
||||||
|
def ogGetImageCompressor (container, filename):
|
||||||
|
imgfile = FileLib.ogGetPath (container, f'{filename}.img')
|
||||||
|
if not os.path.exists (imgfile):
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
|
||||||
|
return None
|
||||||
|
i = ogGetImageInfo (imgfile)
|
||||||
|
return i.split (':')[1]
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
# ogGetImageType str_REPO str_imagen
|
# ogGetImageType str_REPO str_imagen
|
||||||
|
@ -544,7 +634,7 @@ def ogGetImageInfo (imgfile):
|
||||||
#ogGetImageType ('REPO', 'imgprueba') ==> 'NTFS'
|
#ogGetImageType ('REPO', 'imgprueba') ==> 'NTFS'
|
||||||
#ogGetImageType ('CACHE', 'testimg') ==> 'EXTFS'
|
#ogGetImageType ('CACHE', 'testimg') ==> 'EXTFS'
|
||||||
def ogGetImageType (repo, imgname):
|
def ogGetImageType (repo, imgname):
|
||||||
imgfile = FileLib.ogGetPath (src=repo, file=imgname)
|
imgfile = FileLib.ogGetPath (src=repo, file=f'{imgname}.img')
|
||||||
if not os.path.exists (imgfile):
|
if not os.path.exists (imgfile):
|
||||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
|
||||||
return None
|
return None
|
||||||
|
@ -565,6 +655,15 @@ def ogGetImageType (repo, imgname):
|
||||||
#@exception OG_ERR_NOTFOUND fichero no encontrado.
|
#@exception OG_ERR_NOTFOUND fichero no encontrado.
|
||||||
#@note ogGetImagesize REPO imagenA -> 56432234 > Kb
|
#@note ogGetImagesize REPO imagenA -> 56432234 > Kb
|
||||||
#*/ ##
|
#*/ ##
|
||||||
|
#ogGetImageSize ('REPO', 'prueba') ==> '5642158'
|
||||||
|
def ogGetImageSize (repo, imgname):
|
||||||
|
imgfile = FileLib.ogGetPath (src=repo, file=f'{imgname}.img')
|
||||||
|
if not os.path.exists (imgfile):
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
|
||||||
|
return None
|
||||||
|
|
||||||
|
i = ogGetImageInfo (imgfile)
|
||||||
|
return i.split (':')[3]
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
|
|
|
@ -40,7 +40,7 @@ def ogChangeRepo(ip_repo, og_unit=None):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
mount = subprocess.run (['mount'], capture_output=True, text=True).stdout
|
mount = subprocess.run (['mount'], capture_output=True, text=True).stdout
|
||||||
ro = not not list (filter (lambda line: re.search (r'ogimages.*\bro,', line), mount.splitlines()))
|
ro = bool (list (filter (lambda line: re.search (r'ogimages.*\bro,', line), mount.splitlines())))
|
||||||
|
|
||||||
current_repo = ogGetRepoIp()
|
current_repo = ogGetRepoIp()
|
||||||
new_repo = current_repo if ip_repo.upper() == "REPO" else ip_repo
|
new_repo = current_repo if ip_repo.upper() == "REPO" else ip_repo
|
||||||
|
@ -48,7 +48,7 @@ def ogChangeRepo(ip_repo, og_unit=None):
|
||||||
|
|
||||||
subprocess.run(["umount", ogGlobals.OGIMG], check=True)
|
subprocess.run(["umount", ogGlobals.OGIMG], check=True)
|
||||||
|
|
||||||
SystemLib.ogEcho (['session', 'log'], 'info', f'{ogGlobals.lang.MSG_HELP_ogChangeRepo} {new_repo}')
|
SystemLib.ogEcho (['session', 'log'], None, f'{ogGlobals.lang.MSG_HELP_ogChangeRepo} {new_repo}')
|
||||||
options = _ogConnect_options()
|
options = _ogConnect_options()
|
||||||
if not _ogConnect (new_repo, ogprotocol, 'ogimages', ogGlobals.OGIMG, options, ro):
|
if not _ogConnect (new_repo, ogprotocol, 'ogimages', ogGlobals.OGIMG, options, ro):
|
||||||
_ogConnect (current_repo, ogprotocol, 'ogimages', ogGlobals.OGIMG, options, ro)
|
_ogConnect (current_repo, ogprotocol, 'ogimages', ogGlobals.OGIMG, options, ro)
|
||||||
|
@ -61,7 +61,7 @@ def ogChangeRepo(ip_repo, og_unit=None):
|
||||||
|
|
||||||
SystemLib.ogEcho(
|
SystemLib.ogEcho(
|
||||||
["session", "log"],
|
["session", "log"],
|
||||||
'info',
|
None,
|
||||||
f"Repository successfully changed to {new_repo}".strip(),
|
f"Repository successfully changed to {new_repo}".strip(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -164,28 +164,30 @@ def ogGetHostname():
|
||||||
#@note Usa las variables utilizadas por el initrd "/etc/net-ethX.conf
|
#@note Usa las variables utilizadas por el initrd "/etc/net-ethX.conf
|
||||||
#*/ ##
|
#*/ ##
|
||||||
def ogGetIpAddress():
|
def ogGetIpAddress():
|
||||||
IP = ""
|
|
||||||
|
|
||||||
if len(sys.argv) >= 2 and sys.argv[1] == "help":
|
|
||||||
SystemLib.ogHelp("ogGetIpAddress", "ogGetIpAddress", "ogGetIpAddress => 192.168.0.10")
|
|
||||||
return
|
|
||||||
|
|
||||||
if "IPV4ADDR" in os.environ:
|
if "IPV4ADDR" in os.environ:
|
||||||
IP = os.environ["IPV4ADDR"]
|
ip = os.environ["IPV4ADDR"]
|
||||||
else:
|
if '/' in ip: ip = ip.split ('/')[0]
|
||||||
# Obtener direcciones IP.
|
return ip
|
||||||
|
|
||||||
|
extra_args = []
|
||||||
if "DEVICE" in os.environ:
|
if "DEVICE" in os.environ:
|
||||||
IP = subprocess.run(["ip", "-o", "address", "show", "up", "dev", os.environ["DEVICE"]], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode().split()
|
extra_args = [ "dev", os.environ["DEVICE"] ]
|
||||||
else:
|
ipas = subprocess.run (['ip', '-json', 'address', 'show', 'up'] + extra_args, capture_output=True, text=True).stdout
|
||||||
IP = subprocess.run(["ip", "-o", "address", "show", "up"], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode().split()
|
|
||||||
|
|
||||||
IP = [addr.split("/")[0] for addr in IP if "inet" in addr]
|
ipasj = json.loads (ipas)
|
||||||
|
addresses = []
|
||||||
|
for e in ipasj:
|
||||||
|
if 'lo' == e['ifname']: continue
|
||||||
|
if 'addr_info' not in e: continue
|
||||||
|
addrs = e['addr_info']
|
||||||
|
for a in addrs:
|
||||||
|
if 'inet' != a['family']: continue
|
||||||
|
addresses.append ({ 'local': a['local'], 'prefixlen': a['prefixlen'] })
|
||||||
|
|
||||||
# Mostrar solo la primera.
|
if 1 != len (addresses):
|
||||||
if IP:
|
raise Exception ('more than one local IP address found')
|
||||||
print(IP[0])
|
return addresses[0]
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
# ogGetMacAddress
|
# ogGetMacAddress
|
||||||
|
|
|
@ -246,9 +246,6 @@ def _clientip():
|
||||||
addresses = []
|
addresses = []
|
||||||
for e in ipasj:
|
for e in ipasj:
|
||||||
if 'lo' == e['ifname']: continue
|
if 'lo' == e['ifname']: continue
|
||||||
if 'vboxnet' in e['ifname']: continue
|
|
||||||
if 'br-' in e['ifname']: continue
|
|
||||||
if 'tun' in e['ifname']: continue
|
|
||||||
if 'addr_info' not in e: continue
|
if 'addr_info' not in e: continue
|
||||||
addrs = e['addr_info']
|
addrs = e['addr_info']
|
||||||
for a in addrs:
|
for a in addrs:
|
||||||
|
@ -642,7 +639,7 @@ def ogMcastReceiverPartition (disk, par, sess, tool, compressor):
|
||||||
#*/ ##
|
#*/ ##
|
||||||
## now ogCore takes this responsibility
|
## now ogCore takes this responsibility
|
||||||
def ogMcastRequest (img, proto):
|
def ogMcastRequest (img, proto):
|
||||||
return
|
return True
|
||||||
|
|
||||||
|
|
||||||
##########################################
|
##########################################
|
||||||
|
@ -754,7 +751,7 @@ def ogTorrentStart (disk=None, par=None, container=None, torrentfile=None, torre
|
||||||
if 'peer' == mode:
|
if 'peer' == mode:
|
||||||
print ('Donwloading Torrent as peer')
|
print ('Donwloading Torrent as peer')
|
||||||
# Creamos el fichero de resumen por defecto
|
# Creamos el fichero de resumen por defecto
|
||||||
with open (f'{source}.bf', 'w') as fd: pass
|
open (f'{source}.bf', 'w').close()
|
||||||
# ctorrent controla otro fichero -b ${SOURCE}.bfog
|
# ctorrent controla otro fichero -b ${SOURCE}.bfog
|
||||||
subprocess.run (['ctorrent', '-f', '-c', '-X', f'sleep {time}; kill -2 $(pidof ctorrent)', '-C', '100', source, '-s', target, '-b', f'{source}.bfog'])
|
subprocess.run (['ctorrent', '-f', '-c', '-X', f'sleep {time}; kill -2 $(pidof ctorrent)', '-C', '100', source, '-s', target, '-b', f'{source}.bfog'])
|
||||||
elif 'leecher' == mode:
|
elif 'leecher' == mode:
|
||||||
|
@ -763,7 +760,7 @@ def ogTorrentStart (disk=None, par=None, container=None, torrentfile=None, torre
|
||||||
elif 'seeder' == mode:
|
elif 'seeder' == mode:
|
||||||
print ('MODE seeder ctorrent')
|
print ('MODE seeder ctorrent')
|
||||||
# Creamos el fichero de resumen por defecto
|
# Creamos el fichero de resumen por defecto
|
||||||
with open (f'{source}.bf', 'w') as fd: pass
|
open (f'{source}.bf', 'w').close()
|
||||||
# ctorrent controla otro fichero -b ${SOURCE}.bfog
|
# ctorrent controla otro fichero -b ${SOURCE}.bfog
|
||||||
subprocess.run (['ctorrent', '-f', '-c', '-X', f'sleep {time}; kill -2 $(pidof ctorrent)', '-C', '100', source, '-s', target, '-b', f'{source}.bfog'])
|
subprocess.run (['ctorrent', '-f', '-c', '-X', f'sleep {time}; kill -2 $(pidof ctorrent)', '-C', '100', source, '-s', target, '-b', f'{source}.bfog'])
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -6,6 +6,10 @@ import os
|
||||||
import shutil
|
import shutil
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
|
## for ogExecAndLog
|
||||||
|
from io import StringIO
|
||||||
|
from contextlib import redirect_stdout, redirect_stderr
|
||||||
|
|
||||||
import ogGlobals
|
import ogGlobals
|
||||||
import StringLib
|
import StringLib
|
||||||
|
|
||||||
|
@ -14,9 +18,9 @@ import StringLib
|
||||||
#OGLOGSESSION, OGLOGCOMMAND, OGLOGFILE, OG_ERR_LOCKED, OG_ERR_PARTITION, OG_ERR_FORMAT, OG_ERR_NOTEXEC, OG_ERR_NOTFOUND
|
#OGLOGSESSION, OGLOGCOMMAND, OGLOGFILE, OG_ERR_LOCKED, OG_ERR_PARTITION, OG_ERR_FORMAT, OG_ERR_NOTEXEC, OG_ERR_NOTFOUND
|
||||||
|
|
||||||
def _logtype2logfile (t):
|
def _logtype2logfile (t):
|
||||||
if 'log' == t: return ogGlobals.OGLOGFILE
|
if 'log' == t.lower(): return ogGlobals.OGLOGFILE
|
||||||
elif 'command' == t: return ogGlobals.OGLOGCOMMAND
|
elif 'command' == t.lower(): return ogGlobals.OGLOGCOMMAND
|
||||||
elif 'session' == t: return ogGlobals.OGLOGSESSION
|
elif 'session' == t.lower(): return ogGlobals.OGLOGSESSION
|
||||||
else: raise Exception (f'unknown log type ({t})')
|
else: raise Exception (f'unknown log type ({t})')
|
||||||
#/**
|
#/**
|
||||||
# ogEcho [str_logtype ...] [str_loglevel] "str_message" ...
|
# ogEcho [str_logtype ...] [str_loglevel] "str_message" ...
|
||||||
|
@ -51,58 +55,88 @@ def ogEcho (logtypes, loglevel, msg):
|
||||||
else:
|
else:
|
||||||
raise Exception (f'unknown loglevel ({loglevel})')
|
raise Exception (f'unknown loglevel ({loglevel})')
|
||||||
|
|
||||||
def ogExecAndLog(*args):
|
|
||||||
# Variables locales
|
|
||||||
ISCOMMAND = False
|
|
||||||
ISLOG = False
|
|
||||||
ISSESSION = False
|
|
||||||
COMMAND = ""
|
|
||||||
CONTINUE = 1
|
|
||||||
FILES = ""
|
|
||||||
REDIREC = ""
|
|
||||||
FUNCNAME = ogExecAndLog.__name__
|
|
||||||
|
|
||||||
# Si se solicita, mostrar ayuda.
|
#/**
|
||||||
if len(args) > 0 and args[0] == "help":
|
# ogExecAndLog str_logfile ... str_command ...
|
||||||
ogHelp(f"{FUNCNAME} str_logfile ... str_command ...",
|
#@brief Ejecuta un comando y guarda su salida en fichero de registro.
|
||||||
f"{FUNCNAME} COMMAND ls -al /")
|
#@param str_logfile fichero de registro (pueden ser varios).
|
||||||
|
#@param str_command comando y comandos a ejecutar.
|
||||||
|
#@return Salida de ejecución del comando.
|
||||||
|
#@note str_logfile = { LOG, SESSION, COMMAND }
|
||||||
|
#*/
|
||||||
|
#ogHelp (str_logfile ... str_command ...",
|
||||||
|
#ogHelp ([], ogMyLib.ogSomeMethod, *args, **kwargs)
|
||||||
|
#ogHelp ('command', ogMyLib.ogSomeMethod, *args, **kwargs)
|
||||||
|
#ogHelp (['command'], ogMyLib.ogSomeMethod, *args, **kwargs)
|
||||||
|
#ogHelp (['log', 'command'], ogMyLib.ogSomeMethod, *args, **kwargs)
|
||||||
|
def ogExecAndLog (logtypes, fun, *args, **kwargs):
|
||||||
|
logfiles = ['/dev/stdout']
|
||||||
|
if type (logtypes) is list:
|
||||||
|
for l in logtypes:
|
||||||
|
logtypes = list (map (lambda x: x.lower(), logtypes))
|
||||||
|
logfiles.append (_logtype2logfile (l))
|
||||||
|
else: ## string
|
||||||
|
logtypes = logtypes.lower()
|
||||||
|
logfiles.append (_logtype2logfile (logtypes))
|
||||||
|
|
||||||
|
if not fun:
|
||||||
|
ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'no function provided')
|
||||||
return
|
return
|
||||||
|
|
||||||
# Procesar parámetros.
|
## the original bash code does something like this:
|
||||||
while CONTINUE:
|
#if [ $ISCOMMAND ]; then
|
||||||
arg = args.pop(0).lower()
|
# > $OGLOGCOMMAND
|
||||||
if arg == "command":
|
# REDIREC="2>&1"
|
||||||
ISCOMMAND = True
|
#fi
|
||||||
continue
|
#eval $COMMAND $REDIREC | tee -a $FILES
|
||||||
elif arg == "log":
|
|
||||||
ISLOG = True
|
## a hybrid bash/python pseudocode would end up being like the following:
|
||||||
continue
|
#if 'command' in logtypes:
|
||||||
elif arg == "session":
|
# rm $OGLOGCOMMAND
|
||||||
ISSESSION = True
|
# touch $OGLOGCOMMAND
|
||||||
continue
|
#
|
||||||
|
#if 'command' in logtypes:
|
||||||
|
# ## redirect both stdout and stderr
|
||||||
|
# eval $COMMAND 2>&1 | tee -a $FILES
|
||||||
|
#else:
|
||||||
|
# ## redirect stdout only
|
||||||
|
# eval $COMMAND | tee -a $FILES
|
||||||
|
|
||||||
|
import time
|
||||||
|
sout = serr = ''
|
||||||
|
if 'command' in logtypes:
|
||||||
|
os.unlink (ogGlobals.OGLOGCOMMAND)
|
||||||
|
open (ogGlobals.OGLOGCOMMAND, 'w').close()
|
||||||
|
print ('nati: ogExecAndLog: about to redirect stdout and stderr')
|
||||||
|
time.sleep (1) ## nati
|
||||||
|
with redirect_stdout (StringIO()) as r_stdout, redirect_stderr (StringIO()) as r_stderr:
|
||||||
|
rc = fun (*args, **kwargs)
|
||||||
|
sout = r_stdout.getvalue()
|
||||||
|
serr = r_stderr.getvalue()
|
||||||
|
print (f'nati: ogExecAndLog: end of redirections, rc ({rc}) sout ({sout}) serr ({serr})')
|
||||||
|
time.sleep (1) ## nati
|
||||||
else:
|
else:
|
||||||
COMMAND = " ".join(args)
|
print ('nati: ogExecAndLog: about to redirect stdout only')
|
||||||
CONTINUE = 0
|
time.sleep (1)
|
||||||
|
with redirect_stdout (StringIO()) as r_stdout:
|
||||||
|
rc = fun (*args, **kwargs)
|
||||||
|
sout = r_stdout.getvalue()
|
||||||
|
print (f'nati: ogExecAndLog: end of redirections, rc ({rc}) sout ({sout})')
|
||||||
|
time.sleep (1) ## nati
|
||||||
|
|
||||||
# Error si no se recibe un comando que ejecutar.
|
if sout or serr:
|
||||||
if not COMMAND:
|
print ('nati: ogExecAndLog: sout or serr are true')
|
||||||
ogRaiseError(OG_ERR_FORMAT)
|
time.sleep (1) ## nati
|
||||||
return
|
for f in logfiles:
|
||||||
|
print (f'nati: ogExecAndLog: logging to logfile ({f})')
|
||||||
|
with open (f, 'a') as fd:
|
||||||
|
if sout: fd.write (f"ogExecAndLog: {fun.__name__} stdout:\n{sout}")
|
||||||
|
else: fd.write (f"ogExecAndLog: {fun.__name__} stdout: (none)\n")
|
||||||
|
if serr: fd.write (f"ogExecAndLog: {fun.__name__} stderr:\n{serr}")
|
||||||
|
else: fd.write (f"ogExecAndLog: {fun.__name__} stderr: (none)\n")
|
||||||
|
|
||||||
# Componer lista de ficheros de registro.
|
print (f'nati: ogExecAndLog: returning rc ({rc})')
|
||||||
if ISCOMMAND:
|
return rc
|
||||||
FILES = OGLOGCOMMAND
|
|
||||||
open(FILES, "w").close()
|
|
||||||
REDIREC = "2>&1"
|
|
||||||
if ISLOG:
|
|
||||||
FILES += " " + OGLOGFILE
|
|
||||||
if ISSESSION:
|
|
||||||
FILES += " " + OGLOGSESSION
|
|
||||||
|
|
||||||
# Ejecutar comando.
|
|
||||||
subprocess.call(f"{COMMAND} {REDIREC} | tee -a {FILES}", shell=True)
|
|
||||||
# Salida de error del comando ejecutado.
|
|
||||||
return subprocess.PIPESTATUS[0]
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
# ogGetCaller
|
# ogGetCaller
|
||||||
|
@ -211,14 +245,14 @@ def ogRaiseError (logtypes, code, msg):
|
||||||
CODE = ogGlobals.OG_ERR_GENERIC
|
CODE = ogGlobals.OG_ERR_GENERIC
|
||||||
|
|
||||||
call_stack = [i[3] for i in inspect.stack()]
|
call_stack = [i[3] for i in inspect.stack()]
|
||||||
if len (call_stack) < 3: return ## shouldn't happen
|
if len (call_stack) < 2: return ## shouldn't happen
|
||||||
call_stack.pop() ## remove '<module>'
|
call_stack.pop() ## remove '<module>'
|
||||||
call_stack.pop(0) ## remove 'ogRaiseError'
|
call_stack.pop(0) ## remove 'ogRaiseError'
|
||||||
str_call_stack = ' '.join (call_stack)
|
str_call_stack = ' '.join (call_stack)
|
||||||
|
|
||||||
if code == ogGlobals.OG_ERR_FORMAT or \
|
if code == ogGlobals.OG_ERR_FORMAT or \
|
||||||
StringLib.ogCheckStringInGroup (str_call_stack, ogGlobals.NODEBUGFUNCTIONS) or \
|
StringLib.ogCheckStringInGroup (str_call_stack, ogGlobals.NODEBUGFUNCTIONS) or \
|
||||||
not StringLib.ogCheckStringInGroup (call_stack[0], ogGlobals.NODEBUGFUNCTIONS):
|
not (len(call_stack)>0 and StringLib.ogCheckStringInGroup (call_stack[0], ogGlobals.NODEBUGFUNCTIONS)):
|
||||||
ogEcho (logtypes, "error", f"{str_call_stack.replace(' ', '<-')}: {MSG}")
|
ogEcho (logtypes, "error", f"{str_call_stack.replace(' ', '<-')}: {MSG}")
|
||||||
|
|
||||||
return code
|
return code
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
#/**
|
||||||
|
#@file restoreImage
|
||||||
|
#@brief Script de ejemplo para restaurar una imagen.
|
||||||
|
#@param $1 Repositorio (CACHE, REPO o dirección IP)
|
||||||
|
#@param $2 Nombre canónico de la imagen (sin extensión)
|
||||||
|
#@param $3 Número de disco
|
||||||
|
#@param $4 Número de particion
|
||||||
|
#@param $5 Protocolo (UNICAST, UNICAST-DIRECT, MULTICAST o MULTICAST-DIRECT)
|
||||||
|
#@param $6 Opciones del protocolo
|
||||||
|
#@exception OG_ERR_FORMAT 1 formato incorrecto.
|
||||||
|
#@exception OG_ERR_NOTFOUND 2 cambio de repositorio: repositorio no encontrado
|
||||||
|
#@exception OG_ERR_NOTFOUND 2 fichero de imagen o partición no detectados.
|
||||||
|
#@exception $OG_ERR_MCASTRECEIVERFILE 57 Error en la recepción Multicast de un fichero
|
||||||
|
#@exception $OG_ERR_PROTOCOLJOINMASTER 60 Error en la conexión de una sesión Unicast|Multicast con el Master
|
||||||
|
#**/
|
||||||
|
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
|
||||||
|
import ogGlobals
|
||||||
|
import SystemLib
|
||||||
|
import NetLib
|
||||||
|
import StringLib
|
||||||
|
import FileLib
|
||||||
|
import ImageLib
|
||||||
|
import ProtocolLib
|
||||||
|
|
||||||
|
t0 = time.time()
|
||||||
|
prog = os.path.basename (sys.argv[0])
|
||||||
|
|
||||||
|
#Load engine configurator from engine.cfg file.
|
||||||
|
#Carga el configurador del engine desde el fichero engine.cfg
|
||||||
|
# Valores por defecto: #IMGPROG="partclone" ; #IMGCOMP="lzop" ; #IMGEXT="img" #IMGREDUCE="TRUE"
|
||||||
|
## (ogGlobals se encarga)
|
||||||
|
|
||||||
|
# Clear temporary file used as log track by httpdlog
|
||||||
|
# Limpia los ficheros temporales usados como log de seguimiento para httpdlog
|
||||||
|
open (ogGlobals.OGLOGCOMMAND, 'w').close()
|
||||||
|
if SystemLib.ogGetCaller() not in ['deployImage', 'restoreImageCustom']:
|
||||||
|
open (ogGlobals.OGLOGSESSION, 'w').close()
|
||||||
|
|
||||||
|
SystemLib.ogEcho (['log', 'session'], None, f'[1] {ogGlobals.lang.MSG_SCRIPTS_START} {prog} ({sys.argv})')
|
||||||
|
|
||||||
|
# Procesar parámetros de entrada
|
||||||
|
print (f'argv ({sys.argv}) len ({len (sys.argv)})')
|
||||||
|
if len (sys.argv) < 6:
|
||||||
|
SystemLib.ogRaiseError ('session', ogGlobals.OG_ERR_FORMAT, f'{ogGlobals.lang.MSG_FORMAT}: {prog} REPO|CACHE imagen ndisco nparticion [ UNICAST|MULTICAST opciones protocolo]')
|
||||||
|
sys.exit (1)
|
||||||
|
|
||||||
|
_, repo, imgname, disk, par, *other = sys.argv
|
||||||
|
proto = other[0].upper() if len (other) > 0 else 'UNICAST'
|
||||||
|
protoopt = other[1] if len (other) > 1 else ''
|
||||||
|
repo = repo.upper()
|
||||||
|
# Si MCASTWAIT menos que tiempo de espera del servidor lo aumento
|
||||||
|
MCASTWAIT = ogGlobals.MCASTWAIT
|
||||||
|
if ':' in protoopt:
|
||||||
|
port, wait = protoopt.split (':')
|
||||||
|
else:
|
||||||
|
port, wait = ('', '')
|
||||||
|
if proto.startswith ('MULTICAST') and re.match (r'^-?\d+$', wait):
|
||||||
|
if int (MCASTWAIT or 0) < int (wait):
|
||||||
|
MCASTWAIT = int (wait) + 5
|
||||||
|
imgtype = 'img'
|
||||||
|
print (f'repo ({repo}) imgname ({imgname}) disk ({disk}) par ({par}) proto ({proto}) protoopt ({protoopt}) MCASTWAIT ({MCASTWAIT})')
|
||||||
|
|
||||||
|
# Si es una ip y es igual a la del equipo restaura desde cache
|
||||||
|
if repo == NetLib.ogGetIpAddress(): repo = 'CACHE'
|
||||||
|
# Si es una ip y es distinta a la del recurso samba cambiamos de REPO.
|
||||||
|
if StringLib.ogCheckIpAddress (repo) or 'REPO' == repo:
|
||||||
|
# Si falla el cambio -> salimos con error repositorio no valido
|
||||||
|
if not NetLib.ogChangeRepo (repo):
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, repo)
|
||||||
|
sys.exit (1)
|
||||||
|
REPO = 'REPO'
|
||||||
|
|
||||||
|
# Comprobar que existe la imagen del origen.
|
||||||
|
imgfile = FileLib.ogGetPath (repo, f'{imgname}.{imgtype}')
|
||||||
|
imgdir = FileLib.ogGetParentPath (repo, imgname)
|
||||||
|
print (f'imgfile ({imgfile}) imgdir ({imgdir})')
|
||||||
|
if not imgfile or not imgdir:
|
||||||
|
SystemLib.ogRaiseError ('session', ogGlobals.OG_ERR_NOTFOUND, f'{repo}, {imgname}')
|
||||||
|
sys.exit (1)
|
||||||
|
|
||||||
|
# Procesar protocolos de transferencia.
|
||||||
|
retval = 0
|
||||||
|
if proto in ['UNICAST', 'UNICAST-DIRECT']:
|
||||||
|
SystemLib.ogEcho (['log', 'session'], None, f'[40] ogRestoreImage {repo} {imgname} {disk} {par} UNICAST')
|
||||||
|
retval = SystemLib.ogExecAndLog ('command', ImageLib.ogRestoreImage, repo, imgname, disk, par)
|
||||||
|
elif proto in ['MULTICAST', 'MULTICAST-DIRECT']:
|
||||||
|
tool = ImageLib.ogGetImageProgram ('REPO', imgname)
|
||||||
|
if not tool:
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f'could not get tool used for image {imgname}')
|
||||||
|
sys.exit (1)
|
||||||
|
|
||||||
|
compress = ImageLib.ogGetImageCompressor ('REPO', imgname)
|
||||||
|
if not compress:
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f'could not get compressor used for image {imgname}')
|
||||||
|
sys.exit (1)
|
||||||
|
|
||||||
|
SystemLib.ogEcho (['log', 'session'], None, f'[40] ogMcastReceiverPartition {disk} {par} {port} {tool} {compress}')
|
||||||
|
if not ProtocolLib.ogMcastRequest (f'{imgname}.img', protoopt):
|
||||||
|
sys.exit (1)
|
||||||
|
retval = SystemLib.ogExecAndLog ('command', ProtocolLib.ogMcastReceiverPartition, disk, par, port, tool, compress)
|
||||||
|
else:
|
||||||
|
SystemLib.ogRaiseError ('session', ogGlobals.OG_ERR_FORMAT, f'{ogGlobals.lang.MSG_FORMAT}: {prog} REPO|CACHE imagen ndisco nparticion [ UNICAST|MULTICAST opciones protocolo]')
|
||||||
|
sys.exit (1)
|
||||||
|
|
||||||
|
t = time.time() - t0
|
||||||
|
SystemLib.ogEcho (['log', 'session'], None, f'[100] Duracion de la operacion {int (t/60)}m {int (t%60)}s')
|
||||||
|
|
||||||
|
# Código de salida del comando prinicpal de restauración.
|
||||||
|
sys.exit (retval)
|
||||||
|
|
Loading…
Reference in New Issue