refs #1528 add ogCreatePartitions
parent
5e40504eff
commit
caf1f44161
|
@ -54,49 +54,42 @@ def parted(*args):
|
||||||
#@note Requisitos: sfdisk, parted, partprobe, awk
|
#@note Requisitos: sfdisk, parted, partprobe, awk
|
||||||
#@todo Definir atributos (arranque, oculta) y tamaños en MB, GB, etc.
|
#@todo Definir atributos (arranque, oculta) y tamaños en MB, GB, etc.
|
||||||
#*/ ##
|
#*/ ##
|
||||||
def ogCreatePartitions(*args):
|
def ogCreatePartitions (disk, parts):
|
||||||
# Variables locales
|
ND = disk
|
||||||
ND = DISK = PTTYPE = PART = SECTORS = START = SIZE = TYPE = CACHEPART = None
|
DISK = ogDiskToDev (ND)
|
||||||
IODISCO = IOSIZE = CACHESIZE = EXTSTART = EXTSIZE = NVME_PREFIX = tmpsfdisk = None
|
if not DISK: return None
|
||||||
|
|
||||||
# Si se solicita, mostrar ayuda.
|
PTTYPE = ogGetPartitionTableType (disk)
|
||||||
if len(args) == 1 and args[0] == "help":
|
if not PTTYPE: PTTYPE = 'MSDOS' # Por defecto para discos vacíos.
|
||||||
SystemLib.ogHelp('ogCreatePartitions', 'ogCreatePartitions int_ndisk str_parttype:int_partsize ...',
|
|
||||||
'ogCreatePartitions 1 NTFS:10000000 EXT3:5000000 LINUX-SWAP:1000000')
|
|
||||||
return
|
|
||||||
|
|
||||||
# Error si no se reciben al menos 2 parámetros.
|
if 'GPT' == PTTYPE:
|
||||||
if len(args) < 2:
|
return ogCreateGptPartitions (disk, parts)
|
||||||
SystemLib.ogRaiseError(OG_ERR_FORMAT)
|
elif 'MSDOS' != PTTYPE:
|
||||||
return
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, PTTYPE)
|
||||||
|
return None
|
||||||
|
|
||||||
# Nº total de sectores, para evitar desbordamiento (evitar redondeo).
|
SECTORS = ogGetLastSector (disk)
|
||||||
ND = args[0]
|
|
||||||
DISK = ogDiskToDev(ND)
|
|
||||||
if DISK is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
PTTYPE = ogGetPartitionTableType(ND) or "MSDOS" # Por defecto para discos vacíos.
|
# Se recalcula el nº de sectores del disco 1, si existe partición de caché.
|
||||||
|
CACHESIZE = 0
|
||||||
if PTTYPE == "GPT":
|
|
||||||
ogCreateGptPartitions(*args)
|
|
||||||
return
|
|
||||||
elif PTTYPE != "MSDOS":
|
|
||||||
SystemLib.ogRaiseError(OG_ERR_PARTITION, PTTYPE)
|
|
||||||
return
|
|
||||||
|
|
||||||
SECTORS = ogGetLastSector(ND)
|
|
||||||
|
|
||||||
# Se recalcula el nº de sectores del disco 1, si existe partición de caché.
|
|
||||||
CACHEPART = CacheLib.ogFindCache()
|
CACHEPART = CacheLib.ogFindCache()
|
||||||
if CACHEPART and ND == CACHEPART.split()[0]:
|
if CACHEPART:
|
||||||
CACHESIZE = int(CacheLib.ogGetCacheSize()) * 2
|
cache_disk, cache_part = CACHEPART.split()
|
||||||
|
if ND == cache_disk:
|
||||||
|
CACHESIZE = int (CacheLib.ogGetCacheSize()) * 2
|
||||||
|
|
||||||
# Sector de inicio (la partición 1 empieza en el sector 63).
|
# Sector de inicio (la partición 1 empieza en el sector 63).
|
||||||
IODISCO = ogDiskToDev(ND)
|
IODISCO = ogDiskToDev (disk)
|
||||||
IOSIZE = subprocess.getoutput(f"fdisk -l {IODISCO} | awk '/I\\/O/ {{print $4}}'")
|
IOSIZE = 0
|
||||||
|
fdisk_out = subprocess.run (['fdisk', '-l', IODISCO], capture_output=True, text=True).stdout
|
||||||
|
for l in fdisk_out.splitlines():
|
||||||
|
if 'I/O' not in l: continue
|
||||||
|
items = l.split()
|
||||||
|
if len(items) < 4: continue
|
||||||
|
IOSIZE = items[3]
|
||||||
|
break
|
||||||
|
|
||||||
if IOSIZE == "4096":
|
if '4096' == IOSIZE:
|
||||||
START = 4096
|
START = 4096
|
||||||
SECTORS -= 8192
|
SECTORS -= 8192
|
||||||
if CACHESIZE:
|
if CACHESIZE:
|
||||||
|
@ -108,48 +101,84 @@ def ogCreatePartitions(*args):
|
||||||
|
|
||||||
PART = 1
|
PART = 1
|
||||||
|
|
||||||
# Fichero temporal de entrada para "sfdisk"
|
# Fichero temporal de entrada para "sfdisk"
|
||||||
tmpsfdisk = f"/tmp/sfdisk{os.getpid()}"
|
sfdisk_input = 'unit: sectors\n\n'
|
||||||
try:
|
|
||||||
with open(tmpsfdisk, 'w') as f:
|
|
||||||
f.write("unit: sectors\n\n")
|
|
||||||
|
|
||||||
NVME_PREFIX = "p" if "nvme" in DISK else ""
|
NVME_PREFIX = 'p' if 'nvme' in DISK else ''
|
||||||
|
|
||||||
# Generar fichero de entrada para "sfdisk" con las particiones.
|
# Generar fichero de entrada para "sfdisk" con las particiones.
|
||||||
args = args[1:] # Shift
|
for p in parts:
|
||||||
while args:
|
# Conservar los datos de la partición de caché.
|
||||||
# Conservar los datos de la partición de caché.
|
if f'{ND} {PART}' == CACHEPART and CACHESIZE:
|
||||||
if f"{ND} {PART}" == CACHEPART and CACHESIZE:
|
sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start={SECTORS+1}, size={CACHESIZE}, Id=ca\n'
|
||||||
with open(tmpsfdisk, 'a') as f:
|
|
||||||
f.write(f"{DISK}{NVME_PREFIX}{PART} : start={SECTORS + 1}, size={CACHESIZE}, Id=ca\n")
|
|
||||||
PART += 1
|
|
||||||
|
|
||||||
# Leer formato de cada parámetro - Tipo:Tamaño
|
|
||||||
TYPE = args[0].split(":")[0]
|
|
||||||
SIZE = int(args[0].split(":")[1])
|
|
||||||
|
|
||||||
# Obtener identificador de tipo de partición válido.
|
|
||||||
ID = ogTypeToId(TYPE, "MSDOS")
|
|
||||||
with open(tmpsfdisk, 'a') as f:
|
|
||||||
f.write(f"{DISK}{NVME_PREFIX}{PART} : start={START}, size={SIZE}, Id={ID}\n")
|
|
||||||
START += SIZE
|
|
||||||
SECTORS -= SIZE
|
|
||||||
PART += 1
|
PART += 1
|
||||||
args = args[1:]
|
|
||||||
|
|
||||||
# Ejecutar "sfdisk" con el fichero temporal.
|
# Leer formato de cada parámetro - Tipo:Tamaño
|
||||||
subprocess.run(["sfdisk", DISK], input=open(tmpsfdisk, 'r').read(), text=True)
|
TYPE, SIZE = p.split (':')
|
||||||
subprocess.run(["partprobe", DISK])
|
try:
|
||||||
|
SIZE = int (SIZE)
|
||||||
|
except ValueError:
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, SIZE)
|
||||||
|
return None
|
||||||
|
|
||||||
finally:
|
# Obtener identificador de tipo de partición válido.
|
||||||
# Eliminar fichero temporal.
|
ID = ogTypeToId (TYPE, 'MSDOS')
|
||||||
if os.path.exists(tmpsfdisk):
|
if 'CACHE' == TYPE or not ID:
|
||||||
os.remove(tmpsfdisk)
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, TYPE)
|
||||||
|
return None
|
||||||
|
# Comprobar tamaño numérico y convertir en sectores de 512 B.
|
||||||
|
SIZE *= 2
|
||||||
|
# Comprobar si la partición es extendida.
|
||||||
|
EXTSTART = EXTSIZE = 0
|
||||||
|
if 5 == ID:
|
||||||
|
if PART > 4:
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '')
|
||||||
|
return None
|
||||||
|
# El inicio de la primera partición logica es el de la extendida más 4x512
|
||||||
|
EXTSTART = START+2048
|
||||||
|
EXTSIZE = SIZE-2048
|
||||||
|
# Incluir particiones lógicas dentro de la partición extendida.
|
||||||
|
if 5 == PART:
|
||||||
|
if not EXTSTART:
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '')
|
||||||
|
return None
|
||||||
|
START = EXTSTART
|
||||||
|
SECTORS = EXTSTART+EXTSIZE
|
||||||
|
# Generar datos para la partición.
|
||||||
|
sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start={START}, size={SIZE}, Id={ID}\n'
|
||||||
|
# Error si se supera el nº total de sectores.
|
||||||
|
START += SIZE
|
||||||
|
if '4096' == IOSIZE and PART > 4:
|
||||||
|
START += 2048
|
||||||
|
if START > SECTORS:
|
||||||
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'{START//2} > {SECTORS//2}')
|
||||||
|
return None
|
||||||
|
PART += 1
|
||||||
|
|
||||||
if CACHESIZE:
|
# Si no se indican las 4 particiones primarias, definirlas como vacías, conservando la partición de caché.
|
||||||
CacheLib.ogMountCache()
|
while PART <= 4:
|
||||||
return 0
|
if f'{ND} {PART}' == CACHEPART and CACHESIZE:
|
||||||
|
sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start={SECTORS+1}, size={CACHESIZE}, Id=ca\n'
|
||||||
|
else:
|
||||||
|
sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start=0, size=0, Id=0\n'
|
||||||
|
PART += 1
|
||||||
|
# Si se define partición extendida sin lógicas, crear particion 5 vacía.
|
||||||
|
if 5 == PART and EXTSTART:
|
||||||
|
sfdisk_input += f'{DISK}5 : start={EXTSTART}, SIZE={EXTSIZE}, Id=0\n'
|
||||||
|
|
||||||
|
# Desmontar los sistemas de archivos del disco antes de realizar las operaciones.
|
||||||
|
FileSystemLib.ogUnmountAll (ND)
|
||||||
|
if CACHESIZE: CacheLib.ogUnmountCache()
|
||||||
|
|
||||||
|
# Si la tabla de particiones no es valida, volver a generarla.
|
||||||
|
ogCreatePartitionTable (ND)
|
||||||
|
# Definir particiones y notificar al kernel.
|
||||||
|
print (f'about to run sfdisk: ({sfdisk_input})')
|
||||||
|
p = subprocess.run (['sfdisk', DISK], input=sfdisk_input, capture_output=True, text=True)
|
||||||
|
print (f'rc ({p.returncode}) stdout ({p.stdout}) stderr ({p.stderr})')
|
||||||
|
subprocess.run (['partprobe', DISK])
|
||||||
|
if CACHESIZE: CacheLib.ogMountCache()
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
from SystemLib import ogHelp
|
||||||
|
from DiskLib import ogCreatePartitions
|
||||||
|
|
||||||
|
if 2 == len (sys.argv) and 'help' == sys.argv[1]:
|
||||||
|
#parser.print_help() sale en inglés aunque la locale indique otra cosa
|
||||||
|
ogHelp ('ogCreatePartitions', 'ogCreatePartitions int_ndisk str_parttype:int_partsize ...', ['ogCreatePartitions 1 NTFS:10000000 EXT3:5000000 LINUX-SWAP:1000000'])
|
||||||
|
sys.exit (0)
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser (add_help=False)
|
||||||
|
parser.add_argument ('disk')
|
||||||
|
parser.add_argument ('parts', nargs='+')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
ret = ogCreatePartitions (args.disk, args.parts)
|
||||||
|
|
||||||
|
if ret is not None:
|
||||||
|
if ret == True: sys.exit (0)
|
||||||
|
elif ret == False: sys.exit (1)
|
||||||
|
else: print (ret)
|
Loading…
Reference in New Issue