282 lines
11 KiB
Python
282 lines
11 KiB
Python
#!/usr/bin/python3
|
|
|
|
import os
|
|
import sys
|
|
|
|
import ogGlobals
|
|
import SystemLib
|
|
import CacheLib
|
|
import FileSystemLib
|
|
import DiskLib
|
|
import InventoryLib
|
|
|
|
#Load engine configurator from engine.cfg file.
|
|
#Carga el configurador del engine desde el fichero engine.cfg
|
|
## (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.OGLOGSESSION, 'w').close()
|
|
open (ogGlobals.OGLOGCOMMAND, 'w').close()
|
|
open (ogGlobals.OGLOGCOMMAND+'.tmp', 'w').close()
|
|
|
|
# Registro de inicio de ejecución
|
|
SystemLib.ogEcho (['log', 'session'], None, f'{ogGlobals.lang.MSG_INTERFACE_START} {sys.argv}')
|
|
|
|
# Solo ejecutable por OpenGnsys Client.
|
|
#path = os.getenv('PATH')
|
|
#if path:
|
|
# os.environ['PATH'] = f"{path}:{os.path.dirname(__name__)}"
|
|
prog = os.path.basename(__name__)
|
|
|
|
#____________________________________________________________________
|
|
#
|
|
# El parámetro $2 es el que aporta toda la información y el $1 se queda obsoleto
|
|
# Formato de entrada:
|
|
# dis=Número de disco
|
|
# != caracter de separación
|
|
#
|
|
# Y un numero indeterminado de cadenas del tipo siguuenteseparadas por el caracter '$':
|
|
# par=Número de particion*cod=Código de partición*sfi=Sistema de ficheros*tam=Tamaño de la partición*ope=Operación
|
|
# @= caracter de separación
|
|
#____________________________________________________________________
|
|
|
|
# Captura de parámetros (se ignora el 1er parámetro y se eliminan espacios y tabuladores).
|
|
#param='dis=1!par=1*cpt=NTFS*sfi=NTFS*tam=11000000*ope=0%'
|
|
#param = ''.join(sys.argv[2:]).replace(' ', '').replace('\t', '')
|
|
param = sys.argv[2]
|
|
|
|
# Leer los dos bloques de parámetros, separados por '!'.
|
|
tbprm = param.split ('!')
|
|
pparam = tbprm[0] # General disk parameters
|
|
sparam = tbprm[1] # Partitioning and formatting parameters
|
|
is_there_cache = 'CACHE' in sparam
|
|
|
|
# Toma valores de disco y caché, separados por "*".
|
|
# Los valores están en las variables $dis: disco, $che: existe cache (1, 0), $tch: Tamaño de la cache.
|
|
pparams = pparam.split ('*')
|
|
dis = tch = None
|
|
for item in pparams:
|
|
if '=' not in item: continue
|
|
|
|
k, v = item.split ('=', 1)
|
|
if k not in ['dis']:
|
|
print (f'ignoring unknown disk parameter ({k})')
|
|
continue
|
|
|
|
if 'dis' == k: dis = int (v)
|
|
|
|
# Error si no se define el parámetro de disco (dis).
|
|
if dis is None:
|
|
sys.exit (ogGlobals.OG_ERR_FORMAT)
|
|
|
|
# Toma valores de distribución de particiones, separados por "%".
|
|
tbp = [] # Valores de configuración (parámetros para ogCreatePartitions)
|
|
tbf = {} # Tabla de formateo
|
|
|
|
sparams = sparam.split('%')
|
|
|
|
maxp=0
|
|
sum_tam = 0
|
|
do_sum_tam = True
|
|
cache_seen = extended_seen = efi_seen = False
|
|
for item in sparams:
|
|
if not item: continue ## por si nos pasan un '%' al final de todo
|
|
# Leer datos de la partición, separados por "*".
|
|
par = cpt = sfi = tam = None
|
|
ope = 0
|
|
for c in item.split ('*'):
|
|
if '=' not in c: continue
|
|
|
|
k, v = c.split ('=', 1)
|
|
if k not in ['par', 'cpt', 'sfi', 'tam', 'ope']:
|
|
print (f'ignoring unknown partition parameter ({k})')
|
|
continue
|
|
|
|
if 'par' == k: par = int (v)
|
|
elif 'cpt' == k: cpt = v
|
|
elif 'sfi' == k: sfi = v
|
|
elif 'tam' == k: tam = int (v)
|
|
elif 'ope' == k: ope = int (v)
|
|
|
|
missing_params = []
|
|
if par is None or 'None' == par: missing_params.append ('par')
|
|
if cpt is None or 'None' == cpt: missing_params.append ('cpt')
|
|
if sfi is None or 'None' == sfi: missing_params.append ('sfi')
|
|
if tam is None or 'None' == tam: missing_params.append ('tam')
|
|
if missing_params:
|
|
print (f'partition data ({item}) missing required parameters ({' '.join (missing_params)})')
|
|
sys.exit (1)
|
|
|
|
# Componer datos de particionado.
|
|
if 'EFI' == cpt:
|
|
if efi_seen:
|
|
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_FORMAT, f'se ha solicitado más de una partición de ESP')
|
|
sys.exit (1)
|
|
efi_seen = True
|
|
if 'CACHE' == cpt:
|
|
if cache_seen:
|
|
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_FORMAT, f'se ha solicitado más de una partición de cache')
|
|
sys.exit (1)
|
|
cache_seen = True
|
|
tch = tam
|
|
else:
|
|
tbp.append (f'{cpt}:{tam}')
|
|
if do_sum_tam:
|
|
sum_tam += tam
|
|
if 'EXTENDED' == cpt:
|
|
if extended_seen:
|
|
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_FORMAT, f'se ha solicitado más de una partición extendida')
|
|
sys.exit (1)
|
|
extended_seen = True
|
|
extended_is_at = par
|
|
do_sum_tam = False ## don't sum sizes anymore
|
|
|
|
if ope:
|
|
# Si se activa operación de formatear, componer datos de formateo.
|
|
if cpt not in ['EMPTY', 'EXTENDED', 'LINUX-LVM', 'LVM', 'ZPOOL']:
|
|
tbf[par] = sfi
|
|
# Obtener la partición mayor.
|
|
if par > maxp: maxp = par
|
|
|
|
if tch is None:
|
|
tch = 0
|
|
|
|
|
|
|
|
|
|
cur_ptt = DiskLib.ogGetPartitionTableType (dis)
|
|
ptt = 'GPT' if InventoryLib.ogIsEfiActive() else 'MSDOS'
|
|
|
|
if not cache_seen and not tbp:
|
|
SystemLib.ogRaiseError (['session', 'log'], ogGlobals.OG_ERR_FORMAT, f'No se ha solicitado ninguna partición')
|
|
sys.exit (1)
|
|
|
|
if 'GPT' == ptt and extended_seen:
|
|
SystemLib.ogRaiseError (['session', 'log'], ogGlobals.OG_ERR_FORMAT, f'En GPT no se pueden usar particiones extendidas')
|
|
sys.exit (1)
|
|
|
|
## error si nos piden más de 4 y ninguna es extendida
|
|
if 'MSDOS' == ptt and not extended_seen:
|
|
requested_partitions = len (tbp)
|
|
if cache_seen: requested_partitions += 1
|
|
if requested_partitions > 4:
|
|
SystemLib.ogRaiseError (['session', 'log'], ogGlobals.OG_ERR_FORMAT, f'Se han solicitado más de 4 particiones y ninguna es extendida')
|
|
sys.exit (1)
|
|
|
|
if efi_seen:
|
|
if 'EFI' != tbp[0].split (':')[0]:
|
|
SystemLib.ogRaiseError (['session', 'log'], ogGlobals.OG_ERR_FORMAT, f'la partición ESP debe estar declarada en primera posición')
|
|
sys.exit (1)
|
|
else:
|
|
if 'GPT' == ptt and 1 == dis:
|
|
SystemLib.ogRaiseError (['session', 'log'], ogGlobals.OG_ERR_FORMAT, f'En GPT debe haber una partición ESP')
|
|
sys.exit (1)
|
|
|
|
## si no nos definen partición de cache y el disco tiene una, hay que borrarla
|
|
if not cache_seen:
|
|
c = CacheLib.ogFindCache()
|
|
if c:
|
|
cache_disk, cache_part = c.split()
|
|
if int (cache_disk) == int (dis):
|
|
CacheLib.ogUnmountCache()
|
|
CacheLib.ogDeleteCache()
|
|
|
|
## la extendida solo puede estar en la (si hay cache) o en la 4 (si no lo hay)
|
|
if extended_seen:
|
|
extended_should_be_at = 3 if cache_seen else 4
|
|
if extended_is_at != extended_should_be_at:
|
|
SystemLib.ogRaiseError (['session', 'log'], ogGlobals.OG_ERR_FORMAT, f'La partición extendida no puede ser la "{extended_is_at}" sino que debe ser la "{extended_should_be_at}"')
|
|
sys.exit (1)
|
|
|
|
recreate_partition_table = False
|
|
if not cur_ptt:
|
|
SystemLib.ogEcho (['session', 'log'], None, f'No partition table--will create a "{ptt}" one')
|
|
recreate_partition_table = True
|
|
if cur_ptt and ptt != cur_ptt:
|
|
SystemLib.ogEcho (['session', 'log'], None, f'Current partition table type "{cur_ptt}" is wrong for this system--will replace it for a "{ptt}" one')
|
|
recreate_partition_table = True
|
|
|
|
## size check: check that cache fits in the space left by the previously existing partitions
|
|
if not recreate_partition_table and not CacheLib.ogCheckNewCacheSize (dis, tch):
|
|
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_CACHE, f'nueva partición de caché no cabe en el hueco actual')
|
|
## BUG el "hueco actual" me podría dar igual, si luego resulta que también estoy definiendo otras particiones y ya sí hay sitio para todo
|
|
sys.exit (1)
|
|
|
|
## size check: check that the newly defined partitions fit in the disk
|
|
disk_sectors = DiskLib.ogGetLastSector (dis)
|
|
IOSIZE = DiskLib.ogGetIoSize (dis)
|
|
if not IOSIZE:
|
|
SystemLib.ogRaiseError (['session', 'log'], ogGlobals.OG_ERR_FORMAT, f'Failed to get disk sector size')
|
|
sys.exit (1)
|
|
if 512 == IOSIZE:
|
|
sum_tam_sectors = sum_tam*2
|
|
cache_sectors = tch*2
|
|
else:
|
|
sum_tam_sectors = (sum_tam+3)//4 ## sumamos 3 para que la división entera "redondee al alza"
|
|
cache_sectors = (tch+3)//4
|
|
## esta comprobacion puede dejar pasar situaciones que más tarde dan error
|
|
## la ventana es bastante estrecha, y sumando aquí simplemente un 1 por 1000, ya la cerramos del todo
|
|
sum_tam_sectors = int (sum_tam_sectors * 1.001)
|
|
space_left_by_cache = disk_sectors - cache_sectors
|
|
if sum_tam_sectors > space_left_by_cache:
|
|
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_CACHE, f'las particiones no caben en el disco')
|
|
sys.exit (1)
|
|
|
|
#____________________________________________________
|
|
#
|
|
# Proceso
|
|
#____________________________________________________
|
|
# Tamaño actual de la cache
|
|
CACHESIZE=CacheLib.ogGetCacheSize()
|
|
|
|
# Desmonta todas las particiones y la caché
|
|
|
|
SystemLib.ogEcho (['session', 'log'], None, f'[10] {ogGlobals.lang.MSG_HELP_ogUnmountAll}')
|
|
FileSystemLib.ogUnmountAll (dis)
|
|
CacheLib.ogUnmountCache()
|
|
|
|
if recreate_partition_table:
|
|
DiskLib.ogDeletePartitionTable (dis)
|
|
SystemLib.ogExecAndLog ('command', [f'{ogGlobals.OGPYFUNCS}/ogUpdatePartitionTable'])
|
|
DiskLib.ogCreatePartitionTable (dis, ptt)
|
|
|
|
# Inicia la cache.
|
|
if is_there_cache:
|
|
SystemLib.ogEcho (['session', 'log'], None, f'[30] {ogGlobals.lang.MSG_HELP_ogCreateCache}')
|
|
SystemLib.ogEcho (['session', 'log'], None, f' initCache.py {dis} {tch}')
|
|
rc = SystemLib.ogExecAndLog ('command', [f'{ogGlobals.OGSCRIPTS}/initCache.py', str (dis), str (tch)])
|
|
if not rc:
|
|
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_CACHE, f'initCache.py failed')
|
|
sys.exit (1)
|
|
|
|
# Definir particionado.
|
|
if tbp:
|
|
SystemLib.ogEcho (['session', 'log'], None, f'[50] {ogGlobals.lang.MSG_HELP_ogCreatePartitions}')
|
|
SystemLib.ogEcho (['session', 'log'], None, f' ogCreatePartitions {dis} {' '.join (tbp)}')
|
|
res = SystemLib.ogExecAndLog ('command', [f'{ogGlobals.OGPYFUNCS}/ogCreatePartitions', str(dis)] + tbp)
|
|
if not res:
|
|
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_FORMAT, f'ogCreatePartitions {dis} {' '.join (tbp)}')
|
|
sys.exit (1)
|
|
SystemLib.ogExecAndLog ('command', [f'{ogGlobals.OGPYFUNCS}/ogUpdatePartitionTable'])
|
|
|
|
retval = 0
|
|
if tbf:
|
|
# Formatear particiones
|
|
SystemLib.ogEcho (['session', 'log'], None, f'[70] {ogGlobals.lang.MSG_HELP_ogFormat}')
|
|
for p in range (1, maxp+1):
|
|
if p not in tbf: continue
|
|
if 'CACHE' == tbf[p]:
|
|
if CACHESIZE == tch: # Si el tamaño es distinto ya se ha formateado.
|
|
SystemLib.ogEcho (['session', 'log'], None, ' ogFormatCache')
|
|
retval = SystemLib.ogExecAndLog ('command', [f'{ogGlobals.OGPYFUNCS}/ogFormatCache'])
|
|
else:
|
|
SystemLib.ogEcho (['session', 'log'], None, f' ogFormatFs {dis} {p} {tbf[p]}')
|
|
retval = SystemLib.ogExecAndLog ('command', [f'{ogGlobals.OGPYFUNCS}/ogFormatFs', str(dis), str(p), tbf[p]])
|
|
if not retval:
|
|
SystemLib.ogRaiseError (['session', 'log'], ogGlobals.OG_ERR_GENERIC, f'ogFormatFs {dis} {p} {tbf[p]}')
|
|
sys.exit (1)
|
|
|
|
SystemLib.ogEcho (['session', 'log'], None, f'{ogGlobals.lang.MSG_INTERFACE_END} {retval}')
|
|
sys.exit (0)
|