Compare commits
26 Commits
Author | SHA1 | Date |
---|---|---|
|
c33c9ec1af | |
|
6617bace74 | |
|
a560380b81 | |
|
acaf67f486 | |
|
5cf92d6367 | |
|
c2d04ca39f | |
|
4432b60326 | |
|
87b566532c | |
|
c5db321d93 | |
|
3d692f54a5 | |
|
e529768257 | |
|
8029d469a7 | |
|
73721d70f7 | |
|
83c1c7763a | |
|
9e7fda8944 | |
|
df36d74d7c | |
|
38be98d9f1 | |
|
36a8277aab | |
|
cf5ec4c214 | |
|
0d28787318 | |
|
9cad17e4f4 | |
|
a7f4d767f5 | |
|
588ed96098 | |
|
87adfeda1c | |
|
6e806424cc | |
|
334f961e4c |
24
CHANGELOG.md
24
CHANGELOG.md
|
@ -5,6 +5,30 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.27.0] - 2025-07-16
|
||||
|
||||
### Added
|
||||
|
||||
- Add python init scripts
|
||||
|
||||
## [0.26.1] - 2025-07-14
|
||||
|
||||
### Changed
|
||||
|
||||
- Change sort order in `_getAllDisks()`
|
||||
|
||||
## [0.26.0] - 2025-07-14
|
||||
|
||||
### Fixed
|
||||
|
||||
- Overhaul partitioning
|
||||
|
||||
## [0.25.2] - 2025-07-14
|
||||
|
||||
### Fixed
|
||||
|
||||
- Run initCache.py rather than just initCache
|
||||
|
||||
## [0.25.1] - 2025-07-11
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/python3
|
||||
# Proceso general de arranque de OpenGnsys Client.
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
import ogGlobals
|
||||
from NetLib import ogGetIpAddress
|
||||
|
||||
ogstatus = os.environ.get ('ogstatus', '')
|
||||
ogcore = os.environ.get ('ogcore', '')
|
||||
oglog = os.environ.get ('oglog', '')
|
||||
oggroup = os.environ.get ('OGGROUP', '')
|
||||
ogactiveadmin = os.environ.get ('ogactiveadmin', '')
|
||||
LANG = os.environ.get ('LANG', 'es_ES')
|
||||
LANG = LANG[0:LANG.index('_')]
|
||||
|
||||
LOGLEVEL=5
|
||||
|
||||
# Matando plymount para inicir browser o shell
|
||||
subprocess.run (['pkill', '-9', 'plymouthd'])
|
||||
|
||||
# Arranque de OpenGnsys Client daemon (socket).
|
||||
print (ogGlobals.lang.MSG_LAUNCHCLIENT)
|
||||
# Indicar fichero de teclado de Qt para el idioma especificado (tipo "es.qmap").
|
||||
if os.path.exists (f'/usr/local/etc/{LANG}.qmap'):
|
||||
os.environ['QWS_KEYBOARD'] = f'TTY:keymap=/usr/local/etc/{LANG}.qmap'
|
||||
|
||||
if os.path.exists ('/usr/share/OGAgent/opengnsys/linux/OGAgentService.py') and ogstatus != 'offline':
|
||||
os.chdir ('/usr/share/OGAgent')
|
||||
os.environ['OGAGENTCFG_OGCORE_IP'] = ogcore
|
||||
os.environ['OGAGENTCFG_OGLOG_IP'] = oglog
|
||||
os.environ['OGAGENTCFG_URLMENU_SCHEME'] = 'http'
|
||||
os.environ['OGAGENTCFG_URLMENU_IP'] = '127.0.0.1'
|
||||
os.environ['OGAGENTCFG_URLMENU_PORT'] = '81'
|
||||
subprocess.run (['python3', '-m', 'opengnsys.linux.OGAgentService', 'fg'])
|
||||
else:
|
||||
ip = ogGetIpAddress()
|
||||
OGMENU = ''
|
||||
for FILE in [index, oggroup, ip]:
|
||||
if not FILE: continue
|
||||
m = f'{ogGlobals.OGCAC}/menus/{FILE}.html'
|
||||
if os.path.exists (m): OGMENU = m
|
||||
subprocess.run ([f'{ogGlobals.OPENGNSYS}/bin/launch_browser', m])
|
||||
|
||||
# Si fallo en cliente y modo "admin", cargar shell; si no, salir.
|
||||
if ogactiveadmin == 'true':
|
||||
subprocess.run (['bash'])
|
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
## early init
|
||||
import os
|
||||
import sys
|
||||
OPENGNSYS = os.environ.get ('OPENGNSYS', '/opt/opengnsys')
|
||||
os.environ['PYTHONPATH'] = f'{OPENGNSYS}/lib/python3'
|
||||
sys.path.insert (0, os.environ['PYTHONPATH'])
|
||||
## end
|
||||
|
||||
import subprocess
|
||||
|
||||
import ogGlobals
|
||||
from InitLib import loadenviron, write_profile, clean_esp, fileslinks, loadmodules, metadevs, mountrepo, poweroff, filebeat, stunnel, dbus, otherservices, runhttplog
|
||||
|
||||
IPV4ADDR = os.environ.get ('IPV4ADDR', '')
|
||||
OG_IP = os.environ.get ('OG_IP', '')
|
||||
|
||||
loadenviron()
|
||||
write_profile()
|
||||
|
||||
# Funciones de inicio.
|
||||
clean_esp()
|
||||
fileslinks()
|
||||
loadmodules()
|
||||
metadevs()
|
||||
mountrepo()
|
||||
poweroff()
|
||||
filebeat()
|
||||
stunnel()
|
||||
dbus()
|
||||
otherservices()
|
||||
runhttplog()
|
||||
|
||||
if IPV4ADDR and os.path.exists (f'{ogGlobals.OGETC}/init/{IPV4ADDR}.sh'):
|
||||
if OG_IP: subprocess.run ([f'{ogGlobals.OGETC}/init/{OG_IP}.sh'])
|
||||
|
||||
elif os.path.exists (f'{ogGlobals.OGETC}/init.py'):
|
||||
subprocess.run ([f'{ogGlobals.OGETC}/init.py'])
|
||||
|
||||
else:
|
||||
print ('No se ha encontrado script de inicio')
|
||||
subprocess.run (['halt'])
|
|
@ -1,5 +1,12 @@
|
|||
#!/bin/bash
|
||||
|
||||
if grep -q pyinit=true /proc/cmdline; then
|
||||
echo "python init"
|
||||
exec /opt/opengnsys/etc/preinit/default.py
|
||||
else
|
||||
echo "shell init"
|
||||
fi
|
||||
|
||||
# Cargar entorno de OpenGnsys
|
||||
set -a
|
||||
source /opt/opengnsys/etc/preinit/loadenviron.sh
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
import ogGlobals
|
||||
import SystemLib
|
||||
|
@ -34,12 +33,12 @@ 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
|
||||
# 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
|
||||
# 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).
|
||||
|
@ -51,12 +50,13 @@ param = sys.argv[2]
|
|||
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.
|
||||
tbprm = pparam.split ('*')
|
||||
pparams = pparam.split ('*')
|
||||
dis = tch = None
|
||||
for item in tbprm:
|
||||
for item in pparams:
|
||||
if '=' not in item: continue
|
||||
|
||||
k, v = item.split ('=', 1)
|
||||
|
@ -74,10 +74,13 @@ if dis is None:
|
|||
tbp = [] # Valores de configuración (parámetros para ogCreatePartitions)
|
||||
tbf = {} # Tabla de formateo
|
||||
|
||||
tbprm = sparam.split('%')
|
||||
sparams = sparam.split('%')
|
||||
|
||||
maxp=0
|
||||
for item in tbprm:
|
||||
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
|
||||
|
@ -93,7 +96,7 @@ for item in tbprm:
|
|||
if 'par' == k: par = int (v)
|
||||
elif 'cpt' == k: cpt = v
|
||||
elif 'sfi' == k: sfi = v
|
||||
elif 'tam' == k: tam = v
|
||||
elif 'tam' == k: tam = int (v)
|
||||
elif 'ope' == k: ope = int (v)
|
||||
|
||||
missing_params = []
|
||||
|
@ -106,10 +109,29 @@ for item in tbprm:
|
|||
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']:
|
||||
|
@ -118,7 +140,88 @@ for item in tbprm:
|
|||
if par > maxp: maxp = par
|
||||
|
||||
if tch is None:
|
||||
tch = '0'
|
||||
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)
|
||||
|
||||
#____________________________________________________
|
||||
#
|
||||
|
@ -133,53 +236,46 @@ SystemLib.ogEcho (['session', 'log'], None, f'[10] {ogGlobals.lang.MSG_HELP_ogUn
|
|||
FileSystemLib.ogUnmountAll (dis)
|
||||
CacheLib.ogUnmountCache()
|
||||
|
||||
# Elimina la tabla de particiones
|
||||
cur_ptt = DiskLib.ogGetPartitionTableType (dis)
|
||||
ptt = 'GPT' if InventoryLib.ogIsEfiActive() else 'MSDOS'
|
||||
if not cur_ptt or ptt != cur_ptt:
|
||||
if recreate_partition_table:
|
||||
DiskLib.ogDeletePartitionTable (dis)
|
||||
SystemLib.ogExecAndLog ('command', [f'{ogGlobals.OGPYFUNCS}/ogUpdatePartitionTable'])
|
||||
DiskLib.ogCreatePartitionTable (dis, ptt)
|
||||
|
||||
# Inicia la cache.
|
||||
if 'CACHE' in sparam:
|
||||
if is_there_cache:
|
||||
SystemLib.ogEcho (['session', 'log'], None, f'[30] {ogGlobals.lang.MSG_HELP_ogCreateCache}')
|
||||
SystemLib.ogEcho (['session', 'log'], None, f' initCache {tch}')
|
||||
rc = SystemLib.ogExecAndLog ('command', [f'{ogGlobals.OGSCRIPTS}/initCache', tch])
|
||||
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 failed')
|
||||
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_CACHE, f'initCache.py failed')
|
||||
sys.exit (1)
|
||||
|
||||
# Definir particionado.
|
||||
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_GENERIC, f'ogCreatePartitions {dis} {' '.join (tbp)}')
|
||||
sys.exit (1)
|
||||
SystemLib.ogExecAndLog ('command', [f'{ogGlobals.OGPYFUNCS}/ogUpdatePartitionTable'])
|
||||
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'])
|
||||
|
||||
# Formatear particiones
|
||||
SystemLib.ogEcho (['session', 'log'], None, f'[70] {ogGlobals.lang.MSG_HELP_ogFormat}')
|
||||
retval = 0
|
||||
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)
|
||||
# Registro de fin de ejecución
|
||||
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}')
|
||||
|
||||
#___________________________________________________________________
|
||||
#
|
||||
# Retorno
|
||||
#___________________________________________________________________
|
||||
|
||||
sys.exit (0)
|
||||
|
|
|
@ -195,7 +195,7 @@ def ogBoot (disk, par, nvramperm=False, params=''):
|
|||
winboot = os.environ.get ('winboot', '')
|
||||
if 'kexec' == winboot:
|
||||
# Modo de arranque en caliente (con kexec).
|
||||
cp_cmd = f'cp {ogGlobals.OGLIB}/grub4dos/* {mntdir}'
|
||||
cp_cmd = f'cp {ogGlobals.OGLIB}/grub4dos/* {mntdir}' ## shutil sucks a bit for copying both files and dirs
|
||||
subprocess.run (cp_cmd, shell=True)
|
||||
disk0 = int(disk)-1
|
||||
par0 = int(par)-1
|
||||
|
|
|
@ -37,16 +37,15 @@ def ogCreateCache (ndsk=1, part=4, sizecache=0):
|
|||
NVME_PREFIX = 'p'
|
||||
|
||||
END = DiskLib.ogGetLastSector (ndsk)
|
||||
if not END:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'Failed to get last sector of disk')
|
||||
return None
|
||||
SIZE = 2 * sizecache
|
||||
# Inicio partición cache según el disco tenga sectores de 4k o menores
|
||||
IOSIZE = 0
|
||||
fdisk_out = subprocess.run (['fdisk', '-l', DISK], capture_output=True, text=True).stdout
|
||||
for l in fdisk_out.splitlines():
|
||||
items = l.split()
|
||||
if len(items) < 4: continue
|
||||
if 'I/O' == items[0]:
|
||||
IOSIZE = int (items[3])
|
||||
break
|
||||
IOSIZE = DiskLib.ogGetIoSize (ndsk)
|
||||
if not IOSIZE:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Failed to get disk sector size')
|
||||
return None
|
||||
START = 0
|
||||
if 4096 == IOSIZE:
|
||||
END -= 8192
|
||||
|
@ -70,7 +69,7 @@ def ogCreateCache (ndsk=1, part=4, sizecache=0):
|
|||
MINSIZE = 25000
|
||||
MAXSIZE = END
|
||||
if SIZE < MINSIZE or SIZE > MAXSIZE or START < ENDPREVPART:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, f'size ({SIZE}) < minsize ({MINSIZE}) or size > maxsize ({MAXSIZE}) or start ({START}) < endprevpart ({ENDPREVPART})')
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'size ({SIZE}) < minsize ({MINSIZE}) or size ({SIZE}) > maxsize ({MAXSIZE}) or start ({START}) < endprevpart ({ENDPREVPART})')
|
||||
return None
|
||||
|
||||
# Desmontar todos los sistemas de archivos del disco.
|
||||
|
@ -90,27 +89,32 @@ def ogCreateCache (ndsk=1, part=4, sizecache=0):
|
|||
subprocess.run (['gdisk', DISK], input='2\nw\nY\n', capture_output=True, text=True)
|
||||
# Si existe la cache se borra previamente
|
||||
if ogFindCache(): ogDeleteCache()
|
||||
# Capturamos el codigo de particion GPT para cache
|
||||
# PATCH - Cuando es GPT, la particion con codigo CACHE (CA00) no existe y no puede crearse, se cambia por LINUX (8300)
|
||||
ID = DiskLib.ogTypeToId ('LINUX', 'GPT')
|
||||
subprocess.run (['sgdisk', DISK, f'-n{part}:{START}:{END}', f'-c{part}:CACHE', f'-t{part}:{ID}'])
|
||||
|
||||
ID = DiskLib.ogTypeToId ('LINUX', 'GPT_GUID')
|
||||
sfdisk_line = f'{DISK}{NVME_PREFIX}{part} : start= {START}, size= {SIZE}, type={ID}, name=CACHE'
|
||||
elif 'MSDOS' == get_ptt:
|
||||
# Si la tabla de particiones no es valida, volver a generarla.
|
||||
if subprocess.run (['parted', '-s', DISK, 'print']).returncode: ## if True, then parted failed
|
||||
subprocess.run (['fdisk', DISK], input='w\n', text=True)
|
||||
# Definir particiones y notificar al kernel.
|
||||
if subprocess.run (['parted', '-s', DISK, 'print'], capture_output=True).returncode: ## if True, then parted failed
|
||||
subprocess.run (['fdisk', DISK], input='w\n', text=True, capture_output=True)
|
||||
|
||||
ID = DiskLib.ogTypeToId ('CACHE', 'MSDOS')
|
||||
# Salvamos la configuración de las particiones e incluimos la cache.
|
||||
tmp = subprocess.run (['sfdisk', '--dump', DISK], capture_output=True, text=True).stdout.splitlines()
|
||||
tmp = [ x for x in tmp if f'{DISK}{part}' not in x ]
|
||||
tmp.append (f'{DISK}{NVME_PREFIX}{part} : start= {START}, size= {SIZE}, Id={ID}')
|
||||
# Ordenamos las líneas de los dispositivos
|
||||
UNIT = [ x for x in tmp if 'unit' in x ][0]
|
||||
tmp = sorted ([ x for x in tmp if re.match ('^/dev', x) ])
|
||||
tmp = [UNIT, ''] + tmp
|
||||
# Guardamos nueva configuración en el disco.
|
||||
i = '\n'.join(tmp)
|
||||
subprocess.run (['sfdisk', '--no-reread', DISK], input=i, text=True)
|
||||
sfdisk_line = f'{DISK}{NVME_PREFIX}{part} : start= {START}, size= {SIZE}, Id={ID}'
|
||||
else:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'No hay tabla de particiones en el disco')
|
||||
return False
|
||||
|
||||
# Salvamos la configuración de las particiones e incluimos la cache.
|
||||
tmp = subprocess.run (['sfdisk', '--dump', DISK], capture_output=True, text=True).stdout.splitlines()
|
||||
tmp = [ x for x in tmp if f'{DISK}{part}' not in x ] ## grep -v la_de_cache
|
||||
tmp.append (sfdisk_line)
|
||||
# Ordenamos las líneas de los dispositivos
|
||||
UNIT = [ x for x in tmp if 'unit' in x ][0]
|
||||
tmp = sorted ([ x for x in tmp if re.match ('^/dev', x) ])
|
||||
tmp = [UNIT, ''] + tmp
|
||||
# Guardamos nueva configuración en el disco.
|
||||
i = '\n'.join(tmp)
|
||||
subprocess.run (['sfdisk', '--no-reread', DISK], input=i, text=True)
|
||||
|
||||
# Actualiza la tabla de particiones en el kernel.
|
||||
DiskLib.ogUpdatePartitionTable()
|
||||
return True
|
||||
|
@ -139,15 +143,15 @@ def ogDeleteCache():
|
|||
ptt = DiskLib.ogGetPartitionTableType (ndisk)
|
||||
if 'GPT' == ptt:
|
||||
# Si la tabla de particiones no es valida, volver a generarla.
|
||||
if subprocess.run (['sgdisk', '-p', disk]).returncode: ## if True, then sgdisk failed
|
||||
subprocess.run (['gdisk', disk], input='2\nw\nY\n', text=True)
|
||||
if subprocess.run (['sgdisk', '-p', disk], capture_output=True).returncode: ## if True, then sgdisk failed
|
||||
subprocess.run (['gdisk', disk], input='2\nw\nY\n', text=True, capture_output=True)
|
||||
subprocess.run (['sgdisk', disk, f'-d{npart}'])
|
||||
elif 'MSDOS' == ptt:
|
||||
# Si la tabla de particiones no es valida, volver a generarla.
|
||||
if subprocess.run (['parted', '-s', disk, 'print']).returncode: ## if True, then parted failed
|
||||
subprocess.run (['fdisk', disk], input='w', text=True)
|
||||
if subprocess.run (['parted', '-s', disk, 'print'], capture_output=True).returncode: ## if True, then parted failed
|
||||
subprocess.run (['fdisk', disk], input='w', text=True, capture_output=True)
|
||||
# Eliminar la partición de caché.
|
||||
subprocess.run (['fdisk', disk], input=f'd\n{npart}\nw', text=True)
|
||||
subprocess.run (['fdisk', disk], input=f'd\n{npart}\nw', text=True, capture_output=True)
|
||||
# Borrar etiqueta de la caché.
|
||||
if os.path.exists ('/dev/disk/by-label/CACHE'):
|
||||
os.unlink ('/dev/disk/by-label/CACHE')
|
||||
|
@ -358,3 +362,46 @@ def ogUnmountCache():
|
|||
def initCache (*args):
|
||||
p = subprocess.run ([f'{ogGlobals.OGSCRIPTS}/initCache.py'] + list(args))
|
||||
return not p.returncode ## negate shell return code
|
||||
|
||||
|
||||
#/**
|
||||
# ogCheckNewCacheSize
|
||||
#@brief Comprueba si un cache de X tamaño cabe en el hueco que dejan las demás particiones
|
||||
#@param Tamaño de la nueva hipotética cache
|
||||
#@return Boolean, True si la nueva cache cabría, False si no
|
||||
#*/ ##
|
||||
def ogCheckNewCacheSize (disk, kB):
|
||||
DISK = DiskLib.ogDiskToDev (disk)
|
||||
if not DISK: return None
|
||||
|
||||
IOSIZE = DiskLib.ogGetIoSize (disk)
|
||||
if not IOSIZE:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Failed to get disk sector size')
|
||||
return None
|
||||
last_sector = DiskLib.ogGetLastSector (disk)
|
||||
|
||||
end_of_last_partition = 0
|
||||
cachepart = ogFindCache()
|
||||
if cachepart:
|
||||
cache_disk, cache_part = cachepart.split()
|
||||
cache_dev = DiskLib.ogDiskToDev (cache_disk, cache_part)
|
||||
else:
|
||||
cache_dev = None
|
||||
fdisk_l_out = subprocess.run (['fdisk', '-l', DISK], capture_output=True, text=True).stdout
|
||||
for l in fdisk_l_out.splitlines():
|
||||
if not re.match ('^/dev', l): ## no empieza por /dev, nos la saltamos
|
||||
continue
|
||||
if cache_dev and re.match (f'^{cache_dev}', l): ## es la de cache, nos la saltamos
|
||||
continue
|
||||
last_sector_of_partition = int (l.split()[2])
|
||||
if last_sector_of_partition > end_of_last_partition:
|
||||
end_of_last_partition = last_sector_of_partition
|
||||
|
||||
if 512 == IOSIZE:
|
||||
cache_sectors = kB*2
|
||||
else: ## 4096
|
||||
cache_sectors = (kB+3)//4 ## sumamos 3 para que la división entera "redondee al alza"
|
||||
if end_of_last_partition + cache_sectors > last_sector:
|
||||
SystemLib.ogEcho (['session', 'log'], None, f'end_of_last_partition ({end_of_last_partition}) + cache_sectors ({cache_sectors}) > last_sector ({last_sector}), check failed')
|
||||
return False
|
||||
return True
|
||||
|
|
|
@ -38,6 +38,32 @@ def parted(*args):
|
|||
return "Error: 'parted' command not found"
|
||||
|
||||
|
||||
#/**
|
||||
# ogGetIoSize int_ndisk
|
||||
#@brief Devuelve el tamaño de sector de un disco
|
||||
#@param int_ndisk nº de orden del disco
|
||||
#@return Tamaño de sector
|
||||
#*/ ##
|
||||
def ogGetIoSize (disk):
|
||||
DISK = ogDiskToDev (disk)
|
||||
if not DISK: return None
|
||||
|
||||
IOSIZE = None
|
||||
fdisk_out = subprocess.run (['fdisk', '-l', DISK], 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 is None:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Could not extract disk sector size from fdisk output')
|
||||
return None
|
||||
|
||||
return int (IOSIZE)
|
||||
|
||||
|
||||
#/**
|
||||
# ogCreatePartitions int_ndisk str_parttype:int_partsize ...
|
||||
#@brief Define el conjunto de particiones de un disco.
|
||||
|
@ -61,12 +87,11 @@ def ogCreatePartitions (disk, parts):
|
|||
|
||||
PTTYPE = ogGetPartitionTableType (disk)
|
||||
if not PTTYPE: PTTYPE = 'MSDOS' # Por defecto para discos vacíos.
|
||||
|
||||
if 'GPT' == PTTYPE:
|
||||
return ogCreateGptPartitions (disk, parts)
|
||||
elif 'MSDOS' != PTTYPE:
|
||||
if PTTYPE not in ['MSDOS', 'GPT']:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, PTTYPE)
|
||||
return None
|
||||
if 'MSDOS' == PTTYPE: CACHE_ID = ogTypeToId ('CACHE', 'MSDOS')
|
||||
else: CACHE_ID = ogTypeToId ('CACHE', 'GPT_GUID')
|
||||
|
||||
# Se calcula el ultimo sector del disco (total de sectores usables)
|
||||
SECTORS = ogGetLastSector (disk)
|
||||
|
@ -78,24 +103,21 @@ def ogCreatePartitions (disk, parts):
|
|||
cache_disk, cache_part = CACHEPART.split()
|
||||
if int (ND) == int (cache_disk):
|
||||
CACHESIZE = int (CacheLib.ogGetCacheSize()) * 2
|
||||
# Sector de inicio (la partición 1 empieza en el sector 63).
|
||||
IODISCO = ogDiskToDev (disk)
|
||||
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 '4096' == IOSIZE:
|
||||
# Sector de inicio (la partición 1 empieza en el sector 63).
|
||||
IOSIZE = ogGetIoSize (ND)
|
||||
if not IOSIZE:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Failed to get disk sector size')
|
||||
return None
|
||||
|
||||
if 4096 == IOSIZE:
|
||||
START = 4096
|
||||
SECTORS -= 8192
|
||||
if CACHESIZE:
|
||||
SECTORS = SECTORS - CACHESIZE + 2048 - (SECTORS - CACHESIZE) % 2048 - 1
|
||||
else:
|
||||
START = 63
|
||||
else: ## 512
|
||||
if 'MSDOS' == PTTYPE: START = 63
|
||||
else: START = 2048
|
||||
if CACHESIZE:
|
||||
SECTORS -= CACHESIZE
|
||||
|
||||
|
@ -103,71 +125,108 @@ def ogCreatePartitions (disk, parts):
|
|||
|
||||
sfdisk_input = 'unit: sectors\n\n'
|
||||
NVME_PREFIX = 'p' if 'nvme' in DISK else ''
|
||||
EXTSTART = EXTSIZE = 0
|
||||
for p in parts:
|
||||
# Conservar los datos de la partición de caché.
|
||||
if f'{ND} {PART}' == CACHEPART and CACHESIZE:
|
||||
sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start={SECTORS+1}, size={CACHESIZE}, Id=ca\n'
|
||||
PART += 1
|
||||
continue
|
||||
|
||||
# Leer formato de cada parámetro - Tipo:Tamaño
|
||||
TYPE, SIZE = p.split (':')
|
||||
if TYPE is None or 'None' == TYPE: TYPE='EMPTY'
|
||||
|
||||
# Obtener identificador de tipo de partición válido.
|
||||
if 'GPT' == PTTYPE:
|
||||
ID = ogTypeToId (TYPE, 'GPT_GUID')
|
||||
else:
|
||||
ID = ogTypeToId (TYPE, PTTYPE)
|
||||
|
||||
# Conservar los datos de la partición de caché.
|
||||
if f'{ND} {PART}' == CACHEPART and CACHESIZE:
|
||||
sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start={SECTORS+1}, size={CACHESIZE}, type={CACHE_ID}\n'
|
||||
PART += 1
|
||||
|
||||
try:
|
||||
SIZE = int (SIZE)
|
||||
except ValueError:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, SIZE)
|
||||
return None
|
||||
|
||||
# Obtener identificador de tipo de partición válido.
|
||||
ID = ogTypeToId (TYPE, 'MSDOS')
|
||||
if 'CACHE' == TYPE or not ID:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, TYPE)
|
||||
return None
|
||||
# Comprobar tamaño numérico y convertir en sectores de 512 B.
|
||||
SIZE *= 2
|
||||
|
||||
# Comprobar tamaño numérico y convertir en sectores
|
||||
ORIG_SIZE = SIZE ## para reportar en un error
|
||||
if 512 == IOSIZE: SIZE *= 2
|
||||
else: SIZE = (SIZE+3)//4 ## sumamos 3 para que la división entera "redondee al alza"
|
||||
|
||||
# Comprobar si la partición es extendida.
|
||||
EXTSTART = EXTSIZE = 0
|
||||
if 5 == ID:
|
||||
if PART > 4:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '')
|
||||
if '5' == ID:
|
||||
if 'GPT' == PTTYPE:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'EXTENDED')
|
||||
return None
|
||||
|
||||
## la extendida debe ser:
|
||||
## - si no estamos creando cache: /dev/sda4
|
||||
## - si sí estamos creando cache: /dev/sda3
|
||||
## de lo contrario, crea eg. esto:
|
||||
## Device Boot Start End Sectors Size Id Type
|
||||
## /dev/sda1 63 222444728 222444666 106,1G 82 Linux swap / Solaris
|
||||
## /dev/sda2 222444729 244889394 22444666 10,7G 5 Extended <---------
|
||||
## /dev/sda3 244889395 251334060 6444666 3,1G 83 Linux <---------
|
||||
## /dev/sda4 314103633 314572766 469134 229,1M ca unknown
|
||||
## /dev/sda5 222446777 224891442 2444666 1,2G 83 Linux
|
||||
## /dev/sda6 224891443 229558330 4666888 2,2G 83 Linux
|
||||
## la sda2 es extendida, y las lógicas deberían ser sda5, sda6, sda7
|
||||
## pero esto mete una sda3 como lógica, y luego va el cache que es primaria... WTF
|
||||
error_in_extended = False
|
||||
if CACHEPART and PART != 3: error_in_extended = True
|
||||
if not CACHEPART and PART != 4: error_in_extended = True
|
||||
if PART > 4: error_in_extended = True
|
||||
if error_in_extended:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'No se puede definir la partición extendida en la partición "{PART}"')
|
||||
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
|
||||
if 'GPT' == PTTYPE:
|
||||
pass ## sin problema, la partición 5 es simplemente una más
|
||||
else:
|
||||
if not EXTSTART:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'la partición 5 es lógica pero no hay ninguna EXTENDED definida antes')
|
||||
return None
|
||||
START = EXTSTART
|
||||
SECTORS = EXTSTART+EXTSIZE
|
||||
|
||||
# Generar datos para la partición.
|
||||
# En el caso de que la partición sea EMPTY no se crea nada
|
||||
if 'EMPTY' != TYPE:
|
||||
sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start={START}, size={SIZE}, Id={ID}\n'
|
||||
sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start={START}, size={SIZE}, type={ID}\n'
|
||||
|
||||
START += SIZE
|
||||
|
||||
# Error si se supera el nº total de sectores.
|
||||
if '4096' == IOSIZE and PART > 4:
|
||||
if 'MSDOS' == PTTYPE and 4096 == IOSIZE and PART > 4:
|
||||
START += 2048
|
||||
|
||||
# Error si se supera el nº total de sectores.
|
||||
if START > SECTORS:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'{START//2} > {SECTORS//2}')
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'partición "{TYPE}:{ORIG_SIZE}" no cabe')
|
||||
return None
|
||||
PART += 1
|
||||
|
||||
# Si no se indican las 4 particiones primarias, definirlas como vacías, conservando la partición de caché.
|
||||
while PART <= 4:
|
||||
if f'{ND} {PART}' == CACHEPART and CACHESIZE:
|
||||
sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start={SECTORS+1}, size={CACHESIZE}, Id=ca\n'
|
||||
sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start={SECTORS+1}, size={CACHESIZE}, type={CACHE_ID}\n'
|
||||
else:
|
||||
sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start=0, size=0, Id=0\n'
|
||||
sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start=0, size=0, type=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'
|
||||
ID = ogTypeToId ('WINDOWS', PTTYPE)
|
||||
sfdisk_input += f'{DISK}5 : start={EXTSTART}, SIZE={EXTSIZE}, type={ID}\n'
|
||||
|
||||
# Desmontar los sistemas de archivos del disco antes de realizar las operaciones.
|
||||
FileSystemLib.ogUnmountAll (ND)
|
||||
|
@ -183,113 +242,6 @@ def ogCreatePartitions (disk, parts):
|
|||
return not p.returncode
|
||||
|
||||
|
||||
#/**
|
||||
# ogCreateGptPartitions int_ndisk str_parttype:int_partsize ...
|
||||
#@brief Define el conjunto de particiones de un disco GPT
|
||||
#@param int_ndisk nº de orden del disco
|
||||
#@param str_parttype mnemónico del tipo de partición
|
||||
#@param int_partsize tamaño de la partición (en KB)
|
||||
#@return (nada, por determinar)
|
||||
#@exception OG_ERR_FORMAT formato incorrecto.
|
||||
#@exception OG_ERR_NOTFOUND disco o partición no detectado (no es un dispositivo).
|
||||
#@exception OG_ERR_PARTITION error en partición o en tabla de particiones.
|
||||
#@attention El nº de partición se indica por el orden de los párametros \c parttype:partsize
|
||||
#@attention Pueden definirse particiones vacías de tipo \c EMPTY
|
||||
#@attention No puede definirse partición de caché y no se modifica si existe.
|
||||
#@note Requisitos: sfdisk, parted, partprobe, awk
|
||||
#@todo Definir atributos (arranque, oculta) y tamaños en MB, GB, etc.
|
||||
#*/ ##
|
||||
def ogCreateGptPartitions (disk, parts):
|
||||
ND = disk
|
||||
DISK = ogDiskToDev (ND)
|
||||
if not DISK: return None
|
||||
|
||||
# Se calcula el ultimo sector del disco (total de sectores usables)
|
||||
SECTORS = ogGetLastSector (disk)
|
||||
|
||||
# Se recalcula el nº de sectores del disco si existe partición de caché.
|
||||
CACHESIZE = 0
|
||||
CACHEPART = CacheLib.ogFindCache()
|
||||
if CACHEPART:
|
||||
cache_disk, cache_part = CACHEPART.split()
|
||||
if ND == cache_disk:
|
||||
CACHESIZE = int (CacheLib.ogGetCacheSize()) * 2
|
||||
if CACHESIZE:
|
||||
SECTORS -= CACHESIZE
|
||||
|
||||
# Si el disco es GPT empieza en el sector 2048 por defecto, pero podria cambiarse
|
||||
ALIGN = int (subprocess.run (['sgdisk', '-D', DISK], capture_output=True, text=True).stdout)
|
||||
START = ALIGN
|
||||
PART = 1
|
||||
print (f'START ({START}) SECTORS ({SECTORS}) PART ({PART})')
|
||||
|
||||
# Leer parámetros con definición de particionado.
|
||||
DELOPTIONS = []
|
||||
OPTIONS = []
|
||||
for p in parts:
|
||||
# Conservar los datos de la partición de caché.
|
||||
if f'{ND} {PART}' == CACHEPART and CACHESIZE:
|
||||
PART += 1
|
||||
|
||||
# Leer formato de cada parámetro - Tipo:Tamaño
|
||||
TYPE, SIZE = p.split (':')
|
||||
try:
|
||||
SIZE = int (SIZE)
|
||||
except ValueError:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, SIZE)
|
||||
return None
|
||||
|
||||
# Error si la partición es extendida (no válida en discos GPT).
|
||||
if 'EXTENDED' == TYPE:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'EXTENDED')
|
||||
return None
|
||||
|
||||
# Comprobar si existe la particion actual, capturamos su tamaño para ver si cambio o no
|
||||
PARTSIZE = ogGetPartitionSize (ND, PART)
|
||||
# En sgdisk no se pueden redimensionar las particiones, es necesario borrarlas y volver a crealas
|
||||
if PARTSIZE:
|
||||
DELOPTIONS.append (f'-d{PART}')
|
||||
|
||||
# Creamos la particion
|
||||
# Obtener identificador de tipo de partición válido.
|
||||
ID = ogTypeToId (TYPE, 'GPT')
|
||||
if 'CACHE' == TYPE or not ID:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, TYPE)
|
||||
return None
|
||||
# Comprobar tamaño numérico y convertir en sectores de 512 B.
|
||||
SIZE *= 2
|
||||
# SIZE debe ser múltiplo de ALIGN, si no gdisk lo mueve automáticamente.
|
||||
SIZE = (SIZE // ALIGN) * ALIGN
|
||||
|
||||
# Generar datos para la partición.
|
||||
# En el caso de que la partición sea EMPTY no se crea nada
|
||||
if 'EMPTY' != TYPE:
|
||||
OPTIONS += [f'-n{PART}:{START}:+{SIZE}', f'-t{PART}:{ID}']
|
||||
|
||||
START += SIZE
|
||||
|
||||
# Error si se supera el nº total de sectores.
|
||||
if START > SECTORS:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'{START//2} > {SECTORS//2}')
|
||||
return None
|
||||
|
||||
PART += 1
|
||||
|
||||
# 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, 'GPT')
|
||||
|
||||
# Definir particiones y notificar al kernel.
|
||||
p = subprocess.run (['sgdisk'] + DELOPTIONS + OPTIONS + [DISK], capture_output=True, text=True)
|
||||
print (f'sgdisk rc ({p.returncode}) stdout ({p.stdout}) stderr ({p.stderr})')
|
||||
subprocess.run (['partprobe', DISK])
|
||||
if CACHESIZE: CacheLib.ogMountCache()
|
||||
return not p.returncode
|
||||
|
||||
|
||||
#/**
|
||||
# ogCreatePartitionTable int_ndisk [str_tabletype]
|
||||
#@brief Genera una tabla de particiones en caso de que no sea valida, si es valida no hace nada.
|
||||
|
@ -431,7 +383,7 @@ def ogDevToDisk(arg_dev):
|
|||
|
||||
def _getAllDisks():
|
||||
ret = []
|
||||
all_disks = subprocess.run("lsblk -n -e 1,2 -x MAJ:MIN 2>/dev/null || lsblk -n -e 1,2", shell=True, capture_output=True, text=True).stdout.splitlines()
|
||||
all_disks = subprocess.run("lsblk -n -e 1,2 -x NAME 2>/dev/null || lsblk -n -e 1,2", shell=True, capture_output=True, text=True).stdout.splitlines()
|
||||
for line in all_disks:
|
||||
parts = line.split()
|
||||
if parts[5] == "disk":
|
||||
|
@ -785,9 +737,9 @@ def ogGetPartitionActive (disk):
|
|||
break
|
||||
|
||||
if lang is None:
|
||||
del os.environ['LANG']
|
||||
if 'LANG' in os.environ: del os.environ['LANG']
|
||||
else:
|
||||
os.environ['LAMG'] = lang
|
||||
os.environ['LANG'] = lang
|
||||
|
||||
return ret
|
||||
|
||||
|
@ -858,7 +810,7 @@ def ogGetPartitionSize (disk, par):
|
|||
#@return Devuelve el numero paritiones del disco duro indicado
|
||||
#@warning Salidas de errores no determinada
|
||||
#@attention Requisitos: parted
|
||||
#@note Notas sin especificar
|
||||
#@note Notas sin especificar
|
||||
#*/ ##
|
||||
def ogGetPartitionsNumber (disk):
|
||||
DISK = ogDiskToDev (disk)
|
||||
|
@ -1277,6 +1229,23 @@ def ogSetPartitionType (disk, par, t):
|
|||
#ogTypeToId ('LINUX', 'MSDOS') => "83"
|
||||
def ogTypeToId (type, pttype='MSDOS'):
|
||||
data = {
|
||||
'GPT_GUID': {
|
||||
## https://en.wikipedia.org/wiki/GUID_Partition_Table?useskin=vector
|
||||
'EMPTY': '0',
|
||||
'WINDOWS': 'EBD0A0A2-B9E5-4433-87C0-68B6B72699C7',
|
||||
'NTFS': 'EBD0A0A2-B9E5-4433-87C0-68B6B72699C7',
|
||||
'FAT32': 'EBD0A0A2-B9E5-4433-87C0-68B6B72699C7',
|
||||
'FAT16': 'EBD0A0A2-B9E5-4433-87C0-68B6B72699C7',
|
||||
'FAT12': 'EBD0A0A2-B9E5-4433-87C0-68B6B72699C7',
|
||||
'WIN-RESERV': 'E3C9E316-0B5C-4DB8-817D-F92DF00215AE',
|
||||
'LINUX-SWAP': '0657FD6D-A4AB-43C4-84E5-0933C84B4F4F',
|
||||
'LINUX': '0FC63DAF-8483-4772-8E79-3D69D8477DE4',
|
||||
'EXT2': '0FC63DAF-8483-4772-8E79-3D69D8477DE4',
|
||||
'EXT3': '0FC63DAF-8483-4772-8E79-3D69D8477DE4',
|
||||
'EXT4': '0FC63DAF-8483-4772-8E79-3D69D8477DE4',
|
||||
'CACHE': '0FC63DAF-8483-4772-8E79-3D69D8477DE4',
|
||||
'EFI': 'C12A7328-F81F-11D2-BA4B-00A0C93EC93B',
|
||||
},
|
||||
'GPT': {
|
||||
'EMPTY': '0',
|
||||
'WINDOWS': '0700',
|
||||
|
|
|
@ -635,7 +635,7 @@ def ogGetImageInfo (imgfile):
|
|||
if lc_all is not None:
|
||||
os.environ["LC_ALL"] = lc_all
|
||||
else:
|
||||
del os.environ["LC_ALL"]
|
||||
if "LC_ALL" in os.environ: del os.environ["LC_ALL"]
|
||||
|
||||
if 'size' in partclone_info:
|
||||
tools = 'PARTCLONE'
|
||||
|
|
|
@ -0,0 +1,352 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import os
|
||||
import glob
|
||||
import stat
|
||||
import shutil
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
import ogGlobals
|
||||
from InventoryLib import ogIsEfiActive
|
||||
from DiskLib import ogGetEsp
|
||||
from FileSystemLib import ogMount, ogUnmount
|
||||
|
||||
## sets envvar and writes to /etc/environment
|
||||
def env_export (k, v):
|
||||
os.environ[k] = str (v)
|
||||
already_present = False
|
||||
with open ('/etc/environment', 'r') as env_fd:
|
||||
for line in env_fd:
|
||||
if re.search (f'^{k}=', line):
|
||||
already_present = True
|
||||
break
|
||||
if not already_present:
|
||||
with open ('/etc/environment', 'a') as env_fd:
|
||||
env_fd.write (f'{k}={v}\n')
|
||||
return v
|
||||
|
||||
def loadenviron():
|
||||
# Idioma por defecto.
|
||||
LANG = os.environ.get ('LANG', 'es_ES')
|
||||
env_export ('LANG', 'es_ES')
|
||||
|
||||
# Directorios del proyecto OpenGnsys.
|
||||
OPENGNSYS = os.environ.get ('OPENGNSYS', '/opt/opengnsys')
|
||||
env_export ('OPENGNSYS', OPENGNSYS)
|
||||
|
||||
OGBIN = env_export ('OGBIN', f'{OPENGNSYS}/bin')
|
||||
OGETC = env_export ('OGETC', f'{OPENGNSYS}/etc')
|
||||
OGLIB = env_export ('OGLIB', f'{OPENGNSYS}/lib')
|
||||
OGAPI = env_export ('OGAPI', f'{OGLIB}/engine/bin')
|
||||
OGPYFUNCS = env_export ('OGPYFUNCS', f'{OPENGNSYS}/functions')
|
||||
OGSCRIPTS = env_export ('OGSCRIPTS', f'{OPENGNSYS}/scripts')
|
||||
OGIMG = env_export ('OGIMG', f'{OPENGNSYS}/images')
|
||||
OGCAC = env_export ('OGCAC', f'{OPENGNSYS}/cache')
|
||||
OGLOG = env_export ('OGLOG', f'{OPENGNSYS}/log')
|
||||
|
||||
# Exportar parámetros del kernel.
|
||||
with open ('/proc/cmdline', 'r') as fd: cmdline = fd.read()
|
||||
kvars = cmdline.split()
|
||||
for kvar in kvars:
|
||||
if '=' not in kvar: continue
|
||||
k, v = kvar.split ('=')
|
||||
env_export (k, v)
|
||||
|
||||
OGSERVERIMAGES = os.environ.get ('OGSERVERIMAGES', '')
|
||||
if 'ROOTREPO' not in os.environ or not os.environ.get ('ROOTREPO'):
|
||||
env_export ('ROOTREPO', OGSERVERIMAGES)
|
||||
|
||||
# Compatibilidad para usar proxy en clientes ogLive.
|
||||
http_proxy = os.environ.get ('http_proxy', '')
|
||||
ogproxy = os.environ.get ('ogproxy', '')
|
||||
if not http_proxy and ogproxy:
|
||||
env_export ('http_proxy', ogproxy)
|
||||
|
||||
def write_profile():
|
||||
## si estos accesos a os.environ fallan, es porque loadenviron() no se ejecutó
|
||||
OGSCRIPTS = os.environ['OGSCRIPTS']
|
||||
OGPYFUNCS = os.environ['OGPYFUNCS']
|
||||
OGBIN = os.environ['OGBIN']
|
||||
PYTHONPATH = os.environ['PYTHONPATH']
|
||||
LANG = os.environ['LANG']
|
||||
|
||||
PATH = os.environ.get ('PATH', '')
|
||||
|
||||
L = LANG[0:LANG.index('_')]
|
||||
with open ('/etc/profile.d/ogprofile.sh', 'w') as fd:
|
||||
fd.write (f'''
|
||||
(locale-gen {LANG} &>/dev/null &)
|
||||
export PATH={OGSCRIPTS}:{OGPYFUNCS}:{OGBIN}:{PATH}:/opt/oglive/rootfs/opt/drbl/sbin
|
||||
export PYTHONPATH={PYTHONPATH}
|
||||
sysctl -p &>/dev/null
|
||||
loadkeys {L} >/dev/null
|
||||
if [ ! -f /run/resolvconf/resolv.conf -a -n "$ogdns" ]; then
|
||||
mkdir -p /run/resolvconf
|
||||
echo "nameserver $ogdns" > /run/resolvconf/resolv.conf
|
||||
fi
|
||||
'''.strip() + '\n')
|
||||
|
||||
def clean_esp():
|
||||
## BootLib.bootOs() makes a copy of grub.cfg in /boot/grub within the ESP
|
||||
## clean it up
|
||||
if ogIsEfiActive():
|
||||
esp = ogGetEsp()
|
||||
if esp:
|
||||
esp_disk, esp_par = esp.split()
|
||||
mntpt = ogMount (esp_disk, esp_par)
|
||||
os.unlink (f'{mntpt}/boot/grub/grub.cfg')
|
||||
ogUnmount (esp_disk, esp_par)
|
||||
|
||||
def fileslinks():
|
||||
print (ogGlobals.lang.MSG_MAKELINKS)
|
||||
|
||||
# Shell BASH por defecto (para usar "runtest")
|
||||
if os.path.exists ('/bin/sh'): os.unlink ('/bin/sh')
|
||||
os.symlink ('/bin/bash', '/bin/sh')
|
||||
|
||||
# Crear directorio de bloqueos
|
||||
## for some reason we need try/catch even when using 'exist_ok=True'
|
||||
try: os.makedirs ('/var/lock', exist_ok=True)
|
||||
except FileExistsError: pass
|
||||
try: os.makedirs ('/run/lock', exist_ok=True)
|
||||
except FileExistsError: pass
|
||||
|
||||
# Crear ficheros temporales.
|
||||
for f in [ogGlobals.OGLOGCOMMAND, ogGlobals.OGLOGCOMMAND + '.tmp', ogGlobals.OGLOGSESSION, '/tmp/menu.tmp']:
|
||||
open (f, 'w').close()
|
||||
os.chmod (f, 0o777)
|
||||
|
||||
# Enlaces para Qt Embeded.
|
||||
# son cosas de QT4, ya no aplica
|
||||
|
||||
# Autenticación con clave pública para SSH
|
||||
if os.path.exists ('/scripts/ssl/authorized_keys'):
|
||||
for f in glob.glob ('/scripts/ssl/*'):
|
||||
shutil.copy2 (f, '/root/.ssh/')
|
||||
|
||||
def loadmodules():
|
||||
print (ogGlobals.lang.MSG_LOADMODULES)
|
||||
|
||||
# Módulo del ratón.
|
||||
subprocess.run (['modprobe', 'psmouse'], stderr=subprocess.DEVNULL)
|
||||
|
||||
# Cargar módulos específicos del kernel del cliente.
|
||||
uname_r = os.uname()[2]
|
||||
for m in glob.glob (f'{ogGlobals.OGLIB}/modules/{uname_r}/*.ko'):
|
||||
subprocess.run (['insmod', m], capture_output=True)
|
||||
|
||||
def metadevs():
|
||||
print (ogGlobals.lang.MSG_DETECTLVMRAID)
|
||||
subprocess.run (['vgchange', '-ay'], capture_output=True) # Detectar metadispositivos LVM.
|
||||
subprocess.run (['dmraid', '-ay'], capture_output=True) # Detectar metadispositivos RAID.
|
||||
|
||||
def mountrepo():
|
||||
## si estos accesos a os.environ fallan, es porque loadenviron() no se ejecutó
|
||||
ROOTREPO = os.environ['ROOTREPO']
|
||||
|
||||
ROOTSERVER = os.environ.get ('ROOTSERVER', '')
|
||||
ogactiveadmin = os.environ.get ('ogactiveadmin', '')
|
||||
ogprotocol = os.environ.get ('ogprotocol', '')
|
||||
ogstatus = os.environ.get ('ogstatus', '')
|
||||
SERVER = os.environ.get ('SERVER', '')
|
||||
if not ROOTREPO: ROOTREPO = ROOTSERVER
|
||||
|
||||
# TODO Revisar proceso de arranque para no montar 2 veces el repositorio.
|
||||
if 'true' == ogactiveadmin:
|
||||
os.environ['boot'] = 'admin' # ATENCIÓN: siempre en modo "admin".
|
||||
subprocess.run (['umount', ogGlobals.OGIMG], stderr=subprocess.DEVNULL)
|
||||
|
||||
if 'nfs' == ogprotocol:
|
||||
subprocess.run (['mount.nfs', f'{ROOTREPO}:{ogGlobals.OGIMG}', ogGlobals.OGIMG, '-o', 'rw,nolock'])
|
||||
|
||||
elif 'smb' == ogprotocol:
|
||||
PASS = subprocess.run ('grep "^[ \t]*\\(export \\)\\?OPTIONS=" /scripts/ogfunctions 2>&1 | sed "s/\\(.*\\)pass=\\(\\w*\\)\\(.*\\)/\\2/"', shell=True, capture_output=True, text=True).stdout.strip()
|
||||
if not PASS: PASS = 'og'
|
||||
subprocess.run (['mount.cifs', f'//{ROOTREPO}/ogimages', ogGlobals.OGIMG, '-o', f'rw,serverino,acl,username=opengnsys,password={PASS}'])
|
||||
|
||||
elif 'local' == ogprotocol: # TODO: hacer funcion dentro de este script que monte smb
|
||||
# Comprobamos que estatus sea online.
|
||||
if 'offline' == ogstatus or '' == SERVER:
|
||||
# Si estatus es offline buscamos un dispositivo con etiqueta repo
|
||||
# y si no existe montamos la cache como repo (si existe).
|
||||
TYPE = subprocess.run ('blkid | grep REPO | awk -F"TYPE=" \'{print $2}\' | tr -d \\"', shell=True, capture_output=True, text=True).stdout.strip()
|
||||
if '' == TYPE:
|
||||
cac_img = f'{ogGlobals.OGCAC}/{ogGlobals.OGIMG}'
|
||||
if os.path.isdir (cac_img):
|
||||
subprocess.run (['mount', '--bind', cac_img, ogGlobals.OGIMG])
|
||||
else:
|
||||
subprocess.run (['mount', '-t', TYPE, 'LABEL=REPO', ogGlobals.OGIMG])
|
||||
else:
|
||||
# Comprobamos que existe un servicio de samba.
|
||||
rc = subprocess.run (['smbclient', '-L', SERVER, '-N'], capture_output=True, text=True).returncode
|
||||
if not rc: ## success
|
||||
PASS = subprocess.run ('grep "^[ \t]*\\(export \\)\\?OPTIONS=" /scripts/ogfunctions 2>&1 | sed "s/\\(.*\\)pass=\\(\\w*\\)\\(.*\\)/\\2/"', shell=True, capture_output=True, text=True).stdout.strip()
|
||||
if not PASS: PASS = 'og'
|
||||
subprocess.run (['mount.cifs', f'//{ROOTREPO}/ogimages', ogGlobals.OGIMG, '-o', f'rw,serverino,acl,username=opengnsys,password={PASS}'])
|
||||
|
||||
def poweroff():
|
||||
ogntp = os.environ.get ('ogntp', '')
|
||||
status = os.environ.get ('status', '')
|
||||
|
||||
print (ogGlobals.lang.MSG_POWEROFFCONF)
|
||||
# Sincronización horaria con servidor NTP.
|
||||
if ogntp and 'offline' != status:
|
||||
subprocess.run (['ntpdate', ogntp])
|
||||
|
||||
# Crear fichero de configuración por defecto (30 min. de espera).
|
||||
POWEROFFCONF = '/etc/poweroff.conf'
|
||||
with open (POWEROFFCONF, 'w') as fd:
|
||||
fd.write (f'''
|
||||
POWEROFFSLEEP=30
|
||||
POWEROFFTIME=
|
||||
'''.strip() + '\n')
|
||||
# Incluir zona horaria en el fichero de configuración.
|
||||
awk_out = subprocess.run (['awk', 'BEGIN {RS=" "} /^TZ=/ {print}', '/proc/cmdline'], capture_output=True, text=True).stdout.strip()
|
||||
with open (POWEROFFCONF, 'a') as fd:
|
||||
fd.write (awk_out + '\n')
|
||||
|
||||
# Lanzar el proceso "cron".
|
||||
subprocess.run (['cron', '-l'])
|
||||
|
||||
# Definir la "crontab" lanzando el proceso de comprobación cada minuto.
|
||||
crontab_entry = f'* * * * * [ -x {ogGlobals.OGBIN}/poweroffconf ] && {ogGlobals.OGBIN}/poweroffconf\n'
|
||||
subprocess.run (['crontab', '-'], input=crontab_entry, text=True)
|
||||
|
||||
def filebeat():
|
||||
oglog = os.environ.get ('oglog', '')
|
||||
F = '/etc/filebeat/filebeat.yml'
|
||||
OPENSEARCH_PORT = '9200'
|
||||
|
||||
if not os.path.exists (F): return
|
||||
|
||||
PASS = subprocess.run ('grep "^[ \t]*\\(export \\)\\?OPTIONS=" /scripts/ogfunctions 2>&1 | sed "s/\\(.*\\)pass=\\(\\w*\\)\\(.*\\)/\\2/"', shell=True, capture_output=True, text=True).stdout.strip() ## taken from a sibling script
|
||||
if not PASS: PASS = 'og'
|
||||
ogkdf = subprocess.run (f'echo -n {PASS} |sha256sum |cut -c1-12', shell=True, capture_output=True, text=True).stdout.strip()
|
||||
PASS = 'OG+' + ogkdf
|
||||
|
||||
os.chmod (F, 0o600)
|
||||
subprocess.run (['sed', '-i',
|
||||
'-e', f's/__OGLOG_IP/{oglog}/g',
|
||||
'-e', f's/__OGLOG_PORT__/{OPENSEARCH_PORT}/g',
|
||||
'-e', f's/__OPENSEARCH_PASSWORD__/{PASS}/g',
|
||||
F
|
||||
])
|
||||
|
||||
os.makedirs ('/var/log/filebeat', exist_ok=True)
|
||||
subprocess.Popen (['/usr/bin/filebeat', '-c', F, '--path.home', '/usr/share/filebeat', '--path.config', '/etc/filebeat', '--path.data', '/var/lib/filebeat', '--path.logs', '/var/log/filebeat'])
|
||||
|
||||
def stunnel():
|
||||
ogcore = os.environ.get ('ogcore', '')
|
||||
ogusetls = os.environ.get ('ogusetls', '')
|
||||
ogverifytls = os.environ.get ('ogverifytls', '')
|
||||
|
||||
with open ('/etc/stunnel/menu.conf', 'w') as fd: fd.write (f'''
|
||||
setuid = stunnel4
|
||||
setgid = stunnel4
|
||||
pid = /var/run/stunnel4/menu.pid
|
||||
foreground = yes
|
||||
debug = info
|
||||
|
||||
[menu]
|
||||
client = yes
|
||||
accept = 127.0.0.1:81
|
||||
connect = {ogcore}:8443
|
||||
'''.strip() + '\n')
|
||||
if 'true' == ogusetls:
|
||||
if 'true' == ogverifytls:
|
||||
## use tls and verify
|
||||
with open ('/etc/stunnel/menu.conf', 'a') as fd: fd.write (f'''
|
||||
cert = /opt/opengnsys/etc/ogagent.crt
|
||||
key = /opt/opengnsys/etc/ogagent.key
|
||||
CAfile = /opt/opengnsys/etc/ca.crt
|
||||
requireCert = yes
|
||||
verifyChain = yes
|
||||
'''.strip() + '\n')
|
||||
else:
|
||||
## use tls but not verify
|
||||
with open ('/etc/stunnel/menu.conf', 'a') as fd: fd.write (f'''
|
||||
cert = /opt/opengnsys/etc/ogagent.crt
|
||||
key = /opt/opengnsys/etc/ogagent.key
|
||||
CAfile = /opt/opengnsys/etc/ca.crt
|
||||
requireCert = no
|
||||
verifyChain = no
|
||||
'''.strip() + '\n')
|
||||
else:
|
||||
## don't use tls
|
||||
with open ('/etc/stunnel/menu.conf', 'a') as fd: fd.write (f'''
|
||||
requireCert = no
|
||||
verifyChain = no
|
||||
'''.strip() + '\n')
|
||||
|
||||
os.makedirs ('/var/run/stunnel4', exist_ok=True)
|
||||
shutil.chown ('/var/run/stunnel4', 'stunnel4', 'stunnel4')
|
||||
with open ('/var/log/stunnel4/menu.log', 'a') as stunnel_log_fd:
|
||||
subprocess.Popen (['stunnel', '/etc/stunnel/menu.conf'], stdout=stunnel_log_fd, stderr=subprocess.STDOUT)
|
||||
|
||||
def dbus():
|
||||
if os.path.exists ('/etc/dbus-1/system.d/ogbrowser.conf'):
|
||||
os.makedirs ('/run/dbus', exist_ok=True)
|
||||
dbus_addr = subprocess.run (['dbus-daemon', '--print-address', '--system', '--nosyslog'], capture_output=True, text=True).stdout.strip()
|
||||
env_export ('DBUS_SESSION_BUS_ADDRESS', dbus_addr)
|
||||
with open ('/var/log/dbus-monitor.log', 'w') as dbus_mon_fd:
|
||||
subprocess.Popen (['dbus-monitor', '--system'], stdout=dbus_mon_fd, stderr=subprocess.STDOUT)
|
||||
|
||||
def otherservices():
|
||||
DEVICE = os.environ.get ('DEVICE', '')
|
||||
|
||||
if ogIsEfiActive():
|
||||
subprocess.run (['mount', '-t', 'efivarfs', 'none', '/sys/firmware/efi/efivars'])
|
||||
|
||||
print (ogGlobals.lang.MSG_OTHERSERVICES)
|
||||
|
||||
if os.path.exists ('/dev/log') and not stat.S_ISSOCK (os.stat ('/dev/log').st_mode):
|
||||
subprocess.run (['service', 'rsyslog', 'start'])
|
||||
|
||||
# root password
|
||||
PASS = subprocess.run ('grep "^[ \t]*\\(export \\)\\?OPTIONS=" /scripts/ogfunctions 2>&1 | sed "s/\\(.*\\)pass=\\(\\w*\\)\\(.*\\)/\\2/"', shell=True, capture_output=True, text=True).stdout.strip()
|
||||
if not PASS: PASS = 'og'
|
||||
subprocess.run (['passwd', 'root'], input=f'{PASS}\n{PASS}\n', stderr=subprocess.DEVNULL, text=True)
|
||||
|
||||
subprocess.run (['/etc/init.d/ssh', 'start'], capture_output=True, text=True)
|
||||
|
||||
#setterm -blank 0 -powersave off -powerdown 0 < /dev/console > /dev/console 2>&1 ## apagado de monitor
|
||||
subprocess.run (['ethtool', '-s', DEVICE, 'wol', 'g'], stderr=subprocess.DEVNULL) ## Activado WOL en la interfaz usada en arranque PXE.
|
||||
|
||||
def runhttplog():
|
||||
## si estos accesos a os.environ fallan, es porque loadenviron() no se ejecutó
|
||||
OPENGNSYS = os.environ['OPENGNSYS']
|
||||
|
||||
try:
|
||||
shutil.copy2 ('/etc/lighttpd/lighttpd.conf', '/etc/lighttpd/lighttpd.conf.back')
|
||||
shutil.copy2 ('/etc/lighttpd/conf-enabled/10-cgi.conf', '/etc/lighttpd/conf-enabled/10-cgi.conf.back')
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
shutil.copy2 (f'{OPENGNSYS}/lib/httpd/lighttpd.conf', '/etc/lighttpd/')
|
||||
shutil.copy2 (f'{OPENGNSYS}/lib/httpd/10-cgi.conf', '/etc/lighttpd/conf-enabled/')
|
||||
|
||||
subprocess.run (['/etc/init.d/lighttpd', 'start'], capture_output=True)
|
||||
|
||||
o = OPENGNSYS
|
||||
while '/' != o:
|
||||
os.chmod (o, 0o755)
|
||||
o = os.path.dirname (o)
|
||||
os.makedirs ('/usr/lib/cgi-bin', exist_ok=True)
|
||||
|
||||
for filename in os.listdir (f'{OPENGNSYS}/lib/httpd/'):
|
||||
full_file_name = os.path.join (f'{OPENGNSYS}/lib/httpd/', filename)
|
||||
if os.path.isfile (full_file_name):
|
||||
shutil.copy2 (full_file_name, '/usr/lib/cgi-bin')
|
||||
|
||||
## dstat fails because /var/lib/pcp/pmns/root does not exist.
|
||||
## we work around that by starting/stopping pmcd once. When it starts, it creates the missing file.
|
||||
if not os.path.exists ('/var/lib/pcp/pmns/root'):
|
||||
subprocess.run (['/etc/init.d/pmcd', 'start'], capture_output=True)
|
||||
subprocess.run (['/etc/init.d/pmcd', 'stop'], capture_output=True)
|
||||
|
||||
with open ('/tmp/bandwidth', 'w') as f:
|
||||
subprocess.Popen (['dstat', '-dn', '10'], stdout=f)
|
||||
|
||||
with open (ogGlobals.OGLOGSESSION, 'a') as fd:
|
||||
fd.write ('WAITING\n')
|
|
@ -255,7 +255,7 @@ def ogGetRepoIp():
|
|||
#@note Comprobacion segun protocolo de conexion al Repo
|
||||
#*/ ##
|
||||
def ogGetServerIp():
|
||||
return os.environ['ogcore']
|
||||
return os.environ.get ('ogcore', '')
|
||||
|
||||
#/**
|
||||
# ogGetServerPort
|
||||
|
@ -263,10 +263,7 @@ def ogGetServerIp():
|
|||
#@return str_port - Puerto
|
||||
#*/ ##
|
||||
def ogGetServerPort():
|
||||
if 'ogcore_port' in os.environ:
|
||||
return os.environ['ogcore_port']
|
||||
else:
|
||||
return '8443'
|
||||
return os.environ.get ('ogcore_port', '8443')
|
||||
|
||||
|
||||
#/**
|
||||
|
|
|
@ -224,7 +224,6 @@ def ogUcastSendFile (disk=None, par=None, container=None, file=None, sess=None):
|
|||
return
|
||||
|
||||
path2 = FileLib.ogGetPath (file=source)
|
||||
print (f'nati path2 ({path2})')
|
||||
if not path2:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found')
|
||||
return
|
||||
|
@ -483,7 +482,6 @@ def ogMcastSendFile (disk=None, par=None, container=None, file=None, sess=None):
|
|||
return
|
||||
|
||||
path2 = FileLib.ogGetPath (file=source)
|
||||
print (f'nati path2 ({path2})')
|
||||
if not path2:
|
||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found')
|
||||
return
|
||||
|
|
|
@ -178,7 +178,7 @@ def ogGetCaller():
|
|||
caller = words[0].lstrip("-")
|
||||
|
||||
if cols is None:
|
||||
del (os.environ['COLUMNS'])
|
||||
if 'COLUMNS' in os.environ: del os.environ['COLUMNS']
|
||||
else:
|
||||
os.environ['COLUMNS'] = cols
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ MCASTWAIT=30 # timeout (segundos) para abortar la la tran
|
|||
#FACTORSYNC=120 # Factor de compresion para las imagenes (windos en ext4).
|
||||
#BACKUP=False # Realizar copia de seguridad antes de crear la imagen.
|
||||
#IMGFS='EXT4' # Sistema de archivo de la imagenes sincronizadas. EXT4 o BTRFS
|
||||
#OGSLEEP=20 # Tiempo de sleep antes de realizar el reboot
|
||||
OGSLEEP=4 # Tiempo de sleep antes de realizar el reboot
|
||||
NODEBUGFUNCTIONS=['ogCreateImageSyntax', 'ogGetHivePath', 'ogGetOsType', 'ogRestoreImageSyntax', 'ogUnmountAll', 'ogUnmountCache'] # Funciones que no deben mostrar salida de avisos si son llamadas por otras funciones.
|
||||
#DEFAULTSPEED=''
|
||||
## /engine.cfg
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
bootOs
|
|
@ -1 +0,0 @@
|
|||
bootOs
|
|
@ -50,6 +50,8 @@ def main (NDISK, NPART, SIZE, MOUNT):
|
|||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_CACHE, 'failed to create cache')
|
||||
return False
|
||||
DiskLib.ogUpdatePartitionTable()
|
||||
else:
|
||||
print("[10] Partición de caché solicitada es del mismo tamaño que la existente, ignorar.")
|
||||
|
||||
# Si caché no montada y no formateada o cambia el tamaño: formatear.
|
||||
cache = CacheLib.ogFindCache()
|
||||
|
|
|
@ -1,39 +1,74 @@
|
|||
#!/bin/bash
|
||||
# Scirpt de ejemplo para apagar un ordenador
|
||||
# Nota: se usa como base para el programa de apagado de OpenGnsys Admin.
|
||||
#!/usr/bin/python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
# Registrar ejecución manual de script.
|
||||
case "$(ogGetCaller)" in
|
||||
browser|bash) ogEcho log info "Script: $0" ;;
|
||||
esac
|
||||
import ogGlobals
|
||||
from SystemLib import ogGetCaller, ogEcho
|
||||
from DiskLib import ogDiskToDev
|
||||
from FileSystemLib import ogUnmountAll
|
||||
from CacheLib import ogUnmountCache
|
||||
|
||||
DEVICE = os.environ.get ('DEVICE', '')
|
||||
ogstatus = os.environ.get ('ogstatus', '')
|
||||
|
||||
PROG = os.path.basename (sys.argv[0])
|
||||
is_reboot = 'reboot'==PROG
|
||||
|
||||
TIME = None
|
||||
try:
|
||||
TIME = int (sys.argv[1])
|
||||
except:
|
||||
pass
|
||||
|
||||
# Registrar ejecución manual de script.
|
||||
c = ogGetCaller()
|
||||
if c in ['browser', 'OGBrowser', 'bash']:
|
||||
ogEcho ('log', 'info', f'Script: {PROG}')
|
||||
|
||||
# Cargamos el valor por defecto del tiempo de sleep
|
||||
if TIME:
|
||||
print (f'[5] Se ha introducido un retardo de {TIME} segundos para reiniciar')
|
||||
else:
|
||||
TIME = ogGlobals.OGSLEEP
|
||||
print (f'[5] No se ha introducido un retardo, {TIME} segundos para reiniciar')
|
||||
|
||||
# No registrar errores.
|
||||
export DEBUG="no"
|
||||
#DEBUG=no
|
||||
|
||||
# Desmontar los sistemas de archivos y la caché local.
|
||||
echo "[10] Desmontar todos los sistemas de archivos."
|
||||
sync
|
||||
for (( i=1; i <= $(ogDiskToDev | wc -w); i++ )); do
|
||||
ogUnmountAll $i &>/dev/null
|
||||
done
|
||||
echo "[50] Desmontar cache local."
|
||||
ogUnmountCache &>/dev/null
|
||||
print ('[10] Desmontar todos los sistemas de archivos.')
|
||||
subprocess.run (['sync'])
|
||||
ndisks = len (ogDiskToDev())
|
||||
for d in range (1, ndisks+1):
|
||||
ogUnmountAll (d)
|
||||
print ('[50] Desmontar cache local.')
|
||||
ogUnmountCache()
|
||||
|
||||
# Volver a registrar errores.
|
||||
unset DEBUG
|
||||
#DEBUG=yes
|
||||
|
||||
echo "[70] Apagando el equipo."
|
||||
if is_reboot:
|
||||
print ('[90] Reiniciar el equipo.')
|
||||
else:
|
||||
print ('[70] Apagando el equipo.')
|
||||
# Estado correcto de Wake-On-Lan antes de apagar.
|
||||
ethtool -s $DEVICE wol g 2>/dev/null
|
||||
subprocess.run (['ethtool', '-s', DEVICE, 'wol', 'g'], stderr=subprocess.DEVNULL)
|
||||
# Detectar Busybox.
|
||||
BUSYBOX=$(which busyboxOLD)
|
||||
BUSYBOX=${BUSYBOX:-"busybox"}
|
||||
BUSYBOX = shutil.which ('busyboxOLD')
|
||||
if not BUSYBOX: BUSYBOX = shutil.which ('busybox')
|
||||
|
||||
# Retardo para dar lugar al registro en cola de acciones.
|
||||
sleep 5
|
||||
time.sleep (TIME)
|
||||
# Parar Browser para evitar "cuelgues".
|
||||
[ "$ogstatus" == "offline" ] || pkill browser
|
||||
if 'offline' != ogstatus:
|
||||
subprocess.run (['killall', 'QtWebEngineProcess', 'OGBrowser', 'i3', 'sway', 'Xorg', 'startx'], stderr=subprocess.DEVNULL)
|
||||
# Apagar.
|
||||
$BUSYBOX poweroff
|
||||
|
||||
if is_reboot:
|
||||
subprocess.run ([BUSYBOX, 'reboot'])
|
||||
else:
|
||||
subprocess.run ([BUSYBOX, 'poweroff'])
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Script de ejemplo para reiniciar un ordenador
|
||||
# Nota: se usa como base para el programa de reinicio de OpenGnsys Admin.
|
||||
|
||||
|
||||
# Registrar ejecución manual de script.
|
||||
case "$(ogGetCaller)" in
|
||||
browser|bash) ogEcho log info "Script: $0" ;;
|
||||
esac
|
||||
|
||||
# Cargamos el valor por defecto del tiempo de sleep
|
||||
[ -z $OGSLEEP ] && source /opt/opengnsys/etc/engine.cfg
|
||||
|
||||
# Si se recibe un parametro sera el tiempo de sleep antes de realizar el reboot
|
||||
if [ $# == 1 ] && [ "${1//[^0-9]/}" == "$1" ]
|
||||
then
|
||||
TIME=$1
|
||||
echo "[5] Se ha introducido un retardo de $TIME segundos para reiniciar"
|
||||
else
|
||||
# Sin parámetros, o el parámetro introducido no es un número
|
||||
TIME=${OGSLEEP:-5}
|
||||
echo "[5] No se ha introducido un retardo, $TIME segundos para reiniciar"
|
||||
fi
|
||||
|
||||
# No registrar errores.
|
||||
export DEBUG="no"
|
||||
|
||||
# Desmontar los sistemas de archivos y la caché local.
|
||||
echo "[10] Desmontar todos los sistemas de archivos."
|
||||
sync
|
||||
for (( i=1; i <= $(ogDiskToDev | wc -w); i++ )); do
|
||||
ogUnmountAll $i &>/dev/null
|
||||
done
|
||||
echo "[50] Desmontar cache local."
|
||||
ogUnmountCache &>/dev/null
|
||||
|
||||
# Volver a registrar errores.
|
||||
unset DEBUG
|
||||
|
||||
echo "[90] Reiniciar el equipo."
|
||||
# Estado correcto de Wake-On-Lan antes de reiniciar.
|
||||
ethtool -s $DEVICE wol g 2>/dev/null
|
||||
# Detectar Busybox.
|
||||
BUSYBOX=$(which busyboxOLD)
|
||||
BUSYBOX=${BUSYBOX:-"busybox"}
|
||||
|
||||
# Retardo para dar lugar al registro en cola de acciones.
|
||||
sleep $TIME
|
||||
# Parar Browser para evitar "cuelgues".
|
||||
[ "$ogstatus" == "offline" ] || pkill browser
|
||||
# Reiniciar.
|
||||
$BUSYBOX reboot
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
poweroff
|
|
@ -1,38 +0,0 @@
|
|||
import shutil
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
def main():
|
||||
# Copy lighttpd.conf
|
||||
shutil.copy('/etc/lighttpd/lighttpd.conf', '/etc/lighttpd/lighttpd.conf.back')
|
||||
shutil.copy('/opt/opengnsys/lib/httpd/lighttpd.conf', '/etc/lighttpd/')
|
||||
|
||||
# Copy 10-cgi.conf
|
||||
shutil.copy('/etc/lighttpd/conf-enabled/10-cgi.conf', '/etc/lighttpd/conf-enabled/10-cgi.conf.back')
|
||||
shutil.copy('/opt/opengnsys/lib/httpd/10-cgi.conf', '/etc/lighttpd/conf-enabled/')
|
||||
|
||||
# Start lighttpd service
|
||||
subprocess.run(['/etc/init.d/lighttpd', 'start'])
|
||||
|
||||
# Change permissions and create directories
|
||||
os.chmod('/opt', 0o755)
|
||||
os.makedirs('/usr/lib/cgi-bin', exist_ok=True)
|
||||
|
||||
# Copy files to /usr/lib/cgi-bin
|
||||
for filename in os.listdir('/opt/opengnsys/lib/httpd/'):
|
||||
full_file_name = os.path.join('/opt/opengnsys/lib/httpd/', filename)
|
||||
if os.path.isfile(full_file_name):
|
||||
shutil.copy(full_file_name, '/usr/lib/cgi-bin')
|
||||
|
||||
# Run dstat command
|
||||
with open('/tmp/bandwidth', 'w') as f:
|
||||
subprocess.Popen(['dstat', '-dn', '10'], stdout=f)
|
||||
|
||||
# Append "WAITING" to OGLOGSESSION
|
||||
oglogsession = os.getenv('OGLOGSESSION')
|
||||
if oglogsession:
|
||||
with open(oglogsession, 'a') as f:
|
||||
f.write("WAITING\n")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue