refs #1150 add restoreImage.py
parent
b755de21be
commit
b71e631fb1
|
@ -8,6 +8,7 @@ from pathlib import Path
|
|||
import ogGlobals
|
||||
import SystemLib
|
||||
import CacheLib
|
||||
import FileSystemLib
|
||||
|
||||
def parted(*args):
|
||||
parted_path = shutil.which("parted")
|
||||
|
@ -707,32 +708,28 @@ def ogGetPartitionId(*args):
|
|||
print(ID)
|
||||
return
|
||||
|
||||
def ogGetPartitionSize(*args):
|
||||
# Variables locales
|
||||
PART = None
|
||||
SIZE = None
|
||||
|
||||
# Si se solicita, mostrar ayuda.
|
||||
if len(args) == 1 and args[0] == "help":
|
||||
SystemLib.ogHelp('ogGetPartitionSize', 'ogGetPartitionSize int_ndisk int_npartition', 'ogGetPartitionSize 1 1 => 10000000')
|
||||
return
|
||||
#/**
|
||||
# ogGetPartitionSize int_ndisk int_npartition
|
||||
#@brief Muestra el tamano en KB de una particion determinada.
|
||||
#@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.
|
||||
if len(args) != 2:
|
||||
SystemLib.ogRaiseError(OG_ERR_FORMAT)
|
||||
return
|
||||
sz = subprocess.run (['partx', '-gbo', 'SIZE', PART], capture_output=True, text=True).stdout.strip()
|
||||
if sz: return int (int (sz) / 1024)
|
||||
|
||||
# Devolver tamaño de partición, del volumen lógico o del sistema de archivos (para ZFS).
|
||||
PART = ogDiskToDev(args[0], args[1])
|
||||
if PART is None:
|
||||
return
|
||||
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
|
||||
sz = subprocess.run (['lvs', '--noheadings', '-o', 'lv_size', '--units', 'k', PART], capture_output=True, text=True).stdout.strip
|
||||
if sz: return int (sz)
|
||||
|
||||
return FileSystemLib.ogGetFsSize (disk, par)
|
||||
|
||||
def ogGetPartitionsNumber(*args):
|
||||
# Variables locales
|
||||
|
|
|
@ -6,6 +6,7 @@ import ogGlobals
|
|||
import SystemLib
|
||||
import DiskLib
|
||||
import CacheLib
|
||||
import FileSystemLib
|
||||
|
||||
def ogCheckFs(int_ndisk, int_nfilesys):
|
||||
# Si se solicita, mostrar ayuda.
|
||||
|
@ -171,170 +172,144 @@ def ogExtendFs():
|
|||
ogUnlock(int(sys.argv[1]), int(sys.argv[2]))
|
||||
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:
|
||||
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":
|
||||
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\"")
|
||||
|
||||
#/**
|
||||
# ogFormatFs int_ndisk int_nfilesys [type_fstype] [str_label]
|
||||
#@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
|
||||
|
||||
# Error si no se reciben entre 2 y 4 parámetros.
|
||||
if not (2 <= len(sys.argv) <= 4):
|
||||
ogRaiseError(OG_ERR_FORMAT)
|
||||
d = data[type]
|
||||
prog = d['PROG']
|
||||
params = d['PARAMS'] if 'PARAMS' in d else ''
|
||||
labelparam = d['LABELPARAM'] if 'LABELPARAM' in d else ''
|
||||
input = d['INPUT'] if 'INPUT' in d else ''
|
||||
|
||||
if label == "CACHE":
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f"{ogGlobals.lang.MSG_RESERVEDVALUE}: CACHE")
|
||||
return
|
||||
if label:
|
||||
params = f"{params} {labelparam or '-L'} {label}"
|
||||
|
||||
# Obtener fichero de dispositivo.
|
||||
PART = ogDiskToDev(int_ndisk, int_nfilesys)
|
||||
if not PART:
|
||||
return
|
||||
|
||||
# Error si la partición está montada o bloqueada.
|
||||
if ogIsMounted(int_ndisk, int_nfilesys):
|
||||
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)
|
||||
ogLock (disk, par)
|
||||
subprocess.run (['umount', PART])
|
||||
try:
|
||||
subprocess.run([PROG, PARAMS, PART], capture_output=True)
|
||||
ERRCODE = 0
|
||||
if input:
|
||||
errcode = subprocess.run ([prog, params, PART])
|
||||
else:
|
||||
errcode = subprocess.run ([prog, params, PART], input=input, text=True)
|
||||
except FileNotFoundError:
|
||||
ogRaiseError(OG_ERR_NOTEXEC, PROG)
|
||||
ERRCODE = OG_ERR_NOTEXEC
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTEXEC, prog)
|
||||
errcode = ogGlobals.OG_ERR_NOTEXEC
|
||||
except:
|
||||
ogRaiseError(OG_ERR_PARTITION, f"{int_ndisk} {int_nfilesys}")
|
||||
ERRCODE = OG_ERR_PARTITION
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk} {par}")
|
||||
errcode = ogGlobals.OG_ERR_PARTITION
|
||||
|
||||
ogUnlock(int_ndisk, int_nfilesys)
|
||||
return ERRCODE
|
||||
ogUnlock (disk, par)
|
||||
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):
|
||||
ogRaiseError(OG_ERR_FORMAT)
|
||||
return
|
||||
#/**
|
||||
# ogGetFsSize int_ndisk int_npartition [str_unit]
|
||||
#@brief Muestra el tamanio del sistema de archivos indicado, permite definir la unidad de medida, por defecto GB
|
||||
#@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.
|
||||
UNIT = str_unit or "KB"
|
||||
FACTOR = 1
|
||||
if UNIT.upper() == "MB":
|
||||
FACTOR = 1024
|
||||
elif UNIT.upper() == "GB":
|
||||
FACTOR = 1024 * 1024
|
||||
elif UNIT.upper() == "TB":
|
||||
FACTOR = 1024 * 1024 * 1024
|
||||
elif UNIT.upper() != "KB":
|
||||
ogRaiseError(OG_ERR_FORMAT, f"{UNIT} != {{ KB, MB, GB, TB }}")
|
||||
def ogGetFsSize (disk, par, unit=None):
|
||||
u = unit or "KB"
|
||||
factor = 1
|
||||
if u.upper() == "MB":
|
||||
factor = 1024
|
||||
elif u.upper() == "GB":
|
||||
factor = 1024 * 1024
|
||||
elif u.upper() == "TB":
|
||||
factor = 1024 * 1024 * 1024
|
||||
elif u.upper() != "KB":
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f"{unit} != {{ KB, MB, GB, TB }}")
|
||||
return
|
||||
|
||||
# Obtener el tamaño del sistema de archivo (si no está formateado; tamaño = 0).
|
||||
MNTDIR = ogMount(int_ndisk, int_npartition)
|
||||
if MNTDIR:
|
||||
result = subprocess.run(["df", "-BK", MNTDIR], capture_output=True, text=True)
|
||||
VALUE = result.stdout.split("\n")[1].split()[1]
|
||||
SIZE = float(VALUE) / FACTOR
|
||||
mnt = FileSystemLib.ogMount (disk, par)
|
||||
if mnt:
|
||||
result = subprocess.run(["df", "-BK", mnt], capture_output=True, text=True)
|
||||
val = result.stdout.split("\n")[1].split()[1]
|
||||
val = val.replace ('K', '')
|
||||
sz = int (val) / factor
|
||||
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
|
||||
|
@ -461,26 +436,24 @@ def ogIsLocked(disk, par):
|
|||
def ogIsPartitionLocked(disk, par):
|
||||
DISK = DiskLib.ogDiskToDev(disk)
|
||||
PART = DiskLib.ogDiskToDev(disk, par)
|
||||
print (f'nati: ogIsPartitionLocked: DISK ({DISK}) PART ({PART})')
|
||||
if not PART: return
|
||||
|
||||
LOCKDISK = f"/var/lock/lock{DISK.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.
|
||||
if len(sys.argv) == 3 and sys.argv[2] == "help":
|
||||
ogHelp("ogIsMounted", "ogIsMounted int_ndisk int_nfilesys", "ogIsMounted 1 1")
|
||||
return
|
||||
|
||||
# Error si no se reciben 2 parámetros.
|
||||
if len(sys.argv) != 3:
|
||||
ogRaiseError(OG_ERR_FORMAT)
|
||||
return
|
||||
|
||||
# Obtener punto de montaje.
|
||||
MNTDIR = ogGetMountPoint(int_ndisk, int_nfilesys)
|
||||
return bool(MNTDIR)
|
||||
#/**
|
||||
# ogIsMounted int_ndisk int_nfilesys
|
||||
#@brief Comprueba si un sistema de archivos está montado.
|
||||
#@param int_ndisk nº de orden del disco
|
||||
#@param int_nfilesys nº de orden del sistema de archivos
|
||||
#@return Código de salida: 0 - montado, 1 - sin montar o error.
|
||||
#*/ ##
|
||||
def ogIsMounted (disk, par):
|
||||
return bool (ogGetMountPoint (disk, par))
|
||||
|
||||
|
||||
#/**
|
||||
|
@ -523,28 +496,31 @@ def ogIsWritable(int_ndisk, int_nfilesys):
|
|||
options = result.stdout.strip().split(",")
|
||||
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.
|
||||
if len(sys.argv) == 3 and sys.argv[2] == "help":
|
||||
ogHelp("ogLockPartition", "ogLockPartition int_ndisk int_npartition", "ogLockPartition 1 1")
|
||||
return
|
||||
#/**
|
||||
# ogLock int_ndisk int_npartition
|
||||
#@see ogLockPartition
|
||||
#*/
|
||||
def ogLock(disk, par):
|
||||
return ogLockPartition(disk, par)
|
||||
|
||||
# Error si no se reciben 2 parámetros.
|
||||
if len(sys.argv) != 3:
|
||||
ogRaiseError(OG_ERR_FORMAT)
|
||||
return
|
||||
#/**
|
||||
# ogLockPartition int_ndisk int_npartition
|
||||
#@brief Genera un fichero de bloqueo para una partición en uso exlusivo.
|
||||
#@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('/', '-')}"
|
||||
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_PARTITION Tipo de particion desconocido o no se puede montar.
|
||||
#*/ ##
|
||||
|
||||
def ogMountFs (disk, par):
|
||||
dev = DiskLib.ogDiskToDev (disk, par)
|
||||
if not dev: return
|
||||
|
@ -589,6 +564,7 @@ def ogMountFs (disk, par):
|
|||
if mntdir: return mntdir
|
||||
|
||||
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}")
|
||||
return
|
||||
|
||||
|
@ -727,26 +703,28 @@ def ogReduceFs(int_ndisk, int_nfilesys):
|
|||
# Devuelve tamaño del sistema de ficheros.
|
||||
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.
|
||||
if len(sys.argv) == 3 and sys.argv[2] == "help":
|
||||
ogHelp("ogUnlockPartition", "ogUnlockPartition int_ndisk int_npartition", "ogUnlockPartition 1 1")
|
||||
return
|
||||
#/**
|
||||
# ogUnlock int_ndisk int_npartition
|
||||
#@see ogUnlockPartition
|
||||
#*/ ##
|
||||
def ogUnlock (disk, par):
|
||||
return ogUnlockPartition (disk, par)
|
||||
|
||||
# Error si no se reciben 2 parámetros.
|
||||
if len(sys.argv) != 3:
|
||||
ogRaiseError(OG_ERR_FORMAT)
|
||||
return
|
||||
#/**
|
||||
# ogUnlockPartition int_ndisk int_npartition
|
||||
#@brief Elimina el fichero de bloqueo para una particion.
|
||||
#@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('/', '-')}"
|
||||
os.remove(LOCKFILE)
|
||||
|
||||
|
@ -756,7 +734,7 @@ def ogUnlockPartition(int_ndisk, int_npartition):
|
|||
#@see ogUnmountFs
|
||||
#*/ ##
|
||||
def ogUnmount (disk, par):
|
||||
ogUnmountFs (disk, par)
|
||||
return ogUnmountFs (disk, par)
|
||||
|
||||
#/**
|
||||
# ogUnmountFs int_ndisk int_nfilesys
|
||||
|
@ -793,8 +771,10 @@ def ogUnmountFs(disk, par):
|
|||
os.remove(MNTDIR)
|
||||
except:
|
||||
pass
|
||||
return True
|
||||
else:
|
||||
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 }
|
||||
#@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.
|
||||
#@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
|
||||
#*/ ##
|
||||
|
||||
#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
|
||||
|
@ -529,6 +610,15 @@ def ogGetImageInfo (imgfile):
|
|||
#@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
|
||||
|
@ -544,7 +634,7 @@ def ogGetImageInfo (imgfile):
|
|||
#ogGetImageType ('REPO', 'imgprueba') ==> 'NTFS'
|
||||
#ogGetImageType ('CACHE', 'testimg') ==> 'EXTFS'
|
||||
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):
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
|
||||
return None
|
||||
|
@ -565,6 +655,15 @@ def ogGetImageType (repo, imgname):
|
|||
#@exception OG_ERR_NOTFOUND fichero no encontrado.
|
||||
#@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:
|
||||
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()
|
||||
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)
|
||||
|
||||
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()
|
||||
if not _ogConnect (new_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(
|
||||
["session", "log"],
|
||||
'info',
|
||||
None,
|
||||
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
|
||||
#*/ ##
|
||||
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:
|
||||
IP = os.environ["IPV4ADDR"]
|
||||
else:
|
||||
# Obtener direcciones IP.
|
||||
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()
|
||||
else:
|
||||
IP = subprocess.run(["ip", "-o", "address", "show", "up"], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.decode().split()
|
||||
ip = os.environ["IPV4ADDR"]
|
||||
if '/' in ip: ip = ip.split ('/')[0]
|
||||
return ip
|
||||
|
||||
IP = [addr.split("/")[0] for addr in IP if "inet" in addr]
|
||||
extra_args = []
|
||||
if "DEVICE" in os.environ:
|
||||
extra_args = [ "dev", os.environ["DEVICE"] ]
|
||||
ipas = subprocess.run (['ip', '-json', 'address', 'show', 'up'] + extra_args, capture_output=True, text=True).stdout
|
||||
|
||||
# Mostrar solo la primera.
|
||||
if IP:
|
||||
print(IP[0])
|
||||
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'] })
|
||||
|
||||
if 1 != len (addresses):
|
||||
raise Exception ('more than one local IP address found')
|
||||
return addresses[0]
|
||||
|
||||
return 0
|
||||
|
||||
#/**
|
||||
# ogGetMacAddress
|
||||
|
|
|
@ -246,9 +246,6 @@ def _clientip():
|
|||
addresses = []
|
||||
for e in ipasj:
|
||||
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
|
||||
addrs = e['addr_info']
|
||||
for a in addrs:
|
||||
|
@ -642,7 +639,7 @@ def ogMcastReceiverPartition (disk, par, sess, tool, compressor):
|
|||
#*/ ##
|
||||
## now ogCore takes this responsibility
|
||||
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:
|
||||
print ('Donwloading Torrent as peer')
|
||||
# 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
|
||||
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:
|
||||
|
@ -763,7 +760,7 @@ def ogTorrentStart (disk=None, par=None, container=None, torrentfile=None, torre
|
|||
elif 'seeder' == mode:
|
||||
print ('MODE seeder ctorrent')
|
||||
# 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
|
||||
subprocess.run (['ctorrent', '-f', '-c', '-X', f'sleep {time}; kill -2 $(pidof ctorrent)', '-C', '100', source, '-s', target, '-b', f'{source}.bfog'])
|
||||
else:
|
||||
|
|
|
@ -2,10 +2,14 @@ import subprocess
|
|||
import datetime
|
||||
from zoneinfo import ZoneInfo
|
||||
import sys
|
||||
import os
|
||||
import os
|
||||
import shutil
|
||||
import inspect
|
||||
|
||||
## for ogExecAndLog
|
||||
from io import StringIO
|
||||
from contextlib import redirect_stdout, redirect_stderr
|
||||
|
||||
import ogGlobals
|
||||
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
|
||||
|
||||
def _logtype2logfile (t):
|
||||
if 'log' == t: return ogGlobals.OGLOGFILE
|
||||
elif 'command' == t: return ogGlobals.OGLOGCOMMAND
|
||||
elif 'session' == t: return ogGlobals.OGLOGSESSION
|
||||
if 'log' == t.lower(): return ogGlobals.OGLOGFILE
|
||||
elif 'command' == t.lower(): return ogGlobals.OGLOGCOMMAND
|
||||
elif 'session' == t.lower(): return ogGlobals.OGLOGSESSION
|
||||
else: raise Exception (f'unknown log type ({t})')
|
||||
#/**
|
||||
# ogEcho [str_logtype ...] [str_loglevel] "str_message" ...
|
||||
|
@ -51,58 +55,88 @@ def ogEcho (logtypes, loglevel, msg):
|
|||
else:
|
||||
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":
|
||||
ogHelp(f"{FUNCNAME} str_logfile ... str_command ...",
|
||||
f"{FUNCNAME} COMMAND ls -al /")
|
||||
#/**
|
||||
# ogExecAndLog str_logfile ... str_command ...
|
||||
#@brief Ejecuta un comando y guarda su salida en fichero de registro.
|
||||
#@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
|
||||
|
||||
# Procesar parámetros.
|
||||
while CONTINUE:
|
||||
arg = args.pop(0).lower()
|
||||
if arg == "command":
|
||||
ISCOMMAND = True
|
||||
continue
|
||||
elif arg == "log":
|
||||
ISLOG = True
|
||||
continue
|
||||
elif arg == "session":
|
||||
ISSESSION = True
|
||||
continue
|
||||
else:
|
||||
COMMAND = " ".join(args)
|
||||
CONTINUE = 0
|
||||
## the original bash code does something like this:
|
||||
#if [ $ISCOMMAND ]; then
|
||||
# > $OGLOGCOMMAND
|
||||
# REDIREC="2>&1"
|
||||
#fi
|
||||
#eval $COMMAND $REDIREC | tee -a $FILES
|
||||
|
||||
# Error si no se recibe un comando que ejecutar.
|
||||
if not COMMAND:
|
||||
ogRaiseError(OG_ERR_FORMAT)
|
||||
return
|
||||
## a hybrid bash/python pseudocode would end up being like the following:
|
||||
#if 'command' in logtypes:
|
||||
# rm $OGLOGCOMMAND
|
||||
# touch $OGLOGCOMMAND
|
||||
#
|
||||
#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
|
||||
|
||||
# Componer lista de ficheros de registro.
|
||||
if ISCOMMAND:
|
||||
FILES = OGLOGCOMMAND
|
||||
open(FILES, "w").close()
|
||||
REDIREC = "2>&1"
|
||||
if ISLOG:
|
||||
FILES += " " + OGLOGFILE
|
||||
if ISSESSION:
|
||||
FILES += " " + OGLOGSESSION
|
||||
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:
|
||||
print ('nati: ogExecAndLog: about to redirect stdout only')
|
||||
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
|
||||
|
||||
# Ejecutar comando.
|
||||
subprocess.call(f"{COMMAND} {REDIREC} | tee -a {FILES}", shell=True)
|
||||
# Salida de error del comando ejecutado.
|
||||
return subprocess.PIPESTATUS[0]
|
||||
if sout or serr:
|
||||
print ('nati: ogExecAndLog: sout or serr are true')
|
||||
time.sleep (1) ## nati
|
||||
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")
|
||||
|
||||
print (f'nati: ogExecAndLog: returning rc ({rc})')
|
||||
return rc
|
||||
|
||||
#/**
|
||||
# ogGetCaller
|
||||
|
@ -211,14 +245,14 @@ def ogRaiseError (logtypes, code, msg):
|
|||
CODE = ogGlobals.OG_ERR_GENERIC
|
||||
|
||||
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(0) ## remove 'ogRaiseError'
|
||||
str_call_stack = ' '.join (call_stack)
|
||||
|
||||
if code == ogGlobals.OG_ERR_FORMAT 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}")
|
||||
|
||||
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