refs #1397 add createImage.py, fix bugs

code-review
Natalia Serrano 2025-01-29 12:13:30 +01:00
parent 424248b353
commit 9997e78b31
6 changed files with 209 additions and 11 deletions

View File

@ -509,8 +509,9 @@ def ogMakeDir (container=None, disk=None, par=None, file=None):
print (f'nati: ogMakeDir: parent ({parent})')
if not parent:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found')
return
return None
dst = os.path.basename (file)
print (f'nati: ogMakeDir: dst ({dst})')
os.makedirs (os.path.join (parent, dst), exist_ok=True)
return True

View File

@ -85,7 +85,7 @@ def ogCheckFs (disk, par):
errcode = ogGlobals.OG_ERR_PARTITION
ogUnlock (disk, par)
return errcode
return not errcode ## reverse to indicate success
#/**
@ -133,21 +133,21 @@ def ogExtendFs (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par} {type}')
return
if not prog: return
if not prog: return None
if domount:
PART = ogMount (disk, par)
if not PART: return
if not PART: return None
else:
ogUnmount (disk, par)
if ogIsMounted (disk, par):
SystemLib.ogRaiseError([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}')
return
return None
# Error si el sistema de archivos está bloqueado.
if ogIsLocked (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{disk} {par}')
return
return None
# Redimensionar en modo uso exclusivo.
ogLock (disk, par)

View File

@ -262,7 +262,7 @@ def ogCreateImage (disk, par, container, imgfile, tool='partclone', level='gzip'
FileSystemLib.ogUnlock (disk, par)
ogUnlockImage (container, f'{imgfile}.{imgtype}')
return errcode
return not errcode ## reverse to indicate success
#/**

View File

@ -33,10 +33,10 @@ OGLOGCOMMAND='/tmp/command.log'
#OGWINCHKDISK=True #Hacer chkdisk tras la clonacion
ACTIONCACHEFULL='NONE' #Que hacer cuando la cache no tenga espacio libre. [ NONE | FORMAT ] ]
RESTOREPROTOCOLNOTCACHE=None #Que protocolo de restauracion usar en el caso de que no exista cache o no exista espacio sufiente. [NONE | UNICAST | MULTICAST].NONE retorna error
#IMGPROG='partclone'
#IMGCOMP='lzop'
#IMGEXT='img'
#IMGREDUCE=True
IMGPROG='partclone'
IMGCOMP='lzop'
IMGEXT='img'
IMGREDUCE=True
#OGWINREDUCE=True #Al enviar particion reducir el sistema de archivos previamente.
MCASTERRORSESSION=120 #timeout (segundos) para abortar la sesion de multicast si no contacta con el servidor de multicast. Valor asignado a 0, utiliza los valores por defecto de udp-cast
MCASTWAIT=30 # timeout (segundos) para abortar la la transferencia si se interrumpe. Valor asignado a 0, utiliza los valores por defecto de udp-cast

View File

@ -0,0 +1,197 @@
#!/usr/bin/python3
import os
import sys
import time
import tempfile
import subprocess
import ogGlobals
import SystemLib
import NetLib
import StringLib
import DiskLib
import CacheLib
import FileLib
import PostConfLib
import ImageLib
import FileSystemLib
import InventoryLib
import UEFILib
#/**
#@file createImage
#@brief Scirpt de ejemplo para crear una imagen de un sistema de archivos.
#@brief Se usa como base para el programa de creación de imágenes de OpenGnsys Admin).
#@param 1 disco
#@param 2 particion
#@param 3 REPO|CACHE
#@param 4 imagen
#@return
#@exception OG_ERR_FORMAT # 1 formato incorrecto.
#@exception OG_ERR_PARTITION # 3 Error en partición de disco o en su sistema de archivos
#@exception OG_ERR_IMAGE # 5 Error en funcion ogCreateImage o ogRestoreImage.
#@exception OG_ERR_NOTWRITE # 14 error de escritura
#@exception OG_ERR_NOTCACHE # 15 si cache no existe 15
#@exception OG_ERR_CACHESIZE # 16 si espacio de la cache local o remota no tiene espacio 16
#@exception OG_ERR_REDUCEFS # 17 error al reducir sistema de archivos.
#@exception OG_ERR_EXTENDFS # 18 Errror al expandir el sistema de archivos.
#@note
#@todo: que hacer, si el tamaño de la cache es sufciente, pero no tiene espacio libre
#@todo: que hacer, si hay una imagen con igual nombre en la cache
#*/ ##
# Test 1. crear una imagen en un REPO sin espacio libre.
# test 2. crear una imagen en un REPO en modo solo lectura.
# test 3. intentar crear una imagen en la cache de un equipo que no la disponga.
# test 4. crear una imagen en la Cache sin espacio sufiente.
# test 5. intentar crear una imagen, en la que no se puede reducir el FS.
prog = os.path.basename (sys.argv[0])
def main (disk, par, repo, imgname):
time1 = time.time()
imgext = getattr (ogGlobals, 'IMGEXT')
if not imgext: imgext = 'img'
repo = repo.upper()
#Load engine configurator from engine.cfg file.
#Carga el configurador del engine desde el fichero engine.cfg
# Valores por defecto en etc/engine.cfg
# Clear temporary file used as log track by httpdlog
# Limpia los ficheros temporales usados como log de seguimiento para httpdlog
# salvo si es llamado desde createImageCustom
if 'createImageCustom' != SystemLib.ogGetCaller():
with open (ogGlobals.OGLOGSESSION, 'w') as fd: fd.write ('')
with open (ogGlobals.OGLOGCOMMAND, 'w') as fd: fd.write ('')
with open (f'{ogGlobals.OGLOGCOMMAND}.tmp', 'w') as fd: fd.write ('')
SystemLib.ogEcho (['log', 'session'], None, f'[1] {ogGlobals.lang.MSG_SCRIPTS_START} {" ".join(sys.argv)}')
# Si es una ip y es igual a la del equipo restaura desde cache
if NetLib.ogGetIpAddress() == repo:
repo = 'CACHE'
if StringLib.ogCheckIpAddress (repo) or 'REPO' == repo:
if not NetLib.ogChangeRepo (repo):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, repo)
sys.exit (1)
repo = 'REPO'
# Si el repositorio es CACHE comprobamos que exista
if 'CACHE' == repo:
if not CacheLib.ogFindCache():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTCACHE, 'CACHE')
sys.exit (1)
# Obtener información de los parámetros de entrada.
PART = DiskLib.ogDiskToDev (disk, par)
if not PART:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}')
sys.exit (1)
#Comprobamos acceso de escritura.
dirtemp = time.strftime ('%Y%m%d-%H%M%S', time.gmtime())
if not FileLib.ogMakeDir (container=repo, file=f'/{imgname}{dirtemp}'):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTWRITE, repo)
FileLib.ogDeleteTree (repo, f'/{imgname}{dirtemp}')
sys.exit (1)
imgdir = FileLib.ogGetParentPath (src=repo, file=f'/{imgname}')
if not imgdir:
dn = os.path.dirname (f'/{imgname}')
SystemLib.ogEcho (['log', 'session'], None, f'[5] {ogGlobals.lang.MSG_HELP_ogMakeDir} "{repo} {dn}"')
if not FileLib.ogMakeDir (container=repo, file=dn):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTWRITE, f'{repo} /{imgname}')
sys.exit (1)
imgdir = FileLib.ogGetParentPath (src=repo, file=f'/{imgmame}')
if not imgdir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTWRITE, f'{repo} /{imgname}')
sys.exit (1)
bn = os.path.basename (f'/{imgname}')
imgfile = f'{imgdir}/{bn}.{imgext}'
with open (ogGlobals.OGLOGCOMMAND, 'w') as fd: fd.write ('')
PostConfLib.ogCleanOs (disk, par)
#Comprobar espacio que requerira la imagen para ser almacenada
sizedata, sizerequired, sizefree, isenoughspace = ImageLib.ogGetSizeParameters (disk, par, repo, imgname)
SystemLib.ogEcho (['log', 'session'], None, f'[16] {prog} {ogGlobals.lang.MSG_SCRIPTS_CREATE_SIZE} {sizerequired} {sizefree}')
if not isenoughspace:
SystemLib.ogRaiseError ('session', ogGlobals.OG_ERR_CACHESIZE, repo)
sys.exit (1)
# Comprobar consistencia del sistema de archivos.
with open (ogGlobals.OGLOGCOMMAND, 'w') as fd: fd.write ('')
sizefs = FileSystemLib.ogGetFsSize (disk, par)
SystemLib.ogEcho (['log', 'session'], None, f'[20] {ogGlobals.lang.MSG_HELP_ogCheckFs} {par} {sizefs} (KB)')
FileSystemLib.ogUnmount (disk, par)
if not FileSystemLib.ogCheckFs (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'ogCheckFs {disk} {par}')
sys.exit (1)
# Si es UEFI copio el cargador de arranque a la partición
ostype = InventoryLib.ogGetOsType (disk, par)
if InventoryLib.ogIsEfiActive() and 'Windows' == ostype:
SystemLib.ogEcho (['log', 'session'], None, f'[25] {ogGlobals.lang.MSG_HELP_ogCopyEfiBootLoader}')
UEFILib.ogCopyEfiBootLoader (disk, par)
# Evaluar variable de engine.cfg para reducir el sistema de archivos en la creacion
if ogGlobals.IMGREDUCE:
SystemLib.ogEcho (['log', 'session'], None, f'[30] {ogGlobals.lang.MSG_HELP_ogReduceFs}')
FileSystemLib.ogReduceFs (disk, par)
newsizefs = FileSystemLib.ogGetFsSize (disk, par)
timeaux = time.time() - time1
SystemLib.ogEcho (['log', 'session'], None, f' {ogGlobals.lang.MSG_SCRIPTS_TIME_PARTIAL} ( {newsizefs} KB ) : {int (timeaux/60)}m {int (timeaux%60)}s')
# Renombrar el fichero de imagen si ya existe.
if os.path.exists (imgfile):
SystemLib.ogEcho (['log', 'session'], None, f'[35] {ogGlobals.lang.MSG_SCRIPTS_FILE_RENAME} "{imgfile}" -> "{imgfile}.ant".')
os.rename (imgfile, f'{imgfile}.ant')
if os.path.exists (f'{imgfile}.torrent'): os.rename (f'{imgfile}.torrent', f'{imgfile}.torrent.ant')
if os.path.exists (f'{imgfile}.sum'): os.rename (f'{imgfile}.sum', f'{imgfile}.sum.ant')
if os.path.exists (f'{imgfile}.full.sum'): os.rename (f'{imgfile}.full.sum', f'{imgfile}.full.sum.ant')
# Crear la imagen.
with open (ogGlobals.OGLOGCOMMAND, 'w') as fd: fd.write ('')
time2 = time.time()
SystemLib.ogEcho (['log', 'session'], None, f'[40] {ogGlobals.lang.MSG_HELP_ogCreateImage} : ogCreateImage {disk} {par} {repo} {imgname} {ogGlobals.IMGPROG} {ogGlobals.IMGCOMP}')
if not ImageLib.ogCreateImage (disk, par, repo, f'/{imgname}', ogGlobals.IMGPROG, ogGlobals.IMGCOMP):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, 'ogCreateImage')
sys.exit (1)
resumecreateimage = subprocess.run (['grep', 'Total Time:', ogGlobals.OGLOGCOMMAND], capture_output=True, text=True).stdout
timeaux2 = time.time() - time2
SystemLib.ogEcho (['log', 'session'], None, f' {resumecreateimage} ')
SystemLib.ogEcho (['log', 'session'], None, f' {ogGlobals.lang.MSG_SCRIPTS_TIME_PARTIAL} : {int (timeaux2/60)}m {int (timeaux2%60)}s')
# Extender sistema de archivos
time3 = time.time()
SystemLib.ogEcho (['log', 'session'], None, f'[90] Extender sistema de archivos.')
if not FileSystemLib.ogExtendFs (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_EXTENDFS, f'{disk} {par}')
sys.exit (1)
sizefs2 = FileSystemLib.ogGetFsSize (disk, par)
timeaux3 = time.time() - time3
SystemLib.ogEcho (['log', 'session'], None, f' {ogGlobals.lang.MSG_HELP_ogExtendFs} {newsizefs} -> {sizefs} = {sizefs2}: {int (timeaux3/60)}m {int (timeaux3%60)}s')
#TODO que hacer si error al extender sistemade archivos
#resumen de la operacion
p = FileLib.ogGetPath (src=repo, file=f'/{imgname}.{imgext}')
ls_out = subprocess.run (['ls', '-s', p], capture_output=True, text=True).stdout
imgsize = ls_out.split()[0]
imgos = ImageLib.ogGetImageInfo (p)
t = time.time() - time1
SystemLib.ogEcho (['log', 'session'], None, f'[100] {ogGlobals.lang.MSG_SCRIPTS_TIME_TOTAL} {int (t/60)}m {int (t%60)}s')
SystemLib.ogEcho (['log', 'session'], None, f' FileSystem {PART} with {newsizefs} KB data created onto file-image as {imgname} and used {imgsize} KB')
SystemLib.ogEcho (['log', 'session'], None, f' Image-file {imgname} metadata: {imgos}')
if __name__ == '__main__':
if 5 != len (sys.argv):
SystemLib.ogRaiseError ('session', ogGlobals.OG_ERR_FORMAT, f'{ogGlobals.lang.MSG_FORMAT}: {prog} ndisco nparticion REPO|CACHE imagen')
sys.exit (1)
main (*sys.argv[1:])