Compare commits

..

No commits in common. "main" and "ogkdf" have entirely different histories.
main ... ogkdf

28 changed files with 2778 additions and 959 deletions

View File

@ -5,48 +5,6 @@ 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.30.0] - 2025-07-17
### Added
- Add script for getting data out of deployed git images
## [0.29.0] - 2025-07-17
### Changed
- Now Configurar.py takes a third parameter: whether just check stuff or not
## [0.28.0] - 2025-07-17
### Changed
- Use python init scripts by default
## [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

View File

@ -1,49 +0,0 @@
#!/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'])

View File

@ -1,43 +0,0 @@
#!/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'])

View File

@ -1,12 +1,5 @@
#!/bin/bash
if grep -q pyinit=false /proc/cmdline; then
echo "shell init"
else
echo "python init"
exec /opt/opengnsys/etc/preinit.py
fi
# Cargar entorno de OpenGnsys
set -a
source /opt/opengnsys/etc/preinit/loadenviron.sh

View File

@ -2,6 +2,7 @@
import os
import sys
import subprocess
import ogGlobals
import SystemLib
@ -10,6 +11,11 @@ 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()
@ -18,24 +24,39 @@ 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__)
param = sys.argv[2]
check_sizes = False
if len (sys.argv) >= 4:
check_sizes = 'true' == sys.argv[3]
#____________________________________________________________________
#
# 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 ('*')
tbprm = pparam.split ('*')
dis = tch = None
for item in pparams:
for item in tbprm:
if '=' not in item: continue
k, v = item.split ('=', 1)
@ -53,13 +74,10 @@ if dis is None:
tbp = [] # Valores de configuración (parámetros para ogCreatePartitions)
tbf = {} # Tabla de formateo
sparams = sparam.split('%')
tbprm = sparam.split('%')
maxp=0
sum_tam = 0
do_sum_tam = True
cache_seen = extended_seen = efi_seen = False
for item in sparams:
for item in tbprm:
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
@ -75,7 +93,7 @@ for item in sparams:
if 'par' == k: par = int (v)
elif 'cpt' == k: cpt = v
elif 'sfi' == k: sfi = v
elif 'tam' == k: tam = int (v)
elif 'tam' == k: tam = v
elif 'ope' == k: ope = int (v)
missing_params = []
@ -88,29 +106,10 @@ for item in sparams:
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']:
@ -119,91 +118,7 @@ for item in sparams:
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)
if check_sizes: sys.exit (0)
tch = '0'
#____________________________________________________
#
@ -218,46 +133,53 @@ SystemLib.ogEcho (['session', 'log'], None, f'[10] {ogGlobals.lang.MSG_HELP_ogUn
FileSystemLib.ogUnmountAll (dis)
CacheLib.ogUnmountCache()
if recreate_partition_table:
# 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:
DiskLib.ogDeletePartitionTable (dis)
SystemLib.ogExecAndLog ('command', [f'{ogGlobals.OGPYFUNCS}/ogUpdatePartitionTable'])
DiskLib.ogCreatePartitionTable (dis, ptt)
# Inicia la cache.
if is_there_cache:
if 'CACHE' in sparam:
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)])
SystemLib.ogEcho (['session', 'log'], None, f' initCache {tch}')
rc = SystemLib.ogExecAndLog ('command', [f'{ogGlobals.OGSCRIPTS}/initCache', tch])
if not rc:
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_CACHE, f'initCache.py failed')
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_CACHE, f'initCache 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'])
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'])
# Formatear particiones
SystemLib.ogEcho (['session', 'log'], None, f'[70] {ogGlobals.lang.MSG_HELP_ogFormat}')
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)
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
SystemLib.ogEcho (['session', 'log'], None, f'{ogGlobals.lang.MSG_INTERFACE_END} {retval}')
#___________________________________________________________________
#
# Retorno
#___________________________________________________________________
sys.exit (0)

View File

@ -1,53 +0,0 @@
#!/usr/bin/python3
import os
import sys
import subprocess
import ogGlobals
from SystemLib import ogEcho, ogRaiseError
from FileSystemLib import ogMount
prog = sys.argv[0]
if len (sys.argv) != 4:
print (f'Usage: {prog} <dsk> <par> <tmpfile>')
sys.exit (1)
dsk = sys.argv[1]
par = sys.argv[2]
tmpfile = sys.argv[3]
# Registro de inicio de ejecución
ogEcho (['log', 'session'], None, f'{ogGlobals.lang.MSG_INTERFACE_START} {prog} {dsk} {par} {tmpfile}')
mntpt = ogMount (dsk, par)
git_dir = f'{mntpt}/.git'
if not os.path.isdir (git_dir):
ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_FORMAT, f'"{git_dir}" no existe o no es un directorio')
sys.exit (1)
p = subprocess.run (['git', '--git-dir', git_dir, 'branch', '--show-current'], capture_output=True, text=True)
rc = p.returncode
if 0 != rc:
ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_GENERIC, '')
ogEcho (['log', 'session'], 'error', p.stderr)
sys.exit (1)
branch = p.stdout.strip()
p = subprocess.run (['git', '--git-dir', git_dir, 'remote', 'get-url', 'origin'], capture_output=True, text=True)
rc = p.returncode
if 0 != rc:
ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_GENERIC, '')
ogEcho (['log', 'session'], 'error', p.stderr)
sys.exit (1)
repo = os.path.basename (p.stdout.strip())
repo = repo.replace ('.git', '')
with open (tmpfile, 'w') as fd:
fd.write (f'{branch}:{repo}\n')
# Registro de fin de ejecución
ogEcho (['log', 'session'], None, f'{ogGlobals.lang.MSG_INTERFACE_END} 0')
sys.exit (0)

View File

@ -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}' ## shutil sucks a bit for copying both files and dirs
cp_cmd = f'cp {ogGlobals.OGLIB}/grub4dos/* {mntdir}'
subprocess.run (cp_cmd, shell=True)
disk0 = int(disk)-1
par0 = int(par)-1

View File

@ -37,15 +37,16 @@ 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 = DiskLib.ogGetIoSize (ndsk)
if not IOSIZE:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Failed to get disk sector size')
return None
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
START = 0
if 4096 == IOSIZE:
END -= 8192
@ -69,7 +70,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_FORMAT, f'size ({SIZE}) < minsize ({MINSIZE}) or size ({SIZE}) > maxsize ({MAXSIZE}) or start ({START}) < endprevpart ({ENDPREVPART})')
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, f'size ({SIZE}) < minsize ({MINSIZE}) or size > maxsize ({MAXSIZE}) or start ({START}) < endprevpart ({ENDPREVPART})')
return None
# Desmontar todos los sistemas de archivos del disco.
@ -89,32 +90,27 @@ 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()
ID = DiskLib.ogTypeToId ('LINUX', 'GPT_GUID')
sfdisk_line = f'{DISK}{NVME_PREFIX}{part} : start= {START}, size= {SIZE}, type={ID}, name=CACHE'
# 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}'])
elif 'MSDOS' == get_ptt:
# Si la tabla de particiones no es valida, volver a generarla.
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)
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.
ID = DiskLib.ogTypeToId ('CACHE', 'MSDOS')
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)
# 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)
# Actualiza la tabla de particiones en el kernel.
DiskLib.ogUpdatePartitionTable()
return True
@ -143,15 +139,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], capture_output=True).returncode: ## if True, then sgdisk failed
subprocess.run (['gdisk', disk], input='2\nw\nY\n', text=True, capture_output=True)
if subprocess.run (['sgdisk', '-p', disk]).returncode: ## if True, then sgdisk failed
subprocess.run (['gdisk', disk], input='2\nw\nY\n', text=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'], capture_output=True).returncode: ## if True, then parted failed
subprocess.run (['fdisk', disk], input='w', text=True, capture_output=True)
if subprocess.run (['parted', '-s', disk, 'print']).returncode: ## if True, then parted failed
subprocess.run (['fdisk', disk], input='w', text=True)
# Eliminar la partición de caché.
subprocess.run (['fdisk', disk], input=f'd\n{npart}\nw', text=True, capture_output=True)
subprocess.run (['fdisk', disk], input=f'd\n{npart}\nw', text=True)
# Borrar etiqueta de la caché.
if os.path.exists ('/dev/disk/by-label/CACHE'):
os.unlink ('/dev/disk/by-label/CACHE')
@ -362,46 +358,3 @@ 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

View File

@ -38,32 +38,6 @@ 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.
@ -87,11 +61,12 @@ def ogCreatePartitions (disk, parts):
PTTYPE = ogGetPartitionTableType (disk)
if not PTTYPE: PTTYPE = 'MSDOS' # Por defecto para discos vacíos.
if PTTYPE not in ['MSDOS', 'GPT']:
if 'GPT' == PTTYPE:
return ogCreateGptPartitions (disk, parts)
elif 'MSDOS' != PTTYPE:
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)
@ -103,21 +78,24 @@ 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).
IOSIZE = ogGetIoSize (ND)
if not IOSIZE:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'Failed to get disk sector size')
return None
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:
if '4096' == IOSIZE:
START = 4096
SECTORS -= 8192
if CACHESIZE:
SECTORS = SECTORS - CACHESIZE + 2048 - (SECTORS - CACHESIZE) % 2048 - 1
else: ## 512
if 'MSDOS' == PTTYPE: START = 63
else: START = 2048
else:
START = 63
if CACHESIZE:
SECTORS -= CACHESIZE
@ -125,108 +103,71 @@ 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
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 tamaño numérico y convertir en sectores de 512 B.
SIZE *= 2
# Comprobar si la partición es extendida.
if '5' == ID:
if 'GPT' == PTTYPE:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'EXTENDED')
EXTSTART = EXTSIZE = 0
if 5 == ID:
if PART > 4:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '')
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 '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
if not EXTSTART:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '')
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}, type={ID}\n'
sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start={START}, size={SIZE}, Id={ID}\n'
START += SIZE
if 'MSDOS' == PTTYPE and 4096 == IOSIZE and PART > 4:
START += 2048
# Error si se supera el nº total de sectores.
if '4096' == IOSIZE and PART > 4:
START += 2048
if START > SECTORS:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'partición "{TYPE}:{ORIG_SIZE}" no cabe')
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'{START//2} > {SECTORS//2}')
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}, type={CACHE_ID}\n'
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, type=0\n'
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:
ID = ogTypeToId ('WINDOWS', PTTYPE)
sfdisk_input += f'{DISK}5 : start={EXTSTART}, SIZE={EXTSIZE}, type={ID}\n'
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)
@ -242,6 +183,113 @@ 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.
@ -383,7 +431,7 @@ def ogDevToDisk(arg_dev):
def _getAllDisks():
ret = []
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()
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()
for line in all_disks:
parts = line.split()
if parts[5] == "disk":
@ -737,9 +785,9 @@ def ogGetPartitionActive (disk):
break
if lang is None:
if 'LANG' in os.environ: del os.environ['LANG']
del os.environ['LANG']
else:
os.environ['LANG'] = lang
os.environ['LAMG'] = lang
return ret
@ -810,7 +858,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)
@ -1229,23 +1277,6 @@ 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',

View File

@ -635,7 +635,7 @@ def ogGetImageInfo (imgfile):
if lc_all is not None:
os.environ["LC_ALL"] = lc_all
else:
if "LC_ALL" in os.environ: del os.environ["LC_ALL"]
del os.environ["LC_ALL"]
if 'size' in partclone_info:
tools = 'PARTCLONE'

View File

@ -1,352 +0,0 @@
#!/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')

View File

@ -255,7 +255,7 @@ def ogGetRepoIp():
#@note Comprobacion segun protocolo de conexion al Repo
#*/ ##
def ogGetServerIp():
return os.environ.get ('ogcore', '')
return os.environ['ogcore']
#/**
# ogGetServerPort
@ -263,7 +263,10 @@ def ogGetServerIp():
#@return str_port - Puerto
#*/ ##
def ogGetServerPort():
return os.environ.get ('ogcore_port', '8443')
if 'ogcore_port' in os.environ:
return os.environ['ogcore_port']
else:
return '8443'
#/**

View File

@ -224,6 +224,7 @@ 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
@ -482,6 +483,7 @@ 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

View File

@ -178,7 +178,7 @@ def ogGetCaller():
caller = words[0].lstrip("-")
if cols is None:
if 'COLUMNS' in os.environ: del os.environ['COLUMNS']
del (os.environ['COLUMNS'])
else:
os.environ['COLUMNS'] = cols

View File

@ -0,0 +1,345 @@
#!/usr/bin/env python3
import hivex
import argparse
import struct
from hivex import Hivex
from hivex.hive_types import *
# Docs:
#
# https://www.geoffchappell.com/notes/windows/boot/bcd/objects.htm
# https://learn.microsoft.com/en-us/previous-versions/windows/desktop/bcd/bcdbootmgrelementtypes
#print(f"Root: {root}")
BCD_Enumerations = {
"BcdLibraryDevice_ApplicationDevice" : 0x11000001,
"BcdLibraryString_ApplicationPath" : 0x12000002,
"BcdLibraryString_Description" : 0x12000004,
"BcdLibraryString_PreferredLocale" : 0x12000005,
"BcdLibraryObjectList_InheritedObjects" : 0x14000006,
"BcdLibraryInteger_TruncatePhysicalMemory" : 0x15000007,
"BcdLibraryObjectList_RecoverySequence" : 0x14000008,
"BcdLibraryBoolean_AutoRecoveryEnabled" : 0x16000009,
"BcdLibraryIntegerList_BadMemoryList" : 0x1700000a,
"BcdLibraryBoolean_AllowBadMemoryAccess" : 0x1600000b,
"BcdLibraryInteger_FirstMegabytePolicy" : 0x1500000c,
"BcdLibraryInteger_RelocatePhysicalMemory" : 0x1500000D,
"BcdLibraryInteger_AvoidLowPhysicalMemory" : 0x1500000E,
"BcdLibraryBoolean_DebuggerEnabled" : 0x16000010,
"BcdLibraryInteger_DebuggerType" : 0x15000011,
"BcdLibraryInteger_SerialDebuggerPortAddress" : 0x15000012,
"BcdLibraryInteger_SerialDebuggerPort" : 0x15000013,
"BcdLibraryInteger_SerialDebuggerBaudRate" : 0x15000014,
"BcdLibraryInteger_1394DebuggerChannel" : 0x15000015,
"BcdLibraryString_UsbDebuggerTargetName" : 0x12000016,
"BcdLibraryBoolean_DebuggerIgnoreUsermodeExceptions" : 0x16000017,
"BcdLibraryInteger_DebuggerStartPolicy" : 0x15000018,
"BcdLibraryString_DebuggerBusParameters" : 0x12000019,
"BcdLibraryInteger_DebuggerNetHostIP" : 0x1500001A,
"BcdLibraryInteger_DebuggerNetPort" : 0x1500001B,
"BcdLibraryBoolean_DebuggerNetDhcp" : 0x1600001C,
"BcdLibraryString_DebuggerNetKey" : 0x1200001D,
"BcdLibraryBoolean_EmsEnabled" : 0x16000020,
"BcdLibraryInteger_EmsPort" : 0x15000022,
"BcdLibraryInteger_EmsBaudRate" : 0x15000023,
"BcdLibraryString_LoadOptionsString" : 0x12000030,
"BcdLibraryBoolean_DisplayAdvancedOptions" : 0x16000040,
"BcdLibraryBoolean_DisplayOptionsEdit" : 0x16000041,
"BcdLibraryDevice_BsdLogDevice" : 0x11000043,
"BcdLibraryString_BsdLogPath" : 0x12000044,
"BcdLibraryBoolean_GraphicsModeDisabled" : 0x16000046,
"BcdLibraryInteger_ConfigAccessPolicy" : 0x15000047,
"BcdLibraryBoolean_DisableIntegrityChecks" : 0x16000048,
"BcdLibraryBoolean_AllowPrereleaseSignatures" : 0x16000049,
"BcdLibraryString_FontPath" : 0x1200004A,
"BcdLibraryInteger_SiPolicy" : 0x1500004B,
"BcdLibraryInteger_FveBandId" : 0x1500004C,
"BcdLibraryBoolean_ConsoleExtendedInput" : 0x16000050,
"BcdLibraryInteger_GraphicsResolution" : 0x15000052,
"BcdLibraryBoolean_RestartOnFailure" : 0x16000053,
"BcdLibraryBoolean_GraphicsForceHighestMode" : 0x16000054,
"BcdLibraryBoolean_IsolatedExecutionContext" : 0x16000060,
"BcdLibraryBoolean_BootUxDisable" : 0x1600006C,
"BcdLibraryBoolean_BootShutdownDisabled" : 0x16000074,
"BcdLibraryIntegerList_AllowedInMemorySettings" : 0x17000077,
"BcdLibraryBoolean_ForceFipsCrypto" : 0x16000079,
"BcdBootMgrObjectList_DisplayOrder" : 0x24000001,
"BcdBootMgrObjectList_BootSequence" : 0x24000002,
"BcdBootMgrObject_DefaultObject" : 0x23000003,
"BcdBootMgrInteger_Timeout" : 0x25000004,
"BcdBootMgrBoolean_AttemptResume" : 0x26000005,
"BcdBootMgrObject_ResumeObject" : 0x23000006,
"BcdBootMgrObjectList_ToolsDisplayOrder" : 0x24000010,
"BcdBootMgrBoolean_DisplayBootMenu" : 0x26000020,
"BcdBootMgrBoolean_NoErrorDisplay" : 0x26000021,
"BcdBootMgrDevice_BcdDevice" : 0x21000022,
"BcdBootMgrString_BcdFilePath" : 0x22000023,
"BcdBootMgrBoolean_ProcessCustomActionsFirst" : 0x26000028,
"BcdBootMgrIntegerList_CustomActionsList" : 0x27000030,
"BcdBootMgrBoolean_PersistBootSequence" : 0x26000031,
"BcdDeviceInteger_RamdiskImageOffset" : 0x35000001,
"BcdDeviceInteger_TftpClientPort" : 0x35000002,
"BcdDeviceInteger_SdiDevice" : 0x31000003,
"BcdDeviceInteger_SdiPath" : 0x32000004,
"BcdDeviceInteger_RamdiskImageLength" : 0x35000005,
"BcdDeviceBoolean_RamdiskExportAsCd" : 0x36000006,
"BcdDeviceInteger_RamdiskTftpBlockSize" : 0x36000007,
"BcdDeviceInteger_RamdiskTftpWindowSize" : 0x36000008,
"BcdDeviceBoolean_RamdiskMulticastEnabled" : 0x36000009,
"BcdDeviceBoolean_RamdiskMulticastTftpFallback" : 0x3600000A,
"BcdDeviceBoolean_RamdiskTftpVarWindow" : 0x3600000B,
"BcdMemDiagInteger_PassCount" : 0x25000001,
"BcdMemDiagInteger_FailureCount" : 0x25000003,
"Reserved1" : 0x21000001,
"Reserved2" : 0x22000002,
"BcdResumeBoolean_UseCustomSettings" : 0x26000003,
"BcdResumeDevice_AssociatedOsDevice" : 0x21000005,
"BcdResumeBoolean_DebugOptionEnabled" : 0x26000006,
"BcdResumeInteger_BootMenuPolicy" : 0x25000008,
"BcdOSLoaderDevice_OSDevice" : 0x21000001,
"BcdOSLoaderString_SystemRoot" : 0x22000002,
"BcdOSLoaderObject_AssociatedResumeObject" : 0x23000003,
"BcdOSLoaderBoolean_DetectKernelAndHal" : 0x26000010,
"BcdOSLoaderString_KernelPath" : 0x22000011,
"BcdOSLoaderString_HalPath" : 0x22000012,
"BcdOSLoaderString_DbgTransportPath" : 0x22000013,
"BcdOSLoaderInteger_NxPolicy" : 0x25000020,
"BcdOSLoaderInteger_PAEPolicy" : 0x25000021,
"BcdOSLoaderBoolean_WinPEMode" : 0x26000022,
"BcdOSLoaderBoolean_DisableCrashAutoReboot" : 0x26000024,
"BcdOSLoaderBoolean_UseLastGoodSettings" : 0x26000025,
"BcdOSLoaderBoolean_AllowPrereleaseSignatures" : 0x26000027,
"BcdOSLoaderBoolean_NoLowMemory" : 0x26000030,
"BcdOSLoaderInteger_RemoveMemory" : 0x25000031,
"BcdOSLoaderInteger_IncreaseUserVa" : 0x25000032,
"BcdOSLoaderBoolean_UseVgaDriver" : 0x26000040,
"BcdOSLoaderBoolean_DisableBootDisplay" : 0x26000041,
"BcdOSLoaderBoolean_DisableVesaBios" : 0x26000042,
"BcdOSLoaderBoolean_DisableVgaMode" : 0x26000043,
"BcdOSLoaderInteger_ClusterModeAddressing" : 0x25000050,
"BcdOSLoaderBoolean_UsePhysicalDestination" : 0x26000051,
"BcdOSLoaderInteger_RestrictApicCluster" : 0x25000052,
"BcdOSLoaderBoolean_UseLegacyApicMode" : 0x26000054,
"BcdOSLoaderInteger_X2ApicPolicy" : 0x25000055,
"BcdOSLoaderBoolean_UseBootProcessorOnly" : 0x26000060,
"BcdOSLoaderInteger_NumberOfProcessors" : 0x25000061,
"BcdOSLoaderBoolean_ForceMaximumProcessors" : 0x26000062,
"BcdOSLoaderBoolean_ProcessorConfigurationFlags" : 0x25000063,
"BcdOSLoaderBoolean_MaximizeGroupsCreated" : 0x26000064,
"BcdOSLoaderBoolean_ForceGroupAwareness" : 0x26000065,
"BcdOSLoaderInteger_GroupSize" : 0x25000066,
"BcdOSLoaderInteger_UseFirmwarePciSettings" : 0x26000070,
"BcdOSLoaderInteger_MsiPolicy" : 0x25000071,
"BcdOSLoaderInteger_SafeBoot" : 0x25000080,
"BcdOSLoaderBoolean_SafeBootAlternateShell" : 0x26000081,
"BcdOSLoaderBoolean_BootLogInitialization" : 0x26000090,
"BcdOSLoaderBoolean_VerboseObjectLoadMode" : 0x26000091,
"BcdOSLoaderBoolean_KernelDebuggerEnabled" : 0x260000a0,
"BcdOSLoaderBoolean_DebuggerHalBreakpoint" : 0x260000a1,
"BcdOSLoaderBoolean_UsePlatformClock" : 0x260000A2,
"BcdOSLoaderBoolean_ForceLegacyPlatform" : 0x260000A3,
"BcdOSLoaderInteger_TscSyncPolicy" : 0x250000A6,
"BcdOSLoaderBoolean_EmsEnabled" : 0x260000b0,
"BcdOSLoaderInteger_DriverLoadFailurePolicy" : 0x250000c1,
"BcdOSLoaderInteger_BootMenuPolicy" : 0x250000C2,
"BcdOSLoaderBoolean_AdvancedOptionsOneTime" : 0x260000C3,
"BcdOSLoaderInteger_BootStatusPolicy" : 0x250000E0,
"BcdOSLoaderBoolean_DisableElamDrivers" : 0x260000E1,
"BcdOSLoaderInteger_HypervisorLaunchType" : 0x250000F0,
"BcdOSLoaderBoolean_HypervisorDebuggerEnabled" : 0x260000F2,
"BcdOSLoaderInteger_HypervisorDebuggerType" : 0x250000F3,
"BcdOSLoaderInteger_HypervisorDebuggerPortNumber" : 0x250000F4,
"BcdOSLoaderInteger_HypervisorDebuggerBaudrate" : 0x250000F5,
"BcdOSLoaderInteger_HypervisorDebugger1394Channel" : 0x250000F6,
"BcdOSLoaderInteger_BootUxPolicy" : 0x250000F7,
"BcdOSLoaderString_HypervisorDebuggerBusParams" : 0x220000F9,
"BcdOSLoaderInteger_HypervisorNumProc" : 0x250000FA,
"BcdOSLoaderInteger_HypervisorRootProcPerNode" : 0x250000FB,
"BcdOSLoaderBoolean_HypervisorUseLargeVTlb" : 0x260000FC,
"BcdOSLoaderInteger_HypervisorDebuggerNetHostIp" : 0x250000FD,
"BcdOSLoaderInteger_HypervisorDebuggerNetHostPort" : 0x250000FE,
"BcdOSLoaderInteger_TpmBootEntropyPolicy" : 0x25000100,
"BcdOSLoaderString_HypervisorDebuggerNetKey" : 0x22000110,
"BcdOSLoaderBoolean_HypervisorDebuggerNetDhcp" : 0x26000114,
"BcdOSLoaderInteger_HypervisorIommuPolicy" : 0x25000115,
"BcdOSLoaderInteger_XSaveDisable" : 0x2500012b
}
def format_value(bcd, bcd_value):
name = bcd.value_key(bcd_value)
(type, length) = bcd.value_type(bcd_value)
typename = ""
str_value = ""
if type == REG_SZ:
typename = "SZ"
str_value = bcd.value_string(bcd_value)
elif type == REG_DWORD:
typename = "DWORD"
dval = bcd.value_dword(bcd_value)
str_value = hex(dval) + " (" + str(bcd.value_dword(bcd_value)) + ")"
elif type == REG_BINARY:
typename = "BIN"
(length, value) = bcd.value_value(bcd_value)
str_value = value.hex()
elif type == REG_DWORD_BIG_ENDIAN:
typename = "DWORD_BE"
elif type == REG_EXPAND_SZ:
typename = "EXPAND SZ"
elif type == REG_FULL_RESOURCE_DESCRIPTOR:
typename = "RES DESC"
elif type == REG_LINK:
typename = "LINK"
elif type == REG_MULTI_SZ:
typename = "MULTISZ"
(length, str_value) = bcd.value_value(bcd_value)
str_value = str_value.decode('utf-16le')
str_value = str_value.replace("\0", ";")
#value = ";".join("\0".split(value))
elif type == REG_NONE:
typename = "NONE"
elif type == REG_QWORD:
typename = "QWORD"
elif type == REG_RESOURCE_LIST:
typename = "RES LIST"
elif type == REG_RESOURCE_REQUIREMENTS_LIST:
typename = "REQ LIST"
else:
typename = str(type)
str_value = "???"
return (typename, length, str_value)
def dump_all(root, depth = 0):
padding = "\t" * depth
children = bcd.node_children(root)
if len(children) > 0:
for child in children:
name = bcd.node_name(child)
print(f"{padding}{name}")
dump_all(child, depth + 1)
# print(f"Child: {child}")
#print(f"Values: {num_vals}")
return
values = bcd.node_values(root)
#print(f"Value list: {values}")
for v in values:
(type_name, length, str_value) = format_value(bcd, v)
name = bcd.value_key(v)
print(f"{padding}{name: <16}: [{type_name: <10}]; ({length: < 4}) {str_value}")
class WindowsBCD:
def __init__(self, filename):
self.filename = filename
self.bcd = Hivex(filename)
def dump(self, root=None, depth = 0):
padding = "\t" * depth
if root is None:
root = self.bcd.root()
children = self.bcd.node_children(root)
if len(children) > 0:
for child in children:
name = self.bcd.node_name(child)
print(f"{padding}{name}")
self.dump(child, depth + 1)
return
values = self.bcd.node_values(root)
for v in values:
(type_name, length, str_value) = format_value(self.bcd, v)
name = self.bcd.value_key(v)
print(f"{padding}{name: <16}: [{type_name: <10}]; ({length: < 4}) {str_value}")
def list(self):
root = self.bcd.root()
objects = self.bcd.node_get_child(root, "Objects")
for child in self.bcd.node_children(objects):
entry_id = self.bcd.node_name(child)
elements = self.bcd.node_get_child(child, "Elements")
description_entry = self.bcd.node_get_child(elements, "12000004")
if description_entry:
values = self.bcd.node_values(description_entry)
if values:
(type_name, length, str_value) = format_value(self.bcd, values[0])
print(f"{entry_id}: {str_value}")
else:
print(f"{entry_id}: [no description value!?]")
appdevice_entry = self.bcd.node_get_child(elements, "11000001")
if appdevice_entry:
values = self.bcd.node_values(appdevice_entry)
(length, data) = self.bcd.value_value(values[0])
hex = data.hex()
print(f"LEN: {length}, HEX: {hex}, RAW: {data}")
if len(data) > 10:
etype = struct.unpack_from('<I', data, offset = 16)
print(f"Type: {etype}")
else:
print(f"{entry_id}: [no description entry 12000004]")
parser = argparse.ArgumentParser(
prog="Windows BCD parser",
description="Parses the BCD",
)
parser.add_argument("--db", type=str, metavar='BCD file', help="Database to use")
parser.add_argument("--dump", action='store_true', help="Dumps the specified database")
parser.add_argument("--list", action='store_true', help="Lists boot entries in the specified database")
args = parser.parse_args()
bcdobj = WindowsBCD(args.db)
if args.dump:
# "/home/vadim/opengnsys/winboot/boot-copy/EFI/Microsoft/Boot/BCD"
#bcd = Hivex(args.dump)
#root = bcd.root()
#dump_all(root)
bcdobj.dump()
elif args.list:
bcdobj.list()

View File

@ -0,0 +1,124 @@
import logging
import subprocess
import re
# pylint: disable=locally-disabled, line-too-long, logging-fstring-interpolation, too-many-lines
class DiskLibrary:
def __init__(self):
self.logger = logging.getLogger("OpengnsysDiskLibrary")
self.logger.setLevel(logging.DEBUG)
def split_device_partition(self, device):
"""
Parses a device file like /dev/sda3 into the root device (/dev/sda) and partition number (3)
Args:
device (str): Device in /dev
Returns:
[base_device, partno]
"""
r = re.compile("^(.*?)(\\d+)$")
m = r.match(device)
disk = m.group(1)
partno = int(m.group(2))
self.logger.debug(f"{device} parsed into disk device {disk}, partition {partno}")
return (disk, partno)
def get_disk_json_data(self, device):
"""
Returns the partition JSON data dump for the entire disk, even if a partition is passed.
This is specifically in the format used by sfdisk.
Args:
device (str): Block device, eg, /dev/sda3
Returns:
str: JSON dump produced by sfdisk
"""
(disk, partno) = self.split_device_partition(device)
result = subprocess.run(["/usr/sbin/sfdisk", "--json", disk], check=True, capture_output=True, encoding='utf-8')
return result.stdout.strip()
def get_disk_uuid(self, device):
"""
Returns the UUID of the disk itself, if there's a GPT partition table.
Args:
device (str): Block device, eg, /dev/sda3
Returns:
str: UUID
"""
(disk, partno) = self.split_device_partition(device)
result = subprocess.run(["/usr/sbin/sfdisk", "--disk-id", disk], check=True, capture_output=True, encoding='utf-8')
return result.stdout.strip()
def set_disk_uuid(self, device, uuid):
(disk, partno) = self.split_device_partition(device)
subprocess.run(["/usr/sbin/sfdisk", "--disk-id", disk, uuid], check=True, encoding='utf-8')
def get_partition_uuid(self, device):
"""
Returns the UUID of the partition, if there's a GPT partition table.
Args:
device (str): Block device, eg, /dev/sda3
Returns:
str: UUID
"""
(disk, partno) = self.split_device_partition(device)
#result = subprocess.run(["/usr/sbin/sfdisk", "--part-uuid", disk, str(partno)], check=True, capture_output=True, encoding='utf-8')
#return result.stdout.strip()
guid = None
result = subprocess.run(["/usr/sbin/sgdisk", "--info", str(partno), disk], check=True, capture_output=True, encoding='utf-8')
for l in result.stdout.splitlines():
if 'Partition unique GUID' not in l: continue
guid = l.replace ('Partition unique GUID: ', '')
if guid is None:
self.logger.error (f'failed to get UUID of disk "{disk}" part "{partno}"')
return None
return guid
def set_partition_uuid(self, device, uuid):
(disk, partno) = self.split_device_partition(device)
subprocess.run(["/usr/sbin/sfdisk", "--part-uuid", disk, str(partno), uuid], check=True, encoding='utf-8')
def get_partition_type(self, device):
"""
Returns the type UUID of the partition, if there's a GPT partition table.
Args:
device (str): Block device, eg, /dev/sda3
Returns:
str: UUID
"""
(disk, partno) = self.split_device_partition(device)
result = subprocess.run(["/usr/sbin/sfdisk", "--part-type", disk, str(partno)], check=True, capture_output=True, encoding='utf-8')
return result.stdout.strip()
def set_partition_type(self, device, uuid):
(disk, partno) = self.split_device_partition(device)
subprocess.run(["/usr/sbin/sfdisk", "--part-type", disk, str(partno), uuid], check=True, encoding='utf-8')

View File

@ -0,0 +1,52 @@
#!/usr/bin/env python3
import unittest
import logging
import os
import sys
import urllib.request
import tarfile
import subprocess
from shutil import rmtree
from pathlib import Path
parent_dir = str(Path(__file__).parent.parent.absolute())
sys.path.append(parent_dir)
sys.path.append("/opengnsys/installer")
print(parent_dir)
from gitlib import OpengnsysGitLibrary
class GitTests(unittest.TestCase):
def setUp(self):
self.logger = logging.getLogger("OpengnsysTest")
self.oggit = OpengnsysGitLibrary()
self.logger.info("setUp()")
if not hasattr(self, 'init_complete'):
self.init_complete = True
def test_init(self):
self.assertIsNotNone(self.oggit)
def test_acls(self):
self.oggit.ogCreateAcl()
def test_sync_local(self):
# self.oggit.ogSyncLocalGitImage()
None
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)20s - [%(levelname)5s] - %(message)s')
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.info("Inicio del programa")
unittest.main()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
def parse_kernel_cmdline():
"""Parse the kernel arguments to obtain configuration parameters in Oglive
OpenGnsys passes data in the kernel arguments, for example:
[...] group=Aula_virtual ogrepo=192.168.2.1 oglive=192.168.2.1 [...]
Returns:
dict: Dict of configuration parameters and their values.
"""
params = {}
with open("/proc/cmdline", encoding='utf-8') as cmdline:
line = cmdline.readline()
parts = line.split()
for part in parts:
if "=" in part:
key, value = part.split("=")
params[key] = value
return params

View File

@ -0,0 +1,111 @@
import logging
import subprocess
from enum import Enum
class NTFSImplementation(Enum):
KERNEL = 1
NTFS3G = 2
class NTFSLibrary:
"""
A library for managing NTFS filesystems.
Attributes:
logger (logging.Logger): Logger for the class.
implementation (NTFSImplementation): The implementation to use for mounting NTFS filesystems.
"""
def __init__(self, implementation):
"""
Initializes the instance with the given implementation.
Args:
implementation: The implementation to be used by the instance.
Attributes:
logger (logging.Logger): Logger instance for the class, set to debug level.
implementation: The implementation provided during initialization.
"""
self.logger = logging.getLogger("NTFSLibrary")
self.logger.setLevel(logging.DEBUG)
self.implementation = implementation
self.logger.debug("Initializing")
def create_filesystem(self, device, label):
"""
Creates an NTFS filesystem on the specified device with the given label.
Args:
device (str): The device path where the NTFS filesystem will be created.
label (str): The label to assign to the NTFS filesystem.
Returns:
None
Logs:
Logs the creation process with the device and label information.
"""
self.logger.info(f"Creating NTFS in {device} with label {label}")
subprocess.run(["/usr/sbin/mkntfs", device, "-Q", "-L", label], check=True)
def mount_filesystem(self, device, mountpoint):
"""
Mounts a filesystem on the specified mountpoint using the specified NTFS implementation.
Args:
device (str): The device path to be mounted (e.g., '/dev/sda1').
mountpoint (str): The directory where the device will be mounted.
Raises:
ValueError: If the NTFS implementation is unknown.
"""
self.logger.info(f"Mounting {device} in {mountpoint} using implementation {self.implementation}")
if self.implementation == NTFSImplementation.KERNEL:
subprocess.run(["/usr/bin/mount", "-t", "ntfs3", device, mountpoint], check = True)
elif self.implementation == NTFSImplementation.NTFS3G:
subprocess.run(["/usr/bin/ntfs-3g", device, mountpoint], check = True)
else:
raise ValueError("Unknown NTFS implementation: {self.implementation}")
def modify_uuid(self, device, uuid):
"""
Modify the UUID of an NTFS device.
This function changes the UUID of the specified NTFS device to the given UUID.
It reads the current UUID from the device, logs the change, and writes the new UUID.
Args:
device (str): The path to the NTFS device file.
uuid (str): The new UUID to be set, in hexadecimal string format.
Raises:
IOError: If there is an error opening or writing to the device file.
"""
ntfs_uuid_offset = 0x48
ntfs_uuid_length = 8
binary_uuid = bytearray.fromhex(uuid)
binary_uuid.reverse()
self.logger.info(f"Changing UUID on {device} to {uuid}")
with open(device, 'r+b') as ntfs_dev:
self.logger.debug("Reading %i bytes from offset %i", ntfs_uuid_length, ntfs_uuid_offset)
ntfs_dev.seek(ntfs_uuid_offset)
prev_uuid = bytearray(ntfs_dev.read(ntfs_uuid_length))
prev_uuid.reverse()
prev_uuid_hex = bytearray.hex(prev_uuid)
self.logger.debug(f"Previous UUID: {prev_uuid_hex}")
self.logger.debug("Writing...")
ntfs_dev.seek(ntfs_uuid_offset)
ntfs_dev.write(binary_uuid)

View File

@ -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=4 # Tiempo de sleep antes de realizar el reboot
#OGSLEEP=20 # 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

View File

@ -0,0 +1,13 @@
#!/usr/bin/env python3
def _hex_to_bin( hex_str):
while len(hex_str) != 16:
hex_str = "0" + hex_str
hex_int = int(hex_str, 16)
binary = bin(hex_int)[2:].zfill(64)
return binary
print( _hex_to_bin("0ACA"))

View File

@ -0,0 +1 @@
bootOs

View File

@ -0,0 +1 @@
bootOs

View File

@ -50,8 +50,6 @@ 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()

View File

@ -1,74 +1,39 @@
#!/usr/bin/python3
#!/bin/bash
# Scirpt de ejemplo para apagar un ordenador
# Nota: se usa como base para el programa de apagado de OpenGnsys Admin.
import os
import sys
import shutil
import time
import subprocess
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')
# Registrar ejecución manual de script.
case "$(ogGetCaller)" in
browser|bash) ogEcho log info "Script: $0" ;;
esac
# No registrar errores.
#DEBUG=no
export DEBUG="no"
# Desmontar los sistemas de archivos y la caché local.
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()
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.
#DEBUG=yes
unset DEBUG
if is_reboot:
print ('[90] Reiniciar el equipo.')
else:
print ('[70] Apagando el equipo.')
echo "[70] Apagando el equipo."
# Estado correcto de Wake-On-Lan antes de apagar.
subprocess.run (['ethtool', '-s', DEVICE, 'wol', 'g'], stderr=subprocess.DEVNULL)
ethtool -s $DEVICE wol g 2>/dev/null
# Detectar Busybox.
BUSYBOX = shutil.which ('busyboxOLD')
if not BUSYBOX: BUSYBOX = shutil.which ('busybox')
BUSYBOX=$(which busyboxOLD)
BUSYBOX=${BUSYBOX:-"busybox"}
# Retardo para dar lugar al registro en cola de acciones.
time.sleep (TIME)
sleep 5
# Parar Browser para evitar "cuelgues".
if 'offline' != ogstatus:
subprocess.run (['killall', 'QtWebEngineProcess', 'OGBrowser', 'i3', 'sway', 'Xorg', 'startx'], stderr=subprocess.DEVNULL)
[ "$ogstatus" == "offline" ] || pkill browser
# Apagar.
$BUSYBOX poweroff
if is_reboot:
subprocess.run ([BUSYBOX, 'reboot'])
else:
subprocess.run ([BUSYBOX, 'poweroff'])

View File

@ -1 +0,0 @@
poweroff

View File

@ -0,0 +1,54 @@
#!/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

View File

@ -0,0 +1,38 @@
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()