1
0
Fork 0

refs #1613 use ucf, reorganise lib files

deb-package
Natalia Serrano 2025-02-26 15:05:51 +01:00
parent 929a915153
commit 2985d6001b
40 changed files with 12942 additions and 9707 deletions

View File

@ -8,7 +8,7 @@
#*/ #*/
# Montar efivar filesystem # Montar efivar filesystem
isEfiActive && mount -t efivarfs none /sys/firmware/efi/efivars ogIsEfiActive && mount -t efivarfs none /sys/firmware/efi/efivars
# Lanzar servicios complementarios del cliente. # Lanzar servicios complementarios del cliente.
echo "${MSG_OTHERSERVICES:-.}" echo "${MSG_OTHERSERVICES:-.}"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,439 @@
#!/bin/bash
#/**
#@file Cache.lib
#@brief Librería o clase Cache
#@class Cache
#@brief Funciones para gestión de la caché local de disco.
#@version 1.1.1
#@warning License: GNU GPLv3+
#*/
#/**
# ogCreateCache [int_ndisk] int_partsize
#@brief Define la caché local, por defecto en partición 4 del disco 1.
#@param int_ndisk numero de disco donde crear la cache, si no se indica es el 1 por defecto
#@param int_npart número de partición (opcional, 4 por defecto)
#@param int_partsize tamaño de la partición (en KB)
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@note Requisitos: sfdisk, parted, awk, sed
#@warning El tamaño de caché debe estar entre 50 MB y la mitad del disco.
#@warning La caché no puede solaparse con las particiones de datos.
#@version 0.9.1 - Definición de caché local.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010/03/09
#@version 0.9.2 - Corrección definición de límites.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010/06/01
#@version 1.0.4 - Soporte para discos GPT.
#@author Universidad de Huelva
#@date 2012/03/13
#@version 1.0.5 - Posibilidad de crear la cache en cualquier disco duro
#@author Universidad de Huelva
#@date 2012/09/18
#@version 1.1.0 - Posibilidad de crear la caché en cualquier partición.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2016/05/25
#@version 1.1.0 - Soporte discos con sectores de 4k
#@date 2017/01/09
#@version 1.0.6b - Al crear las particiones ordenamos los dispositivos en el fichero auxiliar.
#@author Irina Gomez, ETSII Universidad de Sevilla
#@date 2017/01/09
#*/ ##
function ogCreateCache ()
{
# Variables locales.
local FINDCACHE IOSIZE NDSK SIZECACHE PART DISK START END ENDPREVPART SIZE MINSIZE MAXSIZE
local PTTYPE ID TMPFILE NVME_PREFIX
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [int_ndisk [int_npart]] int_partsize" \
"$FUNCNAME 10000000" "$FUNCNAME 1 10000000" "$FUNCNAME 1 4 10000000"
return
fi
# Si se recibe un parametro, sera el tamano de la cache
case $# in
1) # Error, si no es un entero positivo
[[ $1 =~ ^[1-9][0-9]*$ ]] || ogRaiseError $OG_ERR_FORMAT "$1" || return $?
NDSK=1
PART=4
SIZECACHE=$1
;;
2) # Error, si no son enteros positivos
[[ $1 =~ ^[1-9][0-9]*$ ]] || ogRaiseError $OG_ERR_FORMAT "$1" || return $?
[[ $2 =~ ^[1-9][0-9]*$ ]] || ogRaiseError $OG_ERR_FORMAT "$2" || return $?
NDSK=$1
PART=4
SIZECACHE=$2
;;
3) # Error, si no son enteros positivos
[[ $1 =~ ^[1-9][0-9]*$ ]] || ogRaiseError $OG_ERR_FORMAT "$1" || return $?
[[ $2 =~ ^[1-9][0-9]*$ ]] || ogRaiseError $OG_ERR_FORMAT "$2" || return $?
[[ $3 =~ ^[1-9][0-9]*$ ]] || ogRaiseError $OG_ERR_FORMAT "$3" || return $?
NDSK=$1
PART=$2
SIZECACHE=$3
;;
*) ogRaiseError $OG_ERR_FORMAT
return $?
;;
esac
TMPFILE=/tmp/sfdisk$$
DISK=$(ogDiskToDev $NDSK) || return $?
# PATCH Para discos nvme la particion debe ser p1, p2, etc...en lugar de 1,2, sino falla sfdisk
NVME_PREFIX=""
if [[ $DISK == *"nvme"* ]]; then
NVME_PREFIX="p"
fi
END=$[$(ogGetLastSector $NDSK 2>/dev/null)] # Sector final del disco.
SIZE=$[$SIZECACHE*2] # Tamaño en sectores de 512 B.
# Inicio partición cache según el disco tenga sectores de 4k o menores
IOSIZE=$(fdisk -l $DISK | awk '/I\/O/ {print $4}')
if [ $IOSIZE -eq 4096 ]; then
END=$[$END-8192]
START=$[END-SIZE+2048-(END-SIZE)%2048]
else
START=$[END-SIZE+1]
fi
ENDPREVPART=$[$(ogGetLastSector $NDSK $[PART-1] 2>/dev/null)]
# Error si tamaño no está entre límites permitidos o si se solapa con la partición anterior.
MINSIZE=25000 # Error de formateo si tamaño < 50 MB.
MAXSIZE=$END # Para restringir tamaño > mitad del disco: MAXSIZE=$[END/2]
if [ $SIZE -lt $MINSIZE -o $SIZE -gt $MAXSIZE -o $START -le $ENDPREVPART ]; then
ogRaiseError $OG_ERR_FORMAT "$1" || return $?
fi
# Desmontar todos los sistemas de archivos del disco.
ogUnmountAll $NDSK 2>/dev/null
# Definir particiones y notificar al kernel.
# En el caso de ser disco GPT, de momento se borra la particion y se vuelve a crear,
# por lo que se pierden los datos.
PTTYPE=$(ogGetPartitionTableType $NDSK)
if [ -z "$PTTYPE" ]; then
PTTYPE="MSDOS" # Por defecto para discos vacíos.
ogCreatePartitionTable $NDSK $PTTYPE
fi
case "$(ogGetPartitionTableType $NDSK)" in
GPT)
# Si la tabla de particiones no es valida, volver a generarla.
[ ! $(sgdisk -p $DISK &>/dev/null) ] || echo -e "2\nw\nY\n" | gdisk $DISK
# Si existe la cache se borra previamente
[ -n "$(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=$(ogTypeToId LINUX GPT)
sgdisk $DISK -n$PART:$START:$END -c$PART:CACHE -t$PART:$ID 2>/dev/null
;;
MSDOS)
# Si la tabla de particiones no es valida, volver a generarla.
parted -s $DISK print &>/dev/null || fdisk $DISK <<< "w"
# Definir particiones y notificar al kernel.
ID=$(ogTypeToId CACHE MSDOS)
# Salvamos la configuración de las particiones e incluimos la cache.
trap "rm -f $TMPFILE" 1 2 3 9 15
sfdisk --dump $DISK | grep -v $DISK$PART > $TMPFILE
echo "$DISK$NVME_PREFIX$PART : start= $START, size= $SIZE, Id=$ID" >> $TMPFILE
# Ordenamos las líneas de los dispositivos
UNIT=$(grep unit $TMPFILE)
grep ^/dev $TMPFILE|sort -o $TMPFILE
sed -i "1i $UNIT\n" $TMPFILE
# Guardamos nueva configuración en el disco.
sfdisk --no-reread $DISK < $TMPFILE
rm -f $TMPFILE
;;
esac
# Actualiza la tabla de particiones en el kernel.
ogUpdatePartitionTable
}
#/**
# ogDeleteCache
#@brief Elimina la partición de caché local.
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@note Requisitos: fdisk, sgdisk, partprobe
#@version 0.91 - Definición de caché local.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010/03/11
#@version 1.0.4 - Soporte para discos GPT.
#@author Universidad de Huelva
#@date 2012/03/13
#@version 1.0.6b - llamada correcta a ogUpdatePartitionTable
#@author Antonio Doblas Universidad de Málaga
#@date 2016/11/16
#@version 1.1.0 - Sustituir "sfdisk" por "fdisk" para discos MSDOS.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2016/05/25
#*/ ##
function ogDeleteCache ()
{
# Variables locales.
local NDISK NPART DISK
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME"
return
fi
# Error si no se encuentra partición de caché.
read NDISK NPART <<<"$(ogFindCache)"
[ -n "$NDISK" -a -n "$NPART" ] || ogRaiseError $OG_ERR_PARTITION "$MSG_NOCACHE" || return $?
DISK=$(ogDiskToDev $NDISK)
# Desmontar todos los sistemas de archivos del disco.
ogUnmountAll $NDISK 2>/dev/null
case "$(ogGetPartitionTableType $NDISK)" in
GPT)
# Si la tabla de particiones no es valida, volver a generarla.
[ ! $(sgdisk -p $DISK 2>&1 >/dev/null) ] || echo -e "2\nw\nY\n" | gdisk $DISK
sgdisk $DISK -d$NPART 2>/dev/null
;;
MSDOS)
# Si la tabla de particiones no es valida, volver a generarla.
parted -s $DISK print &>/dev/null || fdisk $DISK <<< "w"
# Eliminar la partición de caché.
echo -e "d\n$NPART\nw" | fdisk $DISK 2>/dev/null
;;
esac
# Borrar etiqueta de la caché.
rm -f /dev/disk/by-label/CACHE
#Actualiza la tabla de particiones en el kernel.
ogUpdatePartitionTable $NDISK
}
#/**
# ogFindCache
#@brief Detecta la partición caché local.
#@param No requiere parametros
#@return int_ndisk int_npart - devuelve el par nº de disco-nº de partición .
#@warning Si no hay cache no devuelve nada
#@version 0.1 - Integracion para Opengnsys - EAC: FindCache() en ATA.lib - HIDRA: DetectarCache.sh
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@Date 2008/06/19
#@author Antonio J. Doblas Viso. Universidad de Malaga
#@Date 2008/10/27
#@version 0.91 - Adaptacion a la cache local de OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010/03/16
#@version 1.0.5 - Obtener caché en discos GPT.
#@author Alberto García, Universidad de Málaga y Ramon Gomez, ETSII Universidad de Sevilla
#@date 2014/05/28
#*/ ##
function ogFindCache ()
{
# Variables locales
local DISK PART
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME => 1 4"
return
fi
# Obtener el dispositivo del sistema de archivos etiquetado como "CACHE".
PART=$(blkid -L "CACHE")
# En discos nvme con particiones GPT la partición se detecta usando el tag PARTLABEL
PART=${PART:-$(blkid -t PARTLABEL=CACHE | awk -F: '{print $1}')}
# Si no se detecta, obtener particiones marcadas de tipo caché en discos MSDOS.
PART=${PART:-$(sfdisk -l 2>/dev/null | awk '$6~/ca|a7/ {print $1}')}
# Por último revisar todos los discos GPT y obtener las particiones etiquetadas como caché.
if [ -z "$PART" ]; then
for DISK in $(ogDiskToDev); do
# Nota: se añade espacio separador solo si existe valor previo.
PART="${PART:+"$PART "}$(sgdisk -p $DISK 2>/dev/null | awk -v d=$DISK '$7~/CACHE/ {printf "%s%s",d,$1;}')"
done
fi
# Devolver número de disco y número de partición de la 1ª partición encontrada.
ogDevToDisk ${PART%% *} 2>/dev/null
}
#/**
# ogFormatCache
#@brief Formatea el sistema de ficheros para la caché local.
#@return (por determinar)
#@warning Prueba con formato Reiser.
#@attention
#@note El sistema de archivos de la caché se queda montado.
#@version 0.1 - Integracion para Opengnsys - EAC: FormatCache() en ATA.lib
#@author Antonio J. Doblas Viso. Universidad de Malaga
#@date 2008/10/27
#@version 0.91 - Creacion cache local.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010-03-11
#@version 1.1.0 - llamada a updateBootCache.
#@author Antonio J. Doblas Viso. Universidad de Malaga
#@date 2018-01-21
#*/ ##
function ogFormatCache ()
{
# Variables locales.
local DEV MNTDIR OPTIONS
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME"
return
fi
# Error si no hay definida partición de caché.
DEV=$(ogFindCache) || ogRaiseError $OG_ERR_PARTITION "$MSG_NOCACHE" || return $?
DEV=$(ogDiskToDev $DEV) || return $?
# Formatear sistema de ficheros.
ogUnmountCache 2>/dev/null
OPTIONS="extent,large_file"
[[ $(uname -r) =~ ^5 ]] && OPTIONS+=",uninit_bg,^metadata_csum,^64bit"
mkfs.ext4 -q -F $DEV -L "CACHE" -O "$OPTIONS" 2>/dev/null || ogRaiseError $OG_ERR_PARTITION "CACHE" || return $?
# Crear estructura básica.
MNTDIR=$(ogMountCache)
mkdir -p $MNTDIR/$OGIMG
# Incluir kernel e Initrd del ogLive
updateBootCache 2>&1>/dev/null
}
#/**
# ogGetCacheSize
#@brief Devuelve el tamaño definido para la partición de caché.
#@return int_partsize tamaño de la partición (en KB)
#@exception OG_ERR_PARTITION No existe partición de caché.
#@version 0.1 - Integracion para Opengnsys - EAC: InfoCache() en FileSystem.lib
#@author Antonio J. Doblas Viso. Universidad de Malaga
#@date 2008/10/27
#@version 0.91 - Definicion de cache local.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010/03/09
#*/ ##
function ogGetCacheSize ()
{
# Variables locales
local PART
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME => 10000000"
return
fi
# Error si no se encuentra partición de caché.
PART=$(ogFindCache) || ogRaiseError $OG_ERR_PARTITION "$MSG_NOCACHE" || return $?
# Devuelve tamaño de la partición de caché.
ogGetPartitionSize $PART
}
#/**
# ogGetCacheSpace
#@brief Devuelve el espacio de disco disponible para la partición de caché.
#@return int_size tamaño disponible (en KB)
#@note El espacio disponible es el que hay entre el límite superior de la partición 3 del disco 1 y el final de dicho disco, y no puede ser superior a la mitad de dicho disco.
#@version 0.1 - Integracion para Opengnsys - EAC: InfoCache() en FileSystem.lib
#@author Antonio J. Doblas Viso. Universidad de Malaga
#@date 2008/10/27
#@version 0.91 - Definicion de cache local.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010/03/09
#@version 1.0.5 - Uso de ogFindCache para detectar disco y particion
#@author Universidad de Huelva
#@date 2012/09/18
#*/ ##
function ogGetCacheSpace ()
{
# Variables locales.
local NDISK DISK NPART SECTORS CYLS ENDPART3
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME => 23165386"
return
fi
# Parche UHU para usar ogFindCache en lugar de 1
# Error si no se encuentra partición de caché.
read NDISK NPART <<<"$(ogFindCache)"
[ -n "$NDISK" -a -n "$NPART" ] || ogRaiseError $OG_ERR_PARTITION "$MSG_NOCACHE" || return $?
DISK=$(ogDiskToDev $NDISK) || return $?
SECTORS=$(awk -v D=${DISK#/dev/} '{if ($4==D) {print $3*2}}' /proc/partitions)
CYLS=$(sfdisk -g $DISK | cut -f2 -d" ")
SECTORS=$[SECTORS/CYLS*CYLS-1]
ENDPART3=$(sfdisk -uS -l $DISK | awk -v P="${DISK}3" '{if ($1==P) print $3}')
# Mostrar espacio libre en KB (1 KB = 2 sectores)
if [ $ENDPART3 -gt $[SECTORS/2] ]; then
echo $[(SECTORS-ENDPART3)/2]
else
echo $[SECTORS/4]
fi
}
#/**
# ogMountCache
#@brief Monta la partición Cache y exporta la variable $OGCAC
#@param sin parametros
#@return path_mountpoint - Punto de montaje del sistema de archivos de cache.
#@warning Salidas de errores no determinada
#@version 0.1 - Integracion para Opengnsys - EAC: MountCache() en FileSystem.lib - HIDRA: MontarCache.sh
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2008/06/19
#@author Antonio J. Doblas Viso. Universidad de Malaga
#@Date 2008/10/27
#@version 0.91 - Adaptacion a la cache local de OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010/03/16
#@version 1.0 - Correccion multiples montajes de cache.
#@author Antonio J. Doblas Viso, Universidad de Malaga
#@date 2011/02/24
#*/ ##
function ogMountCache ()
{
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME ==> /mnt/sda4"
return
fi
ogMountFs $(ogFindCache) 2>/dev/null || ogRaiseError $OG_ERR_PARTITION "$MSG_NOCACHE" || return $?
}
#/**
# ogUnmountCache
#@brief Desmonta la particion Cache y elimina la variable $OGCAC
#@param sin parametros
#@return nada
#@warning Salidas de errores no determinada
#@version 0.1 - Integracion para Opengnsys - EAC: UmountCache() en FileSystem.lib
#@author Antonio J. Doblas Viso. Universidad de Malaga
#@Date 2008/10/27
#@version 0.91 - Adaptacion a la cache local de OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010/03/16
#@version 1.0 - Correccion multiples montajes de cache.
#@author Antonio J. Doblas Viso, Universidad de Malaga
#@date 2011/02/24
#*/ ##
function ogUnmountCache ()
{
# Variables locales.
local CACHE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME"
return
fi
CACHE=$(ogFindCache) || ogRaiseError $OG_ERR_PARTITION "$MSG_NOCACHE"
ogIsMounted $CACHE || return 0
ogUnmountFs $CACHE
# Borrar enlace simbólico de /mnt/ParticiónCache.
rm -f $(ogDiskToDev $CACHE | sed 's/dev/mnt/')
}

View File

@ -1,361 +0,0 @@
import os
import re
import subprocess
import shutil
import sys
import platform
import ogGlobals
import SystemLib
import DiskLib
import FileSystemLib
import CacheLib
#/**
# ogCreateCache [int_ndisk] int_partsize
#@brief Define la caché local, por defecto en partición 4 del disco 1.
#@param int_ndisk numero de disco donde crear la cache, si no se indica es el 1 por defecto
#@param int_npart número de partición (opcional, 4 por defecto)
#@param int_partsize tamaño de la partición (en KB)
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@note Requisitos: sfdisk, parted, awk, sed
#@warning El tamaño de caché debe estar entre 50 MB y la mitad del disco.
#@warning La caché no puede solaparse con las particiones de datos.
#*/ ##
def ogCreateCache (ndsk=1, part=4, sizecache=0):
if not sizecache:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '')
return None
sizecache = int (sizecache)
DISK = DiskLib.ogDiskToDev (ndsk)
if not DISK: return None
# PATCH Para discos nvme la particion debe ser p1, p2, etc...en lugar de 1,2, sino falla sfdisk
NVME_PREFIX = ''
if 'nvme' in DISK:
NVME_PREFIX = 'p'
END = DiskLib.ogGetLastSector (ndsk)
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
START = 0
if 4096 == IOSIZE:
END -= 8192
START = END - SIZE + 2048 - (END-SIZE)%2048
else:
START = END - SIZE + 1
ENDPREVPART = None
i = 1
while True:
prev_part = part - i
if prev_part <= 0: break
ENDPREVPART = DiskLib.ogGetLastSector (ndsk, prev_part)
if ENDPREVPART: break
i += 1
if not ENDPREVPART:
ENDPREVPART=0
#SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, ndsk)
#return None
# Error si tamaño no está entre límites permitidos o si se solapa con la partición anterior.
MINSIZE = 25000
MAXSIZE = END
if SIZE < MINSIZE or SIZE > MAXSIZE or START < ENDPREVPART:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, ndsk)
return None
# Desmontar todos los sistemas de archivos del disco.
FileSystemLib.ogUnmountAll (ndsk)
# Definir particiones y notificar al kernel.
# En el caso de ser disco GPT, de momento se borra la particion y se vuelve a crear,
# por lo que se pierden los datos.
pttype = DiskLib.ogGetPartitionTableType (ndsk)
if not pttype:
pttype = 'MSDOS'
DiskLib.ogCreatePartitionTable (ndsk, pttype)
get_ptt = DiskLib.ogGetPartitionTableType (ndsk)
if 'GPT' == get_ptt:
# Si la tabla de particiones no es valida, volver a generarla.
if subprocess.run (['sgdisk', '-p', DISK]).returncode:
subprocess.run (['gdisk', DISK], input='2\nw\nY\n', 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}'])
elif 'MSDOS' == get_ptt:
# Si la tabla de particiones no es valida, volver a generarla.
if subprocess.run (['parted', '-s', DISK, 'print']).returncode:
subprocess.run (['fdisk', DISK], input='w\n', text=True)
# Definir particiones y notificar al kernel.
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)
# Actualiza la tabla de particiones en el kernel.
DiskLib.ogUpdatePartitionTable()
#/**
# ogDeleteCache
#@brief Elimina la partición de caché local.
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@note Requisitos: fdisk, sgdisk, partprobe
#*/ ##
def ogDeleteCache():
cachepart = ogFindCache()
if not cachepart:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE)
return None
ndisk, npart = cachepart.split()
disk = DiskLib.ogDiskToDev (ndisk)
# Desmontar todos los sistemas de archivos del disco.
FileSystemLib.ogUnmountAll (ndisk)
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:
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']).returncode:
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)
# Borrar etiqueta de la caché.
if os.path.exists ('/dev/disk/by-label/CACHE'):
os.unlink ('/dev/disk/by-label/CACHE')
#Actualiza la tabla de particiones en el kernel.
DiskLib.ogUpdatePartitionTable()
#/**
# ogFindCache
#@brief Detecta la partición caché local.
#@param No requiere parametros
#@return int_ndisk int_npart - devuelve el par nº de disco-nº de partición .
#@warning Si no hay cache no devuelve nada
#*/ ##
def ogFindCache():
# Obtener el dispositivo del sistema de archivos etiquetado como "CACHE".
PART = subprocess.run (['blkid', '-L', 'CACHE'], capture_output=True, text=True).stdout.strip()
# En discos nvme con particiones GPT la partición se detecta usando el tag PARTLABEL
if not PART:
out = subprocess.run (['blkid', '-t', 'PARTLABEL=CACHE'], capture_output=True, text=True).stdout.strip()
PART = out.split (':')[0]
# Si no se detecta, obtener particiones marcadas de tipo caché en discos MSDOS.
if not PART:
out = subprocess.run (['sfdisk', '-l'], capture_output=True, text=True).stdout.splitlines()
for l in out:
elems = l.split (maxsplit=5)
if 6 > len (elems): continue
if 'ca' in elems[5] or 'a7' in elems[5]:
PART=elems[0]
break
# Por último revisar todos los discos GPT y obtener las particiones etiquetadas como caché.
if not PART:
PART = ''
for d in DiskLib.ogDiskToDev():
out = subprocess.run (['sgdisk', '-p', d], capture_output=True, text=True).stdout.splitlines()
for l in out:
elems = l.split (maxsplit=6)
if 7 > len (elems): continue
if 'CACHE' in elems[6]:
p = 'p' if 'nvme' in d else ''
PART += f' {d}{p}{elems[0]}'
if not PART: return
return DiskLib.ogDevToDisk (PART.split()[0]) # usar la 1ª partición encontrada.
#/**
# ogFormatCache
#@brief Formatea el sistema de ficheros para la caché local.
#@return (por determinar)
#@warning Prueba con formato Reiser.
#@attention
#@note El sistema de archivos de la caché se queda montado.
#*/ ##
def ogFormatCache():
cachepart = ogFindCache()
if cachepart is None:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE)
return
cachepart = cachepart.split()
disk = DiskLib.ogDiskToDev (cachepart[0], cachepart[1])
if not disk: return
ogUnmountCache()
options = "extent,large_file"
if re.match("^5", platform.release()):
options += ",uninit_bg,^metadata_csum,^64bit"
try:
subprocess.run(["mkfs.ext4", "-q", "-F", disk, "-L", "CACHE", "-O", options], check=True)
except subprocess.CalledProcessError as e:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, "CACHE")
return
# Crear estructura básica.
mntdir = ogMountCache()
j = '/'.join ([mntdir, ogGlobals.OGIMG]) ## os.path.join doesn't work: "If a segment […] is an absolute path, all previous segments are ignored"
#print (f'cucu mntdir ({mntdir}) OGIMG ({ogGlobals.OGIMG}) j ({j})')
os.makedirs (j, exist_ok=True)
# Incluir kernel e Initrd del ogLive
## como lo llamo sin especificar el path entero?
#subprocess.run (['scripts/updateBootCache.py']) ## TODO
#/**
# ogGetCacheSize
#@brief Devuelve el tamaño definido para la partición de caché.
#@return int_partsize tamaño de la partición (en KB)
#@exception OG_ERR_PARTITION No existe partición de caché.
#*/ ##
def ogGetCacheSize():
cachepart = ogFindCache()
if cachepart is None:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE)
return None
disk, par = cachepart.split()
return DiskLib.ogGetPartitionSize (disk, par)
#/**
# ogGetCacheSpace
#@brief Devuelve el espacio de disco disponible para la partición de caché.
#@return int_size tamaño disponible (en KB)
#@note El espacio disponible es el que hay entre el límite superior de la partición 3 del disco 1 y el final de dicho disco, y no puede ser superior a la mitad de dicho disco.
#*/ ##
def ogGetCacheSpace():
cachepart = ogFindCache()
if not cachepart:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE)
return None
cachepart = cachepart.split()
disk = DiskLib.ogDiskToDev (cachepart[0])
if not disk:
return None
sectors = 0
disk_bn = os.path.basename (disk)
with open ('/proc/partitions', 'r') as fd:
proc_parts = fd.read()
for l in proc_parts.splitlines():
items = l.split()
if len(items) < 4: continue
if items[3] == disk_bn:
sectors = 2 * int (items[2])
if not sectors: return None
sfdisk_out = subprocess.run (['sfdisk', '-g', disk], capture_output=True, text=True).stdout
cyls = int (sfdisk_out.split()[1])
sectors = sectors/cyls * cyls - 1
## the original code has a hard dependency on the existence of a third partition
## if the disk has sda1, sda2 and sda4, the code fails.
## this is an improved version
endpart3 = 0
for trypart in [3, 2, 1]:
sfdisk_out = subprocess.run (['sfdisk', '-uS', '-l', disk], capture_output=True, text=True).stdout
for l in sfdisk_out.splitlines():
items = l.split()
if len(items) < 6: continue
if f'{disk}{trypart}' == items[0]:
endpart3 = int (items[2])
break
if endpart3: break
if not endpart3: return None
# Mostrar espacio libre en KB (1 KB = 2 sectores)
if endpart3 > sectors // 2:
return (sectors - endpart3) // 2
else:
return sectors // 4
#/**
# ogMountCache
#@brief Monta la partición Cache y exporta la variable $OGCAC
#@param sin parametros
#@return path_mountpoint - Punto de montaje del sistema de archivos de cache.
#@warning Salidas de errores no determinada
#*/ ##
def ogMountCache():
c = ogFindCache()
if not c:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE)
return None
c = c.split()
m = FileSystemLib.ogMountFs (c[0], c[1])
if not m:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE)
return None
return m
#/**
# ogUnmountCache
#@brief Desmonta la particion Cache y elimina la variable $OGCAC
#@param sin parametros
#@return nada
#@warning Salidas de errores no determinada
#*/ ##
def ogUnmountCache():
cachepart = ogFindCache()
if cachepart is None:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE)
return
cachepart = cachepart.split()
if not FileSystemLib.ogIsMounted (cachepart[0], cachepart[1]): return True
FileSystemLib.ogUnmountFs (cachepart[0], cachepart[1])
# Eliminar el enlace simbólico de /mnt/ParticiónCache.
dev = DiskLib.ogDiskToDev (cachepart[0], cachepart[1])
dev = dev.replace ('dev', 'mnt')
if os.path.exists (dev): os.remove (dev)
#/**
# initCache
#@brief Simplemente llama al script initCache
#@brief Es necesario tener una función para poder pasársela a ogExecAndLog
#@param los mismos parametros que initCache
#@return lo mismo que devuelve initCache
#*/ ##
def initCache (*args):
p = subprocess.run (['/opt/opengnsys/images/nati/client/shared/scripts/initCache.py'] + list(args))
return p.returncode

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,422 @@
#!/bin/bash
#/**
#@file File.lib
#@brief Librería o clase File
#@class File
#@brief Funciones para gestión de archivos y directorios.
#@version 1.0.4
#@warning License: GNU GPLv3+
#*/
#/**
# ogCalculateChecksum [ str_repo | int_ndisk int_npart ] path_filepath
#@brief Devuelve la suma de comprobación (checksum) de un fichero.
#@param path_filepath camino del fichero (independiente de mayúsculas)
#@param str_repo repositorio de ficheros
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return hex_checksum Checksum del fichero
#@version 0.9.2 - Primera versión para OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010-07-24
#@version 1.0.4 - Calcula solo el checksum del último MB del fichero.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2012-03-16
#*/ ##
function ogCalculateChecksum ()
{
# Variables locales.
local FILE
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath" \
"$FUNCNAME REPO ubuntu.img ==> ef899299caf8b517ce36f1157a93d8bf"
return
fi
# Comprobar que existe el fichero y devolver sus datos.
FILE=$(ogGetPath "$@")
[ -n "$FILE" ] || ogRaiseError $OG_ERR_NOTFOUND "$*" || return $?
tail -c1M "$FILE" | md5sum -b 2>&1 | cut -f1 -d" "
}
#/**
# ogCompareChecksumFiles [ str_repo | int_ndisk int_npart ] path_source [ str_repo | int_ndisk int_npart ] path_target
#@brief Metafunción que compara las sumas de comprobación almacenadas de 2 ficheros.
#@return bool_compare Valor de comparación.
#@warning No es necesario especificar la extensión ".sum".
#@version 0.9.2 - Primera versión para OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010-07-24
#*/ ##
function ogCompareChecksumFiles ()
{
# Variables locales.
local ARGS SOURCE TARGET
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath" \
"if $FUNCNAME REPO ubuntu.img CACHE ubuntu.img; then ...; fi"
return
fi
ARGS="$@"
case "$1" in
/*) # Camino completo. */ (Comentrio Doxygen)
SOURCE=$(ogGetPath "$1")
shift ;;
[1-9]*) # ndisco npartición.
SOURCE=$(ogGetPath "$1" "$2" "$3")
shift 3 ;;
*) # Otros: repo, cache, cdrom (no se permiten caminos relativos).
SOURCE=$(ogGetPath "$1" "$2")
shift 2 ;;
esac
TARGET=$(ogGetPath "$@")
# Comparar los ficheros de checksum.
test "$(cat "$SOURCE.sum" 2>/dev/null)" == "$(cat "$TARGET.sum" 2>/dev/null)"
}
#/**
# ogCalculateFullChecksum [ str_repo | int_ndisk int_npart ] path_filepath
#@brief Devuelve la suma COMPLETA de comprobación (checksum) de un fichero.
#@param path_filepath camino del fichero (independiente de mayúsculas)
#@param str_repo repositorio de ficheros
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return hex_checksum Checksum del fichero
#@version 1.0.5 - Primera versión para OpenGnSys.
#@author Antonio Doblas Viso, EVLT Universidad de Málaga
#@date 2014-07-09
#*/ ##
function ogCalculateFullChecksum ()
{
# Variables locales.
local FILE
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath" \
"$FUNCNAME REPO ubuntu.img ==> ef899299caf8b517ce36f1157a93d8bf"
return
fi
# Comprobar que existe el fichero y devolver sus datos.
FILE=$(ogGetPath "$@")
[ -n "$FILE" ] || ogRaiseError $OG_ERR_NOTFOUND "$*" || return $?
#ADV
md5sum "$FILE" -b 2>&1 | cut -f1 -d" "
# tail -c1M "$FILE" | md5sum -b 2>&1 | cut -f1 -d" "
}
#/**
# ogCopyFile [ str_repo | int_ndisk int_npart ] path_source [ str_repo | int_ndisk int_npart ] path_target
#@brief Metafunción para copiar un fichero de sistema OpenGnSys a un directorio.
#@see ogGetPath
#@return Progreso de la copia.
#@warning Deben existir tanto el fichero origen como el directorio destino.
#@version 0.9 - Pruebas con OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-10-20
#@version 1.0.4 - Copiar usando rsync.
#@author Universidad de Huelva
#@date 2012-07-06
#*/ ##
function ogCopyFile ()
{
# Variables locales.
local ARGS SOURCE TARGET
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_source [ str_repo | int_ndisk int_npartition ] path_target" \
"$FUNCNAME REPO newfile.txt 1 2 /tmp/newfile.txt"
return
fi
ARGS="$@"
case "$1" in
/*) # Camino completo. */ (Comentrio Doxygen)
SOURCE="$(ogGetPath "$1")"
shift ;;
[1-9]*) # ndisco npartición.
SOURCE="$(ogGetPath "$1" "$2" "$3")"
shift 3 ;;
*) # Otros: repo, cache, cdrom (no se permiten caminos relativos).
SOURCE="$(ogGetPath "$1" "$2")"
shift 2 ;;
esac
# Comprobar fichero origen y directorio destino.
[ -n "$SOURCE" ] || ogRaiseError $OG_ERR_NOTFOUND "${ARGS% $*}" || return $?
TARGET="$(ogGetPath "$@")"
[ -n "$TARGET" ] || ogRaiseError $OG_ERR_NOTFOUND "$*" || return $?
# Copiar fichero (para evitar problemas de comunicaciones las copias se hacen con rsync en vez de cp).
rsync --progress --inplace -avh "$SOURCE" "$TARGET"
}
#/**
# ogDeleteFile [ str_repo | int_ndisk int_npartition ] path_filepath
#@brief Metafunción que borra un fichero de un dispositivo.
#@see ogGetPath
#@version 0.9 - Pruebas con OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-09-29
#*/ ##
function ogDeleteFile ()
{
# Variables locales.
local FILE
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_file" \
"$FUNCNAME 1 2 /tmp/newfile.txt"
return
fi
# Comprobar que existe el fichero y borrarlo.
FILE="$(ogGetPath "$@")"
[ -n "$FILE" ] || ogRaiseError $OG_ERR_NOTFOUND "$*" || return $?
rm -f "$FILE" || ogRaiseError $OG_ERR_NOTFOUND "$*" || return $?
}
#/**
# ogDeleteTree [ str_repo | int_ndisk int_npartition ] path_dirpath
#@brief Metafunción que borra todo un subárbol de directorios de un dispositivo.
#@see ogGetPath
#@version 0.9 - Pruebas con OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-09-29
#*/ ##
function ogDeleteTree ()
{
# Variables locales.
local DIR
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_dir" \
"$FUNCNAME 1 2 /tmp/newdir"
return
fi
# Comprobar que existe el directorio y borrarlo con su contenido.
DIR="$(ogGetPath "$@")"
[ -n "$DIR" ] || ogRaiseError $OG_ERR_NOTFOUND "$*" || return $?
rm -fr "$DIR" || ogRaiseError $OG_ERR_NOTFOUND "$*" || return $?
}
#/**
# ogGetPath [ str_repo | int_ndisk int_npartition ] path_filepath
#@brief Inicia el proceso de arranque de un sistema de archivos.
#@param path_filepath camino del fichero (independiente de mayúsculas)
#@param str_repo repositorio de ficheros
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return path_file - camino completo real del fichero.
#@note repo = { REPO, CACHE, CDROM }
#@note Requisitos: \c grep \c sed
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero o dispositivo no encontrado.
#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar.
#@warning En caso de error, sólo devuelve el código y no da mensajes.
#@todo Terminar de definir parámetros para acceso a repositorios.
#@version 0.1 - Integracion para Opengnsys - HIDRA: CaminoWindows.sh; EAC: GetPath(), FormatSintaxSpacePath(), FormatSintaxBackSlashPath (), en FileSystem.lib
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@Date 2008/10/10
#@author Antonio J. Doblas Viso. Universidad de Malaga
#@date 2008/10/27
#@version 0.9 - Pruebas con OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-09-15
#@version 1.1.1 - Correccion comentarios autodocumentacion doxygen .
#@author Antonio J. Doblas Viso. Universidad de Malaga
#@date 2018-07-05
#*/ ##
function ogGetPath ()
{
# Variables locales.
local MNTDIR FILE PREVFILE FILEPATH CURRENTDIR
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath" \
"$FUNCNAME \"/mnt/sda1/windows/system32\" ==> /mnt/sda1/WINDOWS/System32" \
"$FUNCNAME REPO /etc/fstab ==> /opt/opengnsys/images/etc/fstab" \
"$FUNCNAME 1 1 \"/windows/system32\" ==> /mnt/sda1/WINDOWS/System32"
return
fi
# Procesar camino según el número de parámetros.
case $# in
1) FILE="$1" ;;
2) case "${1^^}" in
REPO)
FILE="$OGIMG/$2" ;;
CACHE)
MNTDIR="$(ogMountCache)" || return $?
FILE="$MNTDIR/$OGIMG/$2" ;;
CDROM)
MNTDIR="$(ogMountCdrom)" || return $?
FILE="$MNTDIR/$2" ;;
*) ogRaiseError $OG_ERR_FORMAT
return $? ;;
esac ;;
3) MNTDIR="$(ogMount $1 $2)" || return $?
FILE="$MNTDIR/$3" ;;
*) ogRaiseError $OG_ERR_FORMAT
return $? ;;
esac
# Eliminar caracteres \c / duplicados y finales.
FILE="$(echo $FILE|sed -e 's/\(\/\)*\1/\//g; s/\/$//')"
# Comprobar si existe el fichero para reducir tiempos.
if [ -e "$FILE" ]; then
FILEPATH="$FILE"
else
# Buscar el nombre correcto en cada subdirectorio del camino.
FILEPATH="/"
while [ "$FILE" != "$PREVFILE" ]; do
FILEPATH="$(ls -d "${FILEPATH%/}/${FILE%%/*}" 2>/dev/null || find "$FILEPATH" -maxdepth 1 -iname "${FILE%%/*}" -print 2>/dev/null)" #*/ (Comentario Doxygen)
PREVFILE="$FILE"
FILE="${FILE#*/}"
done
fi
[ -n "$FILEPATH" ] && echo "$FILEPATH"
return 0
}
#/**
# ogGetParentPath [ str_repo | int_ndisk int_npartition ] path_filepath
#@brief Metafunción que devuelve el camino del directorio padre.
#@see ogGetPath
#@version 0.9 - Pruebas con OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-09-29
#*/ ##
function ogGetParentPath ()
{
local PARENT
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath" \
"$FUNCNAME \"/mnt/sda1/windows/system32\" ==> /mnt/sda1/WINDOWS" \
"$FUNCNAME REPO /etc/fstab ==> /opt/opengnsys/images/etc" \
"$FUNCNAME 1 1 \"/windows/system32\" ==> /mnt/sda1/WINDOWS"
return
fi
case $# in
1) PARENT="$(dirname "$1")" ;;
2) PARENT="$1 $(dirname "/$2")" ;;
3) PARENT="$1 $2 $(dirname "/$3")" ;;
*) ogRaiseError $OG_ERR_FORMAT
return $? ;;
esac
ogGetPath $PARENT
}
#/**
# ogIsNewerFile [ str_repo | int_ndisk int_npart ] path_source [ str_repo | int_ndisk int_npart ] path_target
#@brief Metafunción que indica se un fichero es más nuevo que otro.
#@see ogGetPath
#@return Código de salida: 0 - nuevo, 1 - antiguo o error
#@warning Deben existir tanto el fichero origen como el destino.
#@version 0.9.2 - Primera versión para OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010-07-24
#@version 1.0.1 - Devolver falso en caso de error.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-05-18
#*/ ##
function ogIsNewerFile ()
{
# Variables locales.
local ARGS SOURCE TARGET
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_source [ str_repo | int_ndisk int_npartition ] path_target" \
"if $FUNCNAME REPO ubuntu.img CACHE ubuntu.img; then ... fi"
return
fi
ARGS="$@"
case "$1" in
/*) # Camino completo. */ (Comentrio Doxygen)
SOURCE="$(ogGetPath "$1")"
shift ;;
[1-9]*) # ndisco npartición.
SOURCE="$(ogGetPath "$1" "$2" "$3")"
shift 3 ;;
*) # Otros: repo, cache, cdrom (no se permiten caminos relativos).
SOURCE="$(ogGetPath "$1" "$2")"
shift 2 ;;
esac
# Comprobar que existen los ficheros origen y destino.
[ -n "$SOURCE" ] || ogRaiseError $OG_ERR_NOTFOUND "${ARGS% $*}" || return 1
TARGET=$(ogGetPath "$@")
[ -n "$TARGET" ] || ogRaiseError $OG_ERR_NOTFOUND "$*" || return 1
# Devolver si el primer fichero se ha modificado después que el segundo.
test "$SOURCE" -nt "$TARGET"
}
#/**
# ogMakeChecksumFile [ str_repo | int_ndisk int_npart ] path_filepath
#@brief Metafunción que guarda el valor de comprobación de un fichero.
#@see ogCalculateChecksum
#@warning Genera un fichero con extensión ".sum".
#@version 0.9.2 - Primera versión para OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010-07-24
#*/ ##
function ogMakeChecksumFile ()
{
# Variables locales.
local FILE
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath" \
"$FUNCNAME REPO ubuntu.img"
return
fi
# Comprobar que existe el fichero y guardar su checksum.
FILE="$(ogGetPath "$@")"
[ -n "$FILE" ] || ogRaiseError $OG_ERR_NOTFOUND "$*" || return $?
ogCalculateChecksum "$FILE" > "$FILE.sum"
}
#/**
# ogMakeDir [ str_repo | int_ndisk int_npartition ] path_dirpath
#@brief Metafunción que crea un subdirectorio vacío en un dispositivo.
#@see ogGetParentPath
#@version 0.1 - Integracion para Opengnsys - HIDRA: CrearDirectorio.sh, EAC: MkdirPath() en FileSystem.lib
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@Date 2008/10/10
#@author Antonio J. Doblas Viso. Universidad de Malaga
#@date 2008/10/27
#@version 0.9 - Pruebas con OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-09-29
#*/ ##
function ogMakeDir ()
{
local PARENT DIR
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_dir" \
"$FUNCNAME 1 2 /tmp/newdir"
return
fi
PARENT="$(ogGetParentPath "$@")" || return $?
DIR="$(basename "${!#}")"
mkdir -p "$PARENT/$DIR" || ogRaiseError $OG_ERR_NOTFOUND "$*" || return $?
}

View File

@ -1,517 +0,0 @@
#/**
#@file FileLib.py
#@brief Librería o clase File
#@class File
#@brief Funciones para gestión de archivos y directorios.
#@warning License: GNU GPLv3+
#*/
import subprocess
import os
import shutil
import hashlib
import ogGlobals
import SystemLib
import CacheLib
import FileSystemLib
#/**
# ogCalculateChecksum [ str_repo | int_ndisk int_npart ] path_filepath
#@brief Devuelve la suma de comprobación (checksum) de un fichero.
#@param path_filepath camino del fichero (independiente de mayúsculas)
#@param str_repo repositorio de ficheros
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return hex_checksum Checksum del fichero
#*/ ##
#ogCalculateChecksum ([ str_repo | int_ndisk int_npartition ] path_filepath")
#ogCalculateChecksum (container='REPO', file='ubuntu.img') ==> ef899299caf8b517ce36f1157a93d8bf
#ogCalculateChecksum (disk=1, par=1, file='ubuntu.img') ==> ef899299caf8b517ce36f1157a93d8bf
def ogCalculateChecksum (disk=None, par=None, container=None, file=None):
if file is None:
raise TypeError ('missing required argument: "file"')
if container is not None:
if disk is None and par is None:
## we were given container=
f = ogGetPath (src=container, file=file)
dev_err = f'{container} {file}'
print (f'ogGetPath (src=({container}), file=({file})) = f ({f})')
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
f = ogGetPath (src=f'{disk} {par}', file=file)
dev_err = f'{disk} {par} {file}'
print (f'ogGetPath (src=({disk} {par}), file=({file})) = f ({f})')
elif disk is None and par is None:
## we were given nothing
f = ogGetPath (file=file)
dev_err = file
print (f'ogGetPath (file=({file})) = f ({f})')
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
if not f:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, dev_err)
return
last_n_bytes = 1024*1024
if last_n_bytes >= os.stat (f).st_size:
return ogCalculateFullChecksum (disk, par, container, file)
with open (f, 'rb') as fd:
fd.seek (-last_n_bytes, os.SEEK_END)
data = fd.read()
md5 = hashlib.md5(data).hexdigest()
return md5
#/**
# ogCompareChecksumFiles [ str_repo | int_ndisk int_npart ] path_source [ str_repo | int_ndisk int_npart ] path_target
#@brief Metafunción que compara las sumas de comprobación almacenadas de 2 ficheros.
#@return bool_compare Valor de comparación.
#@warning No es necesario especificar la extensión ".sum".
#*/ ##
def ogCompareChecksumFiles(*args):
# Variables locales.
ARGS = args
if "help" in args:
SystemLib.ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath", "if $FUNCNAME REPO ubuntu.img CACHE ubuntu.img; then ...; fi")
return
ARGS = args
if args[0].startswith("/"):
# Camino completo. */ (Comentario Doxygen)
SOURCE = ogGetPath(*args[:1])
args = args[1:]
elif args[0].isdigit():
# ndisco npartición.
SOURCE = ogGetPath(*args[:3])
args = args[3:]
else:
# Otros: repo, cache, cdrom (no se permiten caminos relativos).
SOURCE = ogGetPath(*args[:2])
args = args[2:]
TARGET = ogGetPath(*args)
try:
with open(f"{SOURCE}.sum", "r") as source_file:
source_checksum = source_file.read().strip()
with open(f"{TARGET}.sum", "r") as target_file:
target_checksum = target_file.read().strip()
return source_checksum == target_checksum
except FileNotFoundError:
return False
#/**
# ogCalculateFullChecksum [ str_repo | int_ndisk int_npart ] path_filepath
#@brief Devuelve la suma COMPLETA de comprobación (checksum) de un fichero.
#@param path_filepath camino del fichero (independiente de mayúsculas)
#@param str_repo repositorio de ficheros
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return hex_checksum Checksum del fichero
#*/ ##
def ogCalculateFullChecksum (disk=None, par=None, container=None, file=None):
if file is None:
raise TypeError ('missing required argument: "file"')
if container is not None:
if disk is None and par is None:
## we were given container=
f = ogGetPath (src=container, file=file)
dev_err = f'{container} {file}'
print (f'ogGetPath (src=({container}), file=({file})) = f ({f})')
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
f = ogGetPath (src=f'{disk} {par}', file=file)
dev_err = f'{disk} {par} {file}'
print (f'ogGetPath (src=({disk} {par}), file=({file})) = f ({f})')
elif disk is None and par is None:
## we were given nothing
f = ogGetPath (file=file)
dev_err = file
print (f'ogGetPath (file=({file})) = f ({f})')
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
if not f:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, dev_err)
return
md5 = hashlib.md5()
with open (f, 'rb') as fd:
for chunk in iter (lambda: fd.read (64*1024), b''):
md5.update (chunk)
return md5.hexdigest()
#/**
# ogCopyFile [ str_repo | int_ndisk int_npart ] path_source [ str_repo | int_ndisk int_npart ] path_target
#@brief Metafunción para copiar un fichero de sistema OpenGnSys a un directorio.
#@see ogGetPath
#@return Progreso de la copia.
#@warning Deben existir tanto el fichero origen como el directorio destino.
#*/ ##
#ogCopyFile (src, dst)
#ogCopyFile ({container='REPO', file='newfile.txt'}, {disk=1, par=2, file='/tmp/newfile.txt'})
#ogCopyFile ({disk=1, par=2, file='/tmp/newfile.txt'}, {container='REPO', file='newfile.txt'})
def ogCopyFile (src, dst):
for elem in src, dst:
if elem == src: which = 'source'
else: which = 'target'
if 'file' not in elem:
raise TypeError ('missing required argument in {which} dict:: "file"')
if 'container' in elem:
if 'disk' not in elem and 'par' not in elem:
## we were given container=
path = ogGetPath (src=elem['container'], file=elem['file'])
dev_err = f'{elem["container"]} {elem["file"]}'
print (f'ogGetPath {which} (src=({elem["container"]}), file=({elem["file"]})) = path ({path})')
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if 'disk' in elem and 'par' in elem:
## we were given disk= par=
path = ogGetPath (src=f'{elem["disk"]} {elem["par"]}', file=elem['file'])
dev_err = f'{elem["disk"]} {elem["par"]} {elem["file"]}'
print (f'ogGetPath {which} (src=({elem["disk"]} {elem["par"]}), file=({elem["file"]})) = path ({path})')
elif 'disk' not in elem and 'par' not in elem:
## we were given nothing
path = ogGetPath (file=elem['file'])
dev_err = elem['file']
print (f'ogGetPath {which} (file=({elem["file"]})) = path ({path})')
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
if elem == src:
SOURCE = path
src_dev_err = dev_err
else:
TARGET = path
dst_dev_err = dev_err
if not SOURCE:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {src_dev_err} not found')
return
if not TARGET:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dst_dev_err} not found')
return
print (f'nati: ogCopyFile: SOURCE ({SOURCE}) TARGET ({TARGET})')
# Copiar fichero (para evitar problemas de comunicaciones las copias se hacen con rsync en vez de cp).
print (f'nati: ogCopyFile: rsync --progress --inplace -avh ({SOURCE}) ({TARGET})')
result = subprocess.run(["rsync", "--progress", "--inplace", "-avh", SOURCE, TARGET], capture_output=True, text=True)
return result.returncode
#/**
# ogDeleteFile [ str_repo | int_ndisk int_npartition ] path_filepath
#@brief Metafunción que borra un fichero de un dispositivo.
#@see ogGetPath
#@version 0.9 - Pruebas con OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-09-29
#*/ ##
#ogDeleteFile ([ str_repo | int_ndisk int_npartition ] path_file)
#ogDeleteFile (container='REPO', file='/tmp/newfile.txt')
#ogDeleteFile (disk=1, par=2, file='/tmp/newfile.txt')
def ogDeleteFile (disk=None, par=None, container=None, file=None):
if file is None:
raise TypeError ('missing required argument: "file"')
if container is not None:
if disk is None and par is None:
## we were given container=
src = container
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
src = f'{disk} {par}'
else:
## we were given nothing
raise TypeError ('either "container" or both "disk" and "par" must be specified')
f = ogGetPath (src=src, file=file)
if not f:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{src} {file}')
return
try:
os.remove (f)
except OSError as e:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, str (e))
return
#/**
# ogDeleteTree [ str_repo | int_ndisk int_npartition ] path_dirpath
#@brief Metafunción que borra todo un subárbol de directorios de un dispositivo.
#@see ogGetPath
#*/ ##
#ogDeleteTree (container='REPO', file='/tmp/newdir')
#ogDeleteTree (disk=1, par=2, file='/tmp/newdir')
def ogDeleteTree (disk=None, par=None, container=None, file=None):
if file is None:
raise TypeError ('missing required argument: "file"')
if container is not None:
if disk is None and par is None:
## we were given container=
src = container
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
src = f'{disk} {par}'
else:
## we were given nothing
raise TypeError ('either "container" or both "disk" and "par" must be specified')
f = ogGetPath (src=src, file=file)
if not f:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{src} {file}')
return
try:
shutil.rmtree (f)
except OSError as e:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, e)
return
#/**
# ogGetPath [ str_repo | int_ndisk int_npartition ] path_filepath
#@brief Inicia el proceso de arranque de un sistema de archivos.
#@param path_filepath camino del fichero (independiente de mayúsculas)
#@param str_repo repositorio de ficheros
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return path_file - camino completo real del fichero.
#@note repo = { REPO, CACHE, CDROM }
#@note Requisitos: \c grep \c sed
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero o dispositivo no encontrado.
#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar.
#@warning En caso de error, sólo devuelve el código y no da mensajes.
#@todo Terminar de definir parámetros para acceso a repositorios.
#*/ ##
#ogGetPath (file='/mnt/sda1/windows/system32') ==> '/mnt/sda1/WINDOWS/System32'
#ogGetPath (src='REPO', file='/etc/fstab') ==> '/opt/opengnsys/images/etc/fstab'
#ogGetPath (src='1 1', file='/windows/system32') ==> '/mnt/sda1/WINDOWS/System32'
def ogGetPath (src=None, file=None):
if file is None:
raise TypeError ('missing required argument: "file"')
f = file
if src is not None:
if 'REPO' == src:
f = os.path.join (ogGlobals.OGIMG, file.strip('/'))
elif 'CACHE' == src:
mntdir = CacheLib.ogMountCache()
if not mntdir: return None
f = os.path.join (mntdir, ogGlobals.OGIMG.strip('/'), file.strip('/'))
elif 'CDROM' == src:
mntdir = FileSystemLib.ogMountCdrom()
if not mntdir: return None
f = os.path.join (mntdir, file.strip('/'))
else:
try:
disk, part = src.split()
except ValueError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '')
return
mntdir = FileSystemLib.ogMount (disk, part)
if not mntdir: return None
f = os.path.join (mntdir, file.strip('/'))
f = os.path.normpath (f)
if os.path.exists (f):
filepath = f
#print (f'f ({f}) existe, filepath=f ({filepath})')
else:
# Buscar el nombre correcto en cada subdirectorio del camino.
prevfile = ''
filepath = '/'
#print (f'f ({f}) prevfile ({prevfile})')
while f != prevfile:
#print ('\nno son iguales, nueva iteracion...')
f_first_component = f.split ('/')[0] ## take 1st component
ls_path = os.path.join (filepath, f_first_component) ## "ls" makes reference to the original bash version
#print (f'f_first_component ({f_first_component}) ls_path ({ls_path})')
## build filepath to return
if os.path.exists (ls_path):
filepath = ls_path
#print (f'ls_path existe, filepath ({filepath})')
else:
filepath = subprocess.run (['find', filepath, '-maxdepth', '1', '-iname', f_first_component, '-print'], capture_output=True, text=True).stdout.strip()
#print (f'ls_path no existe, filepath ({filepath})')
prevfile = f
if '/' in f:
f = '/'.join (f.split('/')[1:]) ## remove 1st component
#print (f'f ({f}) prevfile ({prevfile})')
return filepath
#/**
# ogGetParentPath [ str_repo | int_ndisk int_npartition ] path_filepath
#@brief Metafunción que devuelve el camino del directorio padre.
#@see ogGetPath
#*/ ##
#ogGetParentPath ([ str_repo | int_ndisk int_npartition ] path_filepath
#ogGetParentPath ( file='/mnt/sda1/windows/system32') ==> '/mnt/sda1/WINDOWS'
#ogGetParentPath (src='REPO', file='/etc/fstab') ==> '/opt/opengnsys/images/etc'
#ogGetParentPath (src='1 1', file='/windows/system32') ==> '/mnt/sda1/WINDOWS'
def ogGetParentPath (src=None, file=None):
if file is None:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '')
return
if src is None:
return ogGetPath (file=os.path.dirname (file))
else:
return ogGetPath (src=src, file=os.path.dirname('/'+file))
#/**
# ogIsNewerFile [ str_repo | int_ndisk int_npart ] path_source [ str_repo | int_ndisk int_npart ] path_target
#@brief Metafunción que indica se un fichero es más nuevo que otro.
#@see ogGetPath
#@return Código de salida: 0 - nuevo, 1 - antiguo o error
#@warning Deben existir tanto el fichero origen como el destino.
#*/ ##
def ogIsNewerFile(*args):
# Variables locales.
ARGS = args
if "help" in args:
SystemLib.ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_source [ str_repo | int_ndisk int_npartition ] path_target", "if $FUNCNAME REPO ubuntu.img CACHE ubuntu.img; then ... fi")
return
ARGS = args
if args[0].startswith("/"):
# Camino completo. */ (Comentrio Doxygen)
SOURCE = ogGetPath(*args[:1])
args = args[1:]
elif args[0].isdigit():
# ndisco npartición.
SOURCE = ogGetPath(*args[:3])
args = args[3:]
else:
# Otros: repo, cache, cdrom (no se permiten caminos relativos).
SOURCE = ogGetPath(*args[:2])
args = args[2:]
TARGET = ogGetPath(*args)
# Comprobar que existen los ficheros origen y destino.
if not SOURCE:
SystemLib.ogRaiseError(
"session",
ogGlobals.OG_ERR_NOTFOUND,
f"Not found: {args[:-1]}"
)
return
if not TARGET:
SystemLib.ogRaiseError(
"session",
ogGlobals.OG_ERR_NOTFOUND,
f"Not found: {args[-1]}"
)
return
# Devolver si el primer fichero se ha modificado después que el segundo.
return os.path.getmtime(SOURCE) > os.path.getmtime(TARGET)
#/**
# ogMakeChecksumFile [ str_repo | int_ndisk int_npart ] path_filepath
#@brief Metafunción que guarda el valor de comprobación de un fichero.
#@see ogCalculateChecksum
#@warning Genera un fichero con extensión ".sum".
#*/ ##
def ogMakeChecksumFile(*args):
# Variables locales.
FILE = None
if "help" in args:
SystemLib.ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath", "$FUNCNAME REPO ubuntu.img")
return
# Comprobar que existe el fichero y guardar su checksum.
FILE = ogGetPath(*args)
if not FILE:
SystemLib.ogRaiseError(
"session",
ogGlobals.OG_ERR_NOTFOUND,
f"Not found: {args}"
)
return
checksum = ogCalculateChecksum(FILE)
with open(f"{FILE}.sum", "w") as f:
f.write(checksum)
#/**
# ogMakeDir [ str_repo | int_ndisk int_npartition ] path_dirpath
#@brief Metafunción que crea un subdirectorio vacío en un dispositivo.
#@see ogGetParentPath
#*/ ##
#ogMakeDir (container='REPO', file='/tmp/newdir')
#ogMakeDir (disk='1', par='2', file='/tmp/newdir')
def ogMakeDir (container=None, disk=None, par=None, file=None):
if file is None:
raise TypeError ('missing required argument: "file"')
if container is not None:
if disk is None and par is None:
## we were given container=
parent = ogGetParentPath (src=container, file=file)
dev_err = f'{container} {file}'
print (f'ogGetParentPath (src=({container}), file=({file})) = parent ({parent})')
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
parent = ogGetParentPath (src=f'{disk} {par}', file=file)
dev_err = f'{disk} {par} {file}'
print (f'ogGetParentPath (src=({disk} {par}), file=({file})) = parent ({parent})')
elif disk is None and par is None:
## we were given nothing
parent = ogGetParentPath (file=file)
dev_err = file
print (f'ogGetParentPath (file=({file})) = parent ({parent})')
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
print (f'nati: ogMakeDir: parent ({parent})')
if not parent:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found')
return None
dst = os.path.basename (file)
print (f'nati: ogMakeDir: dst ({dst})')
os.makedirs (os.path.join (parent, dst), exist_ok=True)
return True

File diff suppressed because it is too large Load Diff

View File

@ -1,906 +0,0 @@
#/**
#@file FileSystemLib.py
#@brief Librería o clase FileSystem
#@class FileSystem
#@brief Funciones para gestión de sistemas de archivos.
#@warning License: GNU GPLv3+
#*/
import subprocess
import sys
import os.path
import ogGlobals
import SystemLib
import DiskLib
import CacheLib
import FileSystemLib
#/**
# ogCheckFs int_ndisk int_nfilesys
#@brief Comprueba el estado de un sistema de archivos.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#@exception OG_ERR_PARTITION Partición desconocida o no accesible.
#@note Requisitos: *fsck*
#@warning No se comprueban sistemas de archivos montados o bloqueados.
#@todo Definir salidas.
#*/ ##
def ogCheckFs (disk, par):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return
data = {
'EXT2': { 'prog': 'e2fsck', 'params': '-y', 'codes': (1, 2), },
'EXT3': { 'prog': 'e2fsck', 'params': '-y', 'codes': (1, 2), },
'EXT4': { 'prog': 'e2fsck', 'params': '-y', 'codes': (1, 2), },
'CACHE': { 'prog': 'e2fsck', 'params': '-y', 'codes': (1, 2), },
'BTRFS': { 'prog': 'btrfsck', 'codes': (1), },
'REISERFS': { 'prog': 'fsck.reiserfs', 'codes': (1, 2), 'input': 'Yes' },
'REISER4': { 'prog': 'fsck.reiser4', 'params': '-ay', },
'JFS': { 'prog': 'fsck.jfs', 'codes': (1, 2), },
'XFS': { 'prog': 'xfs_repair', },
'F2FS': { 'prog': 'fsck.f2fs', },
'NTFS': { 'prog': 'ntfsfix', },
'EXFAT': { 'prog': 'fsck.exfat', },
'FAT32': { 'prog': 'dosfsck', 'params': '-a', 'codes': (1), },
'FAT16': { 'prog': 'dosfsck', 'params': '-a', 'codes': (1), },
'FAT12': { 'prog': 'dosfsck', 'params': '-a', 'codes': (1), },
'HFS': { 'prog': 'fsck.hfs', 'params': '-f', },
'HFSPLUS': { 'prog': 'fsck.hfs', 'params': '-f', },
'UFS': { 'prog': 'fsck.ufs', },
'ZFS': { 'prog': 'fsck.zfs', },
}
type = ogGetFsType (disk, par)
if type in data:
prog = data[type]['prog']
params = data[type]['params'] if 'params' in data[type] else ''
codes = data[type]['codes'] if 'codes' in data[type] else []
input = data[type]['input'] if 'input' in data[type] else None
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk}, {par}, {type}')
return None
ogUnmount (disk, par)
if ogIsMounted (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}')
return None
if ogIsLocked (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{disk} {par}')
return None
ogLock (disk, par)
rc = subprocess.run ([prog] + params.split() + [PART], input=input, text=True).returncode
if 0 == rc or rc in codes:
errcode = 0
elif 127 == rc:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTEXEC, prog)
errcode = ogGlobals.OG_ERR_NOTEXEC
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}')
errcode = ogGlobals.OG_ERR_PARTITION
ogUnlock (disk, par)
return not errcode ## reverse to indicate success
#/**
# ogExtendFs int_ndisk int_nfilesys
#@brief Extiende un sistema de archivos al tamaño de su partición.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#@exception OG_ERR_PARTITION Partición desconocida o no accesible.
#@note Requisitos: *resize*
#*/ ##
def ogExtendFs (disk, par):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return
data = {
'EXT2': { 'prog': 'resize2fs', 'params': '-f', },
'EXT3': { 'prog': 'resize2fs', 'params': '-f', },
'EXT4': { 'prog': 'resize2fs', 'params': '-f', },
'BTRFS': { 'prog': 'btrfs', 'params': 'filesystem resize max', 'domount': True },
'REISERFS': { 'prog': 'resize_reiserfs', 'params': '-f', },
'REISER4': { 'prog': 'resize_reiserfs', 'params': '-f', },
'NTFS': { 'prog': 'ntfsresize', 'params': '-f', 'input': 'y' },
'F2FS': { 'unsupported': True },
'JFS': { 'unsupported': True },
'NILFS2': { 'unsupported': True }, # try "nilfs-resize"
'XFS': { 'unsupported': True },
'EXFAT': { 'unsupported': True },
'FAT32': { 'unsupported': True }, # try "fatresize"
'FAT16': { 'unsupported': True }, # try "fatresize"
'HFS': { 'unsupported': True },
'HFSPLUS': { 'unsupported': True },
'UFS': { 'unsupported': True },
}
type = ogGetFsType (disk, par)
if type in data:
prog = data[type]['prog'] if 'prog' in data[type] else None
params = data[type]['params'] if 'params' in data[type] else None
domount = data[type]['domount'] if 'domount' in data[type] else False
input = data[type]['input'] if 'input' in data[type] else None
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par} {type}')
return
if not prog: return None
if domount:
PART = ogMount (disk, par)
if not PART: return None
else:
ogUnmount (disk, par)
if ogIsMounted (disk, par):
SystemLib.ogRaiseError([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}')
return None
# Error si el sistema de archivos está bloqueado.
if ogIsLocked (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{disk} {par}')
return None
# Redimensionar en modo uso exclusivo.
ogLock (disk, par)
try:
if input:
rc = subprocess.run ([prog] + params.split() + [PART], input=input, text=True).returncode
else:
rc = subprocess.run ([prog] + params.split() + [PART]).returncode
except FileNotFoundError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTEXEC, prog)
rc = ogGlobals.OG_ERR_NOTEXEC
except:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}')
rc = ogGlobals.OG_ERR_PARTITION
ogUnlock (disk, par)
return not rc ## reverse to indicate success
#/**
# ogFormat int_ndisk int_nfilesys | CACHE
#@see ogFormatFs ogFormatCache
#*/ ##
def ogFormat (disk, par=None, fs=None, label=None):
if disk.lower() == "cache":
return CacheLib.ogFormatCache()
else:
return ogFormatFs (disk, par, fs=fs, label=label)
#/**
# ogFormatFs int_ndisk int_nfilesys [type_fstype] [str_label]
#@brief Formatea un sistema de ficheros según el tipo de su partición.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@param type_fstype mnemónico de sistema de ficheros a formatear (opcional al reformatear)
#@param str_label etiqueta de volumen (opcional)
#@return (por determinar)
#@exception OG_ERR_FORMAT Formato de ejecución incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#@exception OG_ERR_PARTITION Partición no accesible o desconocida.
#@note Requisitos: mkfs*
#@warning No formatea particiones montadas ni bloqueadas.
#@todo Definir salidas.
#*/ ##
def ogFormatFs (disk, par, fs=None, label=None):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return
if ogIsMounted (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_DONTFORMAT, f'{ogGlobals.lang.MSG_MOUNT}: {disk} {par}')
return None
if ogIsLocked (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f"{disk} {par}")
return None
if not fs:
fs = ogGetFsType (disk, par)
if not fs:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f"{disk} {par} ...")
return None
data = {
'EXT2': { 'PROG': 'mkfs.ext2', 'PARAMS': '-F' },
'EXT3': { 'PROG': 'mkfs.ext3', 'PARAMS': '-F' },
'EXT4': { 'PROG': 'mkfs.ext4', 'PARAMS': '-F' },
'BTRFS': { 'PROG': 'mkfs.btrfs', 'PARAMS': '-f' },
'REISERFS': { 'PROG': 'mkfs.reiserfs', 'PARAMS': '-f', 'LABELPARAM': '-l' },
'REISER4': { 'PROG': 'mkfs.reiser4', 'PARAMS': '-f', 'INPUT': 'y\n' },
'XFS': { 'PROG': 'mkfs.xfs', 'PARAMS': '-f' },
'JFS': { 'PROG': 'mkfs.jfs', 'INPUT': 'y\n' },
'F2FS': { 'PROG': 'mkfs.f2fs', 'LABELPARAM': '-l' },
'NILFS2': { 'PROG': 'mkfs.nilfs2', 'PARAMS': '-f' },
'LINUX-SWAP': { 'PROG': 'mkswap' },
'NTFS': { 'PROG': 'mkntfs', 'PARAMS': '-f' },
'EXFAT': { 'PROG': 'mkfs.exfat', 'LABELPARAM': '-n' },
'FAT32': { 'PROG': 'mkdosfs', 'PARAMS': '-F 32', 'LABELPARAM': '-n' },
'FAT16': { 'PROG': 'mkdosfs', 'PARAMS': '-F 16', 'LABELPARAM': '-n' },
'FAT12': { 'PROG': 'mkdosfs', 'PARAMS': '-F 12', 'LABELPARAM': '-n' },
'HFS': { 'PROG': 'mkfs.hfs' },
'HFSPLUS': { 'PROG': 'mkfs.hfsplus', 'LABELPARAM': '-v' },
'UFS': { 'PROG': 'mkfs.ufs', 'PARAMS': '-O 2' },
}
if fs not in data:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk} {par} {fs}")
return
d = data[fs]
prog = d['PROG']
params = d['PARAMS'] if 'PARAMS' in d else ''
labelparam = d['LABELPARAM'] if 'LABELPARAM' in d else ''
input = d['INPUT'] if 'INPUT' in d else ''
if label == "CACHE":
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f"{ogGlobals.lang.MSG_RESERVEDVALUE}: CACHE")
return
if label:
params = f"{params} {labelparam or '-L'} {label}"
ogLock (disk, par)
subprocess.run (['umount', PART])
try:
if input:
errcode = subprocess.run ([prog] + params.split (' ') + [PART]).returncode
else:
errcode = subprocess.run ([prog] + params.split (' ') + [PART], input=input, text=True).returncode
except FileNotFoundError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTEXEC, prog)
errcode = ogGlobals.OG_ERR_NOTEXEC
except:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk} {par}")
errcode = ogGlobals.OG_ERR_PARTITION
ogUnlock (disk, par)
return errcode
#/**
# ogGetFsSize int_ndisk int_npartition [str_unit]
#@brief Muestra el tamanio del sistema de archivos indicado, permite definir la unidad de medida, por defecto GB
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_unit unidad (opcional, por defecto: KB)
#@return float_size - Tamaño del sistema de archivos
#@note str_unit = { KB, MB, GB, TB }
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o partición no corresponden con un dispositivo.
#*/ ##
def ogGetFsSize (disk, par, unit='KB'):
factor = 1
if unit.upper() == "MB":
factor = 1024
elif unit.upper() == "GB":
factor = 1024 * 1024
elif unit.upper() == "TB":
factor = 1024 * 1024 * 1024
elif unit.upper() != "KB":
SystemLib.ogRaiseError (
[],
ogGlobals.OG_ERR_FORMAT,
f"{unit} != {{ KB, MB, GB, TB }}"
)
return
# Obtener el tamaño del sistema de archivo (si no está formateado; tamaño = 0).
mnt = FileSystemLib.ogMount (disk, par)
if mnt:
result = subprocess.run(["df", "-BK", mnt], capture_output=True, text=True)
val = result.stdout.split("\n")[1].split()[1]
val = val.replace ('K', '')
sz = int (val) / factor
else:
sz = 0
return int (sz)
#/**
# ogGetFsType int_ndisk int_nfilesys
#@brief Devuelve el mnemonico con el tipo de sistema de archivos.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@return Mnemonico
#@note Mnemonico: { EXT2, EXT3, EXT4, BTRFS, REISERFS, XFS, JFS, FAT12, FAT16, FAT32, NTFS, LINUX-SWAP, LINUX-LVM, LINUX-RAID, HFS, HFSPLUS, CACHE }
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#*/ ##
def ogGetFsType(disk, part):
PART = DiskLib.ogDiskToDev(disk, part)
if not PART: return
TYPE = None
if PART.startswith("/"):
out = subprocess.run(["blkid", "-o", "export", PART], capture_output=True, text=True).stdout.splitlines()
for line in out:
if line.startswith("TYPE="):
TYPE = line.split("=")[1].upper()
break
else:
try:
subprocess.run(["zfs", "mount", PART])
except FileNotFoundError:
SystemLib.ogRaiseError (
[],
ogGlobals.OG_ERR_NOTEXEC,
'zfs'
)
return
out = subprocess.run(["mount"], capture_output=True, text=True).stdout.splitlines()
for line in out:
if line.startswith(PART):
TYPE = line.split()[4].upper()
break
if not TYPE:
SystemLib.ogRaiseError (
[],
ogGlobals.OG_ERR_NOTFOUND,
f'{disk} {part}'
)
return
# Componer valores correctos.
if TYPE == "EXT4":
if f"{disk} {part}" == CacheLib.ogFindCache():
if ogIsFormated(disk, part):
TYPE = "CACHE"
elif TYPE == "VFAT":
result = subprocess.run(["blkid", "-po", "export", PART], capture_output=True, text=True)
for line in result.stdout.split("\n"):
if line.startswith("VERSION="):
TYPE = line.split("=")[1].upper()
break
elif TYPE == "SWAP":
TYPE = "LINUX-SWAP"
elif TYPE.startswith("LVM"):
TYPE = "LINUX-LVM"
elif "RAID" in TYPE:
TYPE = "LINUX-RAID"
elif TYPE == "ZFS_MEMBER":
TYPE = "ZVOL"
elif "_MEMBER" in TYPE:
TYPE = TYPE.replace("_MEMBER", "")
return TYPE
#/**
# ogGetMountPoint int_ndisk int_nfilesys
#@brief Devuelve el punto de montaje de un sistema de archivos.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@return Punto de montaje
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#@note Requisitos: \c mount* \c awk
#*/ ##
def ogGetMountPoint(disk, par):
PART = DiskLib.ogDiskToDev(disk, par)
if not PART: return
return subprocess.run(["findmnt", "-n", "-o", "TARGET", PART], capture_output=True, text=True).stdout.strip()
#/**
# ogIsFormated int_ndisk int_nfilesys
#@brief Comprueba si un sistema de archivos está formateado.
#@param int_ndisk nº de orden del disco o volumen.
#@param int_nfilesys nº de orden del sistema de archivos
#@return Código de salida: True - formateado, False - sin formato o error.
#*/ ##
def ogIsFormated(disk, part):
PART = DiskLib.ogDiskToDev (disk, part)
if not PART:
return
# Revisar tipo de sistema de archivos.
if PART.startswith("/"):
out = subprocess.run(["blkid", "-s", "TYPE", PART], capture_output=True, text=True).stdout.strip()
if 'swap' in out: return False
if '_member' in out: return False
return bool(out)
else:
out = subprocess.run(["zfs", "list", "-Hp", "-o", "canmount", PART], capture_output=True, text=True).stdout.strip()
return out == "on"
#/**
# ogIsLocked int_ndisk int_npartition
#@see ogIsPartitionLocked
#*/
def ogIsLocked(disk, par):
return ogIsPartitionLocked(disk, par)
#/**
# ogIsPartitionLocked int_ndisk int_npartition
#@brief Comprueba si una partición o su disco están bloqueados por una operación de uso exclusivo.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return Código de salida: 0 - bloqueado, 1 - sin bloquear o error.
#@note Los ficheros de bloqueo se localizan en \c /var/lock/dev, siendo \c dev el dispositivo de la partición o de su disco, sustituyendo el carácter "/" por "-".
#*/ ##
def ogIsPartitionLocked(disk, par):
DISK = DiskLib.ogDiskToDev(disk)
PART = DiskLib.ogDiskToDev(disk, par)
if not PART: return
LOCKDISK = f"/var/lock/lock{DISK.replace('/', '-')}"
LOCKPART = f"/var/lock/lock{PART.replace('/', '-')}"
rc = os.path.isfile(LOCKDISK) or os.path.isfile(LOCKPART)
return rc
#/**
# ogIsMounted int_ndisk int_nfilesys
#@brief Comprueba si un sistema de archivos está montado.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@return Código de salida: 0 - montado, 1 - sin montar o error.
#*/ ##
def ogIsMounted (disk, par):
return bool (ogGetMountPoint (disk, par))
#/**
# ogIsReadonly int_ndisk int_nfilesys
#@brief Comprueba si un sistema de archivos está montado solo de lectura.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@return Código de salida: 0 - montado solo de lectura, 1 - con escritura o no montado.
#@version 1.1.0 - Primera versión para OpenGnsys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2016-01-20
#*/ ##
def ogIsReadonly(disk, par):
PART = DiskLib.ogDiskToDev(disk, par)
if not PART: return
result = subprocess.run(["findmnt", "-n", "-o", "OPTIONS", PART], capture_output=True, text=True)
options = result.stdout.strip().split(",")
return "ro" in options
#/**
# ogIsWritable int_ndisk int_nfilesys
#@brief Comprueba si un sistema de archivos está montado de lectura y escritura.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@return Código de salida: 0 - lectura y escritura, 1 - solo lectura o no montado.
#*/ ##
def ogIsWritable (disk, par):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return
result = subprocess.run(["findmnt", "-n", "-o", "OPTIONS", PART], capture_output=True, text=True)
options = result.stdout.strip().split(",")
return "rw" in options
#/**
# ogLock int_ndisk int_npartition
#@see ogLockPartition
#*/
def ogLock(disk, par):
return ogLockPartition(disk, par)
#/**
# ogLockPartition int_ndisk int_npartition
#@brief Genera un fichero de bloqueo para una partición en uso exlusivo.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#@note El fichero de bloqueo se localiza en \c /var/lock/part, siendo \c part el dispositivo de la partición, sustituyendo el carácter "/" por "-".
#*/ ##
def ogLockPartition (disk, par):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return
LOCKFILE = f"/var/lock/lock{PART.replace('/', '-')}"
try:
open (LOCKFILE, 'w').close()
except:
return False
return True
#/**
# ogMount int_ndisk int_nfilesys
#@see ogMountFs ogMountCache ogMountCdrom
#*/ ##
def ogMount(*args):
if 1 == len (args):
if 'cache' == args[0].lower():
return DiskLib.ogMountCache()
elif 'cdrom' == args[0].lower():
return ogMountCdrom()
elif 2 == len (args):
return ogMountFs(args[0], args[1])
#/**
# ogMountFirstFs int_ndisk
#@brief Monta el primer sistema de archivos disponible en el disco.
#@param int_ndisk nº de orden del disco
#@return Punto de montaje del primer sistema de archivos detectado
#*/ ##
def ogMountFirstFs (disk):
NPARTS = DiskLib.ogGetPartitionsNumber (disk)
for PART in range (1, NPARTS + 1):
MNTDIR = ogMount (disk, PART)
if MNTDIR:
return MNTDIR
SystemLib.ogRaiseError ('session', ogGlobals.OG_ERR_NOTFOUND, f'{disk}')
return ogGlobals.OG_ERR_NOTFOUND
#/**
# ogMountFs int_ndisk int_nfilesys
#@brief Monta un sistema de archivos.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@return Punto de montaje
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#@exception OG_ERR_PARTITION Tipo de particion desconocido o no se puede montar.
#*/ ##
def ogMountFs (disk, par):
dev = DiskLib.ogDiskToDev (disk, par)
if not dev: return
mntdir = ogGetMountPoint (disk, par)
if mntdir: return mntdir
if ogIsLocked (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_PARTITION}, {disk} {par}')
return
# El camino de un dispositivo normal comienza por el carácter "/".
if dev.startswith ('/'):
# Crear punto de montaje o enlace simbólico para caché local.
mntdir = dev.replace ('/dev', '/mnt')
if f"{disk} {par}" == CacheLib.ogFindCache():
os.makedirs(ogGlobals.OGCAC, exist_ok=True)
try:
os.symlink(ogGlobals.OGCAC, mntdir)
except FileExistsError:
pass
else:
os.makedirs(mntdir, exist_ok=True)
# Montar sistema de archivos.
try:
rc = subprocess.run(['mount', dev, mntdir], check=True).returncode
except subprocess.CalledProcessError:
try:
rc = subprocess.run(['mount', dev, mntdir, '-o', 'force,remove_hiberfile'], check=True).returncode
except subprocess.CalledProcessError:
SystemLib.ogRaiseError (
[],
ogGlobals.OG_ERR_PARTITION,
f"{disk}, {par}"
)
return
if 0 == rc:
pass
elif 14 == rc:
try:
subprocess.run (['ntfsfix', '-d', par], check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError (
[],
ogGlobals.OG_ERR_PARTITION,
f"{disk, par}"
)
#return
else:
try:
subprocess.run (['mount', par, mntdir, '-o', 'ro'], check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError (
[],
ogGlobals.OG_ERR_PARTITION,
f"{disk, par}"
)
#return
# Aviso de montaje de solo lectura.
if ogIsReadonly(disk, par):
SystemLib.ogEcho("warning", f'ogMountFs: {ogGlobals.lang.MSG_MOUNTREADONLY}: "{disk}, {par}"')
else:
# Montar sistema de archivos ZFS (un ZPOOL no comienza por "/").
subprocess.run(['zfs', 'mount', dev])
return mntdir
#/**
# ogMountCdrom
#@brief Monta dispositivo óptico por defecto
#@return Punto de montaje
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_PARTITION Tipo de particion desconocido o no se puede montar.
#@version
#@author
#@date
#*/ ##
def ogMountCdrom():
DEV = '/dev/cdrom' # Por defecto
outlines = subprocess.run (['mount'], capture_output=True, text=True).stdout.split ('\n')
mntdir = ''
for l in outlines:
items = l.split (' ')
if DEV == items[0]:
mntdir = items[2]
break
if not mntdir:
mntdir = DEV.replace ('/dev', '/mnt')
os.makedirs (mntdir, exist_ok=True)
try:
subprocess.run (['mount', '-t', 'iso9660', DEV, mntdir], check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'cdrom')
return None
return mntdir
#/**
# ogReduceFs int_ndisk int_nfilesys
#@brief Reduce el tamaño del sistema de archivos, sin tener en cuenta el espacio libre.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@return int_tamañoKB - tamaño en KB
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#@exception OG_ERR_PARTITION Partición desconocida o no accesible.
#@warning En Windows, se borran los ficheros de hiberanción y de paginación.
#@warning El sistema de archivos se amplía al mínimo + 10%.
#@note Requisitos: *resize*
#*/ ##
def ogReduceFs (disk, par):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return
# Redimensionar según el tipo de partición.
type = ogGetFsType (disk, par)
if type in ['EXT2', 'EXT3', 'EXT4']:
ogUnmount (disk, par)
rc = subprocess.run (['resize2fs', '-fpM', PART], capture_output=True, text=True).returncode
if rc:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk},{par}")
return None
elif 'BTRFS' == type:
mntdir = ogMount (disk, par)
# Calcular tamaño ocupado + 10%, redondeado + 1 (incluyendo letra de unidad).
btrfs_lines = subprocess.run (['btrfs', 'filesystem', 'show', mntdir], capture_output=True, text=True).stdout.splitlines()
for l in btrfs_lines:
if 'devid' not in l: continue
## 'devid 2 size 8.89GiB used 1.00GiB path /dev/sda4'
devid_str, devid, size_str, size, used_str, used, path_str, path = l.split()
if PART != os.path.realpath (path): continue
(sz, unit) = re.search ('^([^A-Z]+)([A-Z])', used).groups()
sz = float (sz) * 1.1 + 1
size = f'{str(sz)}{unit}'
subprocess.run (['btrfs', 'filesystem', 'resize', size, mntdir], capture_output=True, text=True)
break
elif type in ['REISERFS', 'REISER4']:
mntdir = ogMount (disk, par)
df_lines = subprocess.run (['df', '-k', mntdir], capture_output=True, text=True).stdout.splitlines()
for l in df_lines:
if 'Filesystem' in l: continue
fs, blocks, used, avail, use_pct, mntpt = l.split()
size = str (int (used) * 1.1)
ogUnmount (disk, par)
subprocess.run (['resize_reiserfs', f'-s{size}K', PART], input='y\n', capture_output=True, text=True)
break
elif type == 'NTFS':
ogUnmount (disk, par)
nr_lines = subprocess.run (['ntfsresize', '-fi', PART], capture_output=True, text=True).stdout.splitlines()
maxsize = None
size = None
for l in nr_lines:
if 'device size' in l:
maxsize = float (l.split()[3])
if 'resize at' in l:
size = l.split()[4]
size = int ((int (size) * 1.1 / 1024 + 1) * 1024)
if not maxsize and not size:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk},{par}')
return None
import time
extrasize = 0
retval = 1
while retval != 0 and size+extrasize < maxsize:
nr = subprocess.run (['ntfsresize', '-fns', str(size), PART], capture_output=True, text=True)
for l in nr.stdout.splitlines():
if 'Needed relocations' not in l: continue
extrasize = int ((int (l.split()[3])*1.1/1024+1)*1024)
break
retval = nr.returncode
size += extrasize
if size < maxsize:
rc = subprocess.run (['ntfsresize', '-fs', str(size), PART], input='y\n', capture_output=True, text=True).returncode
if rc:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk},{par}")
return None
elif type in ['FAT32', 'FAT16', 'F2FS', 'JFS', 'NILFS2', 'XFS', 'EXFAT', 'HFS', 'HFSPLUS', 'UFS']:
pass
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk},{par}")
return None
return ogGetFsSize (disk, par)
#/**
# ogUnlock int_ndisk int_npartition
#@see ogUnlockPartition
#*/ ##
def ogUnlock (disk, par):
return ogUnlockPartition (disk, par)
#/**
# ogUnlockPartition int_ndisk int_npartition
#@brief Elimina el fichero de bloqueo para una particion.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#@note El fichero de bloqueo se localiza en \c /var/lock/part, siendo \c part el dispositivo de la partición, sustituyendo el carácter "/" por "-".
#*/ ##
def ogUnlockPartition (disk, par):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return
LOCKFILE = f"/var/lock/lock{PART.replace('/', '-')}"
if os.path.exists (LOCKFILE):
os.remove (LOCKFILE)
#/**
# ogUnmount int_ndisk int_npartition
#@see ogUnmountFs
#*/ ##
def ogUnmount (disk, par):
return ogUnmountFs (disk, par)
#/**
# ogUnmountFs int_ndisk int_nfilesys
#@brief Desmonta un sistema de archivos.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@return Nada
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#@warning La partición no está previamente montada o no se puede desmontar.
#*/ ##
def ogUnmountFs(disk, par):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return
MNTDIR = ogGetMountPoint (disk, par)
# Si está montada, desmontarla.
if MNTDIR:
# Error si la particion está bloqueada.
if ogIsLocked (disk, par):
SystemLib.ogRaiseError (
[],
ogGlobals.OG_ERR_LOCKED,
f"{ogGlobals.lang.MSG_PARTITION}, {disk} {par}"
)
return
# Desmontar y borrar punto de montaje.
try:
subprocess.run(["umount", PART], check=True)
except subprocess.CalledProcessError:
SystemLib.ogEcho("warning", f'ogUnmountFs: {ogGlobals.lang.MSG_DONTUNMOUNT}: "{disk}, {par}"')
try:
os.rmdir(MNTDIR)
except:
try:
os.remove(MNTDIR)
except:
pass
return True
else:
SystemLib.ogEcho ([], "warning", f'{ogGlobals.lang.MSG_DONTMOUNT}: "{disk},{par}"')
return True
#/**
# ogUnmountAll int_ndisk
#@brief Desmonta todos los sistema de archivos de un disco, excepto el caché local.
#@param int_ndisk nº de orden del disco
#@return Nada
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#@warning No se desmonta la partición marcada como caché local.
#*/ ##
def ogUnmountAll (disk):
DISK = DiskLib.ogDiskToDev (disk)
n = DiskLib.ogGetPartitionsNumber (disk)
if not n: return None
for PART in range (1, n+1):
if 'CACHE' != ogGetFsType (disk, PART):
ogUnmount (disk, PART)
#/**
# ogUnsetDirtyBit int_ndisk int_npart
#@brief Inhabilita el Dirty Bit del sistema de ficheros NTFS para evitar un CHKDSK en el primer arranque
#@param int_ndisk nº de orden del disco
#@param int_npart nº de orden de partición
#@return Nada
#@exception OG_ERR_FORMAT Formato incorrecto.
#*/ ##
def ogUnsetDirtyBit (disk, par):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return None
TYPE = ogGetFsType (disk, par)
if 'NTFS' == TYPE:
ogUnmount (disk, par)
subprocess.run (['ntfsfix', '--clear-dirty', PART])
#/**
# ogGetFreeSize int_disco int_partition str_SizeOutput
#@brief muestra informacion del tamaño total, datos y libre.
#@param int_ndisk nº de orden del disco
#@param int_npart nº de orden de partición
#@param str_unitSize unidad mostrada
#@return int_size:int_data:int_free
#@TODO Componer corretcamente esta función.
#@exception OG_ERR_FORMAT Formato incorrecto.
#*/ ##
def ogGetFreeSize(disk, part, unit='KB'):
PART = DiskLib.ogDiskToDev (disk, part)
if not PART: return
unit2factor = {
'kb': 1.024 / 1,
'mb': 1.024 / 1000,
'gb': 1.024 / 1000000,
}
if unit.lower() not in unit2factor:
kk
factor = unit2factor[unit.lower()]
particion = FileSystemLib.ogMount (disk, part)
if not particion:
kk
df = subprocess.run (['df'], capture_output=True, text=True).stdout
df_part = list (filter (lambda l: particion in l, df.splitlines()))
if not len (df_part):
kk
_, size, used, free, pct, mntpt = df_part[0].split()
return float (free) * factor

File diff suppressed because it is too large Load Diff

View File

@ -1,836 +0,0 @@
#!/usr/bin/python3
import shutil
import subprocess
import os
import os.path
import re
from pathlib import Path
import DiskLib
import FileSystemLib
import SystemLib
import ogGlobals
import FileLib
import CacheLib
import NetLib
## ProtocolLib.ogUcastSyntax() calls ogCreateImageSyntax()
## in ogCreateImageSyntax(), param2 may contain a pipe or may be empty
## if param2 is empty, then ogUcastSyntax():
## - does a .split()
## - accesses the third element of the resulting array (ie. does "parts[2]")
## - promptly gets an IndexError exception
##
## param2 in ogCreateImageSyntax() only contains a pipe if 'mbuffer' is installed
## therefore, a hard dependency on mbuffer is created
##
## raise an Exception at import time if mbuffer is not present
if not shutil.which ('mbuffer'):
raise FileNotFoundError ('"mbuffer" utility must be present')
#/**
#@file ImageLib.py
#@brief Librería o clase Image
#@class Image
#@brief Funciones para creación, restauración y clonación de imágenes de sistemas.
#@warning License: GNU GPLv3+
#*/
#/**
# ogCreateImageSyntax path_device path_filename [str_tool] [str_compressionlevel]
#@brief Genera una cadena de texto con la instrucción para crear un fichero imagen
#@param path_device dispositivo Linux del sistema de archivos
#@param path_fileneme path absoluto del fichero imagen
#@param [opcional] str_tool herrmaienta de clonacion [partimage, partclone, ntfsclone]
#@param [opcional] str_compressionlevel nivel de compresion. [0 -none-, 1-lzop-, 2-gzip]
#@return str_command - cadena con el comando que se debe ejecutar.
#@warning Salida nula si se producen errores.
#@TODO introducir las herramientas fsarchiver, dd
#*/ ##
#ogCreateImageSyntax /dev/sda1 /opt/opengnsys/images/prueba.img partclone lzop
#ogCreateImageSyntax /dev/sda1 /opt/opengnsys/images/prueba.img
def ogCreateImageSyntax (dev, imgfile, tool='partclone', level='gzip'):
if 'ntfsclone' == tool:
param1 = f'ntfsclone --force --save-image -O - {dev}'
elif 'partimage' == tool or 'default' == tool:
param1 = f'partimage -M -f3 -o -d -B gui=no -c -z0 --volume=0 save {dev} stdout'
elif 'partclone' == tool:
disk, part = DiskLib.ogDevToDisk (dev).split()
fs = FileSystemLib.ogGetFsType (disk, part)
param1 = {
'EXT2': 'partclone.extfs',
'EXT3': 'partclone.extfs',
'EXT4': 'partclone.extfs',
'BTRFS': 'partclone.btrfs',
'REISERFS': 'partclone.reiserfs',
'REISER4': 'partclone.reiser4',
'JFS': 'partclone.jfs',
'XFS': 'partclone.xfs',
'F2FS': 'partclone.f2fs',
'NILFS2': 'partclone.nilfs2',
'NTFS': 'partclone.ntfs',
'EXFAT': 'partclone.exfat',
'FAT16': 'partclone.fat',
'FAT32': 'partclone.fat',
'HFS': 'partclone.hfsp',
'HFSPLUS': 'partclone.hfsp',
'UFS': 'partclone.ufs',
'VMFS': 'partclone.vmfs',
}.get (fs, 'partclone.imager')
dash_c = '-c'
if not shutil.which (param1):
param1 = 'partclone.dd'
# Algunas versiones de partclone.dd no tienen opción "-c".
out = subprocess.run (['partclone.dd', '--help'], capture_output=True, text=True).stdout
if ' -c' not in out: dash_c = ''
param1=f'{param1} -d0 -F {dash_c} -s {dev}'
else:
raise Exception (f'unknown tool "{tool}"')
param2 = '| mbuffer -q -m 40M ' if shutil.which ('mbuffer') else ' '
param3 = {
0: ' > ',
'none': ' > ',
1: ' | lzop > ',
'lzop': ' | lzop > ',
2: ' | gzip -c > ',
'gzip': ' | gzip -c > ',
3: ' | bzip -c > ',
'bzip': ' | bzip -c > ',
}.get (level, ' > ')
#print (f'param1 ({param1}) param2 ({param2}) param3 ({param3}) imgfile ({imgfile})')
if param1: return f'{param1} {param2} {param3} {imgfile}'
#/**
# ogRestoreImageSyntax path_filename path_device [str_tools] [str_compressionlevel]
#@brief Genera una cadena de texto con la instrucción para crear un fichero imagen
#@param path_device dispositivo Linux del sistema de archivos
#@param path_fileneme path absoluto del fichero imagen
#@param [opcional] str_tools herrmaienta de clonacion [partimage, partclone, ntfsclone]
#@param [opcional] str_compressionlevel nivel de compresion. [0 -none-, 1-lzop-, 2-gzip]
#@return cadena con el comando que se debe ejecutar.
#@exception OG_ERR_FORMAT formato incorrecto.
#@warning En pruebas iniciales
#@TODO introducir las herramientas fsarchiver, dd
#@TODO introducir el nivel de compresion gzip
#*/ ##
#ogRestoreImageSyntax /opt/opengnsys/images/prueba.img /dev/sda1 [partclone] [lzop]
def ogRestoreImageSyntax (imgfile, part, tool=None, level=None):
if not os.path.exists (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
## original bash code is broken: 'return' is never called
#return
if tool is None or level is None:
infoimg = ogGetImageInfo (imgfile)
if not infoimg:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'no image {imgfile}')
## original bash code is broken: 'return' is never called
#return
try:
tool, level = infoimg.split (':')[0:2]
except:
tool, level = '', ''
return ogRestoreImageSyntax (imgfile, part, tool, level)
tool = tool.lower()
level = level.lower()
compressor = {
0: ' ',
'none': ' ',
1: ' lzop -dc ',
'lzop': ' lzop -dc ',
2: ' gzip -dc ',
'gzip': ' gzip -dc ',
3: ' bzip -dc ',
'bzip': ' bzip -dc ',
}.get (level, '')
#print (f'tool ({tool}) level ({level}) compressor ({compressor})')
if compressor == '':
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'Compressor no valid {level}')
## original bash code is broken: 'return' is never called
#return
mbuffer = '| mbuffer -q -m 40M ' if shutil.which ('mbuffer') else ' '
#print (f'mbuffer ({mbuffer})')
if 'ntfsclone' == tool:
tool = f'| ntfsclone --restore-image --overwrite {part} -'
elif 'partimage' == tool:
tool = f'| partimage -f3 -B gui=no restore {part} stdin'
elif 'partclone' in tool:
# -C para que no compruebe tamaños
tool = f'| partclone.restore -d0 -C -I -o {part}'
elif 'dd' == tool:
tool = f'| pv | dd conv=sync,noerror bs=1M of={part}'
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'Tools imaging no valid {tool}')
## original bash code is broken: 'return' is never called
#return
#print (f'tool ({tool})')
return f'{compressor} {imgfile} {mbuffer} {tool}'.strip()
#/**
# ogCreateDiskImage int_ndisk str_repo path_image [str_tools] [str_compressionlevel]
#@brief Crea una imagen (copia de seguridad) de un disco completo.
#@param int_ndisk nº de orden del disco
#@param str_repo repositorio de imágenes (remoto o caché local)
#@param path_image camino de la imagen (sin extensión)
#@return (nada, por determinar)
#@note repo = { REPO, CACHE }
#@note Esta primera versión crea imágenes con dd comprimidas con gzip.
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@exception OG_ERR_LOCKED particion bloqueada por otra operación.
#@exception OG_ERR_IMAGE error al crear la imagen del sistema.
#@warning En pruebas iniciales
#@todo Gestión de bloqueos de disco
#@todo Comprobar si debe desmontarse la caché local
#@todo Comprobar que no se crea la imagen en el propio disco
#*/ ##
#/**
# ogCreateImage int_ndisk int_npartition str_repo path_image [str_tools] [str_compressionlevel]
#@brief Crea una imagen a partir de una partición.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_repo repositorio de imágenes (remoto o caché local)
#@param path_image camino de la imagen (sin extensión)
#@param [opcional] str_tools herrmaienta de clonacion [partimage, partclone, ntfsclone]
#@param [opcional] str_compressionlevel nivel de compresion. [0 -none-, 1-lzop-, 2-gzip]
#@return (nada, por determinar)
#@note repo = { REPO, CACHE }
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@exception OG_ERR_PARTITION partición no accesible o no soportada.
#@exception OG_ERR_LOCKED particion bloqueada por otra operación.
#@exception OG_ERR_IMAGE error al crear la imagen del sistema.
#@todo Comprobaciones, control de errores, definir parámetros, etc.
#*/ ##
def ogCreateImage (disk, par, container, imgfile, tool='partclone', level='gzip'):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return None
if FileSystemLib.ogIsLocked (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_ERR_LOCKED} {disk}, {par}')
return None
imgtype = 'img' # Extensión genérica de imágenes.
imgdir = FileLib.ogGetParentPath (src=container, file=imgfile)
if not imgdir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{container} {imgfile}')
return None
bn = os.path.basename (imgfile)
IMGFILE = f'{imgdir}/{bn}.{imgtype}'
if ogIsImageLocked (IMGFILE):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_IMAGE} {container}, {imgfile}')
return None
# Generar la instruccion a ejecutar antes de aplicar los bloqueos.
program = ogCreateImageSyntax (PART, IMGFILE, tool=tool, level=level)
# Desmontar partición, bloquear partición e imagen.
FileSystemLib.ogUnmount (disk, par)
if not FileSystemLib.ogLock (disk, par):
return None
if not ogLockImage (container, f'{imgfile}.{imgtype}'):
return None
# Crear Imagen.
#trap
p = subprocess.run (program, shell=True, check=True)
errcode = p.returncode
if 0 == errcode:
i = ogGetImageInfo (IMGFILE)
h = NetLib.ogGetHostname()
with open (f'{IMGFILE}.info', 'w') as fd:
fd.write (f'{i}:{h}\n')
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f'{disk} {par} {IMGFILE}')
if os.path.exists (IMGFILE):
os.unlink (IMGFILE)
FileSystemLib.ogUnlock (disk, par)
ogUnlockImage (container, f'{imgfile}.{imgtype}')
return not errcode ## reverse to indicate success
#/**
# ogCreateMbrImage int_ndisk str_repo path_image
#@brief Crea una imagen a partir del sector de arranque de un disco.
#@param int_ndisk nº de orden del disco
#@param str_repo repositorio de imágenes (remoto o caché local)
#@param path_image camino de la imagen (sin extensión)
#@return (nada, por determinar)
#@note repo = { REPO, CACHE }
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@exception OG_ERR_IMAGE error al crear la imagen del sistema.
#*/ ##
#/**
# ogCreateBootLoaderImage int_ndisk str_repo path_image
#@brief Crea una imagen del boot loader a partir del sector de arranque de un disco.
#@param int_ndisk nº de orden del disco
#@param str_repo repositorio de imágenes (remoto o caché local)
#@param path_image camino de la imagen (sin extensión)
#@return (nada, por determinar)
#@note repo = { REPO, CACHE }
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@exception OG_ERR_IMAGE error al crear la imagen del sistema.
#*/ ##
#/**
# ogGetSizeParameters int_num_disk int_num_part str_repo [monolit|sync|diff]
#@brief Devuelve el tamaño de los datos de un sistema de ficheros, el espacio necesario para la imagen y si cabe en el repositorio elegido.
#@param int_disk numero de disco
#@param int_part numero de particion
#@param str_repo repositorio de imágenes { REPO, CACHE }
#@param str_imageName Nombre de la imagen
#@param str_imageType Tipo de imagen: monolit (por defecto), sync o diff. (parametro opcional)
#@return SIZEDATA SIZEREQUIRED SIZEFREE ISENOUGHSPACE
#@note si str_imageType= diff necesario /tmp/ogimg.info, que es creado por ogCreateInfoImage.
#@note para el tamaño de la imagen no sigue enlaces simbólicos.
#@exception OG_ERR_FORMAT formato incorrecto.
#*/ ##
#SIZEDATA, SIZEREQUIRED, SIZEFREE, ISENOUGHSPACE = ogGetSizeParameters (1, 1, 'REPO', 'myimg')
def ogGetSizeParameters (disk, par, repo, imgname, imgtype=None):
repo = repo.upper()
## imgtype se soporta como parametro pero se ignora
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}')
return None
#if [ "$IMGTYPE" == "_DIFF_" ]; then cosas
#else:
sizedata = None
df_out = subprocess.run (['df', '-k'], capture_output=True, text=True).stdout
for l in df_out.splitlines():
if (re.search (f'{mntdir}$', l)):
sizedata = int (l.split()[2])
break
if sizedata is None:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, 'sizedata is None')
return None
#if [ "$IMGTYPE" == "_SYNC_" -o "$IMGTYPE" == "_DIFF_" ]; then cosas
#else:
factorgzip=55/100
factorlzop=65/100
sizerequired = sizedata * factorlzop
#Comprobar espacio libre en el contenedor.
sizefree = None
if 'CACHE' == repo:
CACHEPART = CacheLib.ogFindCache()
if not CACHEPART:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTCACHE, '')
return None
cache_disk, cache_par = CACHEPART.split()
sizefree = FileSystemLib.ogGetFreeSize (cache_disk, cache_par)
if 'REPO' == repo:
df_out = subprocess.run (['df', '-k'], capture_output=True, text=True).stdout
for l in df_out.splitlines():
if (re.search (f'{ogGlobals.OGIMG}', l)):
sizefree = int (l.split()[3])
break
if sizefree is None:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, 'sizefree is None')
return None
# Comprobamos si existe una imagen con el mismo nombre en $REPO
# En sincronizadas restamos tamaño de la imagen y en monoloticas de la .ant
#case "${IMGTYPE}" in blah blah
#*)
imgext = 'img.ant'
imgdir = FileLib.ogGetParentPath (src=repo, file=f'/{imgname}')
bn = os.path.basename (f'/{imgname}')
imgfile = FileLib.ogGetPath (file=f'{imgdir}/{bn}.{imgext}')
if not imgfile:
imgsize = 0
else:
ls_out = subprocess.run (['ls', '-s', imgfile], capture_output=True, text=True).stdout
imgsize = int (ls_out.split()[0])
sizefree = sizefree + imgsize
if sizerequired < sizefree:
isenoughspace = True
else:
isenoughspace = False
return sizedata, sizerequired, sizefree, isenoughspace
#/**
# ogIsImageLocked [str_repo] path_image
#@brief Comprueba si una imagen está bloqueada para uso exclusivo.
#@param str_repo repositorio de imágenes (opcional)
#@param path_image camino de la imagen (sin extensión)
#@return Código de salida: 0 - bloqueado, 1 - sin bloquear o error.
#@note repo = { REPO, CACHE }
#@exception OG_ERR_FORMAT formato incorrecto.
#*/ ##
#ogIsImageLocked ('/opt/opengnsys/images/aula1/win7.img')
#ogIsImageLocked ('REPO', '/aula1/win7.img')
def ogIsImageLocked (container=None, imgfile=None):
if container and imgfile:
p = FileLib.ogGetPath (src=container, file=f'{imgfile}.lock')
elif imgfile:
p = FileLib.ogGetPath (file=f'{imgfile}.lock')
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'{container} {imgfile}')
return
return os.path.exists (p)
#/**
# ogLockImage [str_repo] path_image
#@brief Bloquea una imagen para uso exclusivo.
#@param str_repo repositorio de imágenes (opcional)
#@param path_image camino de la imagen (sin extensión)
#@return Nada.
#@note Se genera un fichero con extensión .lock
#@note repo = { REPO, CACHE }
#@exception OG_ERR_FORMAT formato incorrecto.
#*/ ##
def ogLockImage (container=None, imgfile=None):
if not imgfile:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '')
return None
if container:
imgdir = FileLib.ogGetParentPath (src=container, file=imgfile)
else:
imgdir = FileLib.ogGetParentPath (file=imgfile)
try:
bn = os.path.basename (imgfile)
open (f'{imgdir}/{bn}.lock', 'w').close()
return True
except:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTWRITE, f'{container} {imgfile}')
return None
#/**
# ogRestoreDiskImage str_repo path_image int_npartition
#@brief Restaura (recupera) una imagen de un disco completo.
#@param str_repo repositorio de imágenes o caché local
#@param path_image camino de la imagen
#@param int_ndisk nº de orden del disco
#@return (por determinar)
#@warning Primera versión en pruebas
#@todo Gestionar bloqueos de disco
#@todo Comprobar que no se intenta restaurar de la caché sobre el mismo disco
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero de imagen o partición no detectados.
#@exception OG_ERR_LOCKED partición bloqueada por otra operación.
#@exception OG_ERR_IMAGE error al restaurar la imagen del sistema.
#@exception OG_ERR_IMGSIZEPARTITION Tamaño de la particion es menor al tamaño de la imagen.
#*/ ##
#/**
# ogRestoreImage str_repo path_image int_ndisk int_npartition
#@brief Restaura una imagen de sistema de archivos en una partición.
#@param str_repo repositorio de imágenes o caché local
#@param path_image camino de la imagen
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return (por determinar)
#@exception OG_ERR_FORMAT 1 formato incorrecto.
#@exception OG_ERR_NOTFOUND 2 fichero de imagen o partición no detectados.
#@exception OG_ERR_PARTITION 3 # Error en partición de disco.
#@exception OG_ERR_LOCKED 4 partición bloqueada por otra operación.
#@exception OG_ERR_IMAGE 5 error al restaurar la imagen del sistema.
#@exception OG_ERR_IMGSIZEPARTITION 30 Tamaño de la particion es menor al tamaño de la imagen.
#@todo Comprobar incongruencias partición-imagen, control de errores, definir parámetros, caché/repositorio, etc.
#*/ ##
#ogRestoreImage ('REPO', '/aula1/win7', '1', '1')
def ogRestoreImage (repo, imgpath, disk, par):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f' {disk} {par}')
return None
imgtype = 'img'
imgfile = FileLib.ogGetPath (repo, f'{imgpath}.{imgtype}')
if not os.path.exists (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f' {disk} {par}')
return None
if not ogGetImageInfo (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f' {repo} {imgpath}')
return None
# Error si la imagen no cabe en la particion.
imgsize = ogGetImageSize (repo, imgpath)
if not imgsize:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f' {repo} {imgpath}')
return None
if not FileSystemLib.ogMount (disk, par):
FileSystemLib.ogFormat (disk, par)
partsize = DiskLib.ogGetPartitionSize (disk, par)
if float (imgsize) > float (partsize):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMGSIZEPARTITION, f' {partsize} < {imgsize}')
return None
if ogIsImageLocked (container=None, imgfile=imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_IMAGE} {repo}, {imgpath}.{imgtype}')
return None
if FileSystemLib.ogIsLocked (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_PARTITION} {disk}, {par}')
return None
program = ogRestoreImageSyntax (imgfile, PART)
if not FileSystemLib.ogUnmount (disk, par):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f' {disk} {par}')
return None
if not FileSystemLib.ogLock (disk, par):
print (f'not FileSystemLib.ogLock()')
return None
rc = None
try:
p = subprocess.run (program, shell=True, capture_output=True, text=True)
rc = p.returncode
if not rc:
SystemLib.ogRaiseError ([], ogGlobalsOG_ERR_IMAGE, f'{imgfile}, {disk}, {par}')
except:
pass
finally:
FileSystemLib.ogUnlock (disk, par)
return rc
#/**
# ogRestoreMbrImage str_repo path_image int_ndisk
#@brief Restaura la imagen del sector de arranque de un disco.
#@param str_repo repositorio de imágenes o caché local
#@param path_image camino de la imagen
#@param int_ndisk nº de orden del disco
#@return (por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero de imagen o partición no detectados.
#@exception OG_ERR_IMAGE error al restaurar la imagen del sistema.
#*/ ##
#/**
# ogRestoreBootLoaderImage str_repo path_image int_ndisk
#@brief Restaura la imagen del boot loader del sector de arranque de un disco.
#@param str_repo repositorio de imágenes o caché local
#@param path_image camino de la imagen
#@param int_ndisk nº de orden del disco
#@return (por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero de imagen o partición no detectados.
#@exception OG_ERR_IMAGE error al restaurar la imagen del sistema.
#*/ ##
#/**
# ogUnlockImage [str_repo] path_image
#@brief Desbloquea una imagen con uso exclusivo.
#@param str_repo repositorio de imágenes (opcional)
#@param path_image camino de la imagen (sin extensión)
#@return Nada.
#@note repo = { REPO, CACHE }
#@note Se elimina el fichero de bloqueo con extensión .lock
#@exception OG_ERR_FORMAT formato incorrecto.
#*/ ##
#ogUnlockImage REPO /cucu.img
def ogUnlockImage (container=None, imgfile=None):
f = f'{imgfile}.lock'
if container:
p = FileLib.ogGetPath (src=container, file=f)
else:
p = FileLib.ogGetPath (file=f)
if os.path.exists (p):
os.unlink (p)
#/**
# ogGetImageInfo filename
#@brief muestra información sobre la imagen monolitica.
#@param 1 filename path absoluto del fichero imagen
#@return cadena compuesta por clonacion:compresor:sistemaarchivos:tamañoKB
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero no encontrado.
#@exception OG_ERR_IMAGE "Image format is not valid $IMGFILE"
#@warning En pruebas iniciales
#@TODO Definir sintaxis de salida (herramienta y compresor en minuscula)
#@TODO Arreglar loop para ntfsclone
#@TODO insertar parametros entrada tipo OG
#*/ ##
#ogGetImageInfo /opt/opengnsys/images/prueba.img ==> PARTCLONE:LZOP:NTFS:5642158"
def ogGetImageInfo (imgfile):
if not os.path.exists (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
return
imgdetect = False
filehead = f'/tmp/{os.path.basename (imgfile)}.infohead'
compressor = subprocess.run (['file', imgfile], capture_output=True, text=True).stdout.split()[1]
if compressor not in ['gzip', 'lzop']:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f'Image format is not valid {imgfile}')
return
## original bash idiom is: $($COMPRESSOR -dc $IMGFILE 2>/dev/null | head -n 40 > $FILEHEAD) || ogRaiseError
## the purpose of which I can't fully comprehend
#print (f'shelling out "{compressor} -dc {imgfile} |head -n 40 > {filehead}"')
if subprocess.run (f'{compressor} -dc {imgfile} |head -n 40 > {filehead}', shell=True).returncode:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f'Image format is not valid {imgfile}')
return
tools = fs = size = None
if False == imgdetect:
lc_all = os.getenv ('LC_ALL')
os.environ['LC_ALL'] = 'C'
partclone_info = subprocess.run (['partclone.info', filehead], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout
#partclone_info = subprocess.run (['cat', '/tmp/foo-partclone'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout
## sacado de un email de alberto garcía uma.es
#Partclone v0.3.13 http://partclone.org
#Unknown mode
#File system: NTFS
#Device size: 29.2 GB = 7138019 Blocks
#Space in use: 26.6 GB = 6485355 Blocks
#Free Space: 2.7 GB = 652664 Blocks
#Block size: 4096 Byte
#
#image format: 0002
#created on a: 64 bits platform
#with partclone: v0.3.13
#bitmap mode: BIT
#checksum algo: CRC32
#checksum size: 4
#blocks/checksum: 256
if lc_all is not None:
os.environ["LC_ALL"] = lc_all
else:
del os.environ["LC_ALL"]
if 'size' in partclone_info:
tools = 'PARTCLONE'
m = re.search (r'File system *: *(\S+)', partclone_info)
fs = m.group(1) if m else ''
sizefactor = 1000000 if 'GB' in partclone_info else 1024
m = re.search (r'Device size *: *(\S+)', partclone_info)
size = float (m.group(1)) if m else 0
size = int (size * sizefactor)
## why is this?
#if fs in ['HFS', 'HFSPLUS', 'FAT32']:
# #FSPLUS=$(echo $PARTCLONEINFO | awk '{gsub(/\: /,"\n"); print toupper($9);}')
# fsplus = 'PLUS'
# if fsplus: # fs += fsplus ## 'HFS' -> 'HFSPLUS'
imgdetect = True
if False == imgdetect and not os.path.exists ('/dev/loop2'):
filehead_contents = Path (filehead).read_bytes()
if b'ntfsclone-image' in filehead_contents:
#print (f'shelling out "cat {filenead} | ntfsclone --restore --overwrite /dev/loop2 - 2>&1"')
ntfscloneinfo = subprocess.run (f'cat {filenead} | ntfsclone --restore --overwrite /dev/loop2 - 2>&1', shell=True, capture_output=True, text=True).stdout
#ntfscloneinfo = subprocess.run (['cat', '/tmp/foo-ntfsclone'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout
## sacado de claude 3 haiku
#ntfsclone v2023.4.0 (libntfs-3g)
#NTFS volume version: 3.1
#Cluster size: 4096 bytes
#Image volume size: 104857600 bytes (105 MB)
#Space in use: 52428800 bytes (52 MB)
#Reading and restoring NTFS...
#100.00 percent completed
#Syncing ...
#Successfully cloned image to device '/dev/loop2'.
else:
ntfscloneinfo = ''
if 'ntfsclone' in ntfscloneinfo:
tools = 'NTFSCLONE'
m = re.search (r'Image volume size *: *(\S+)', ntfscloneinfo)
size = float (m.group(1))/1000 if m else 0
fs = 'NTFS'
imgdetect = True
if False == imgdetect:
partimageinfo = subprocess.run (['partimage', '-B', 'gui=no', 'imginfo', filehead], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout
#partimageinfo = subprocess.run (['cat', '/tmp/foo-partimage'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout
## sacado de un email de alberto garcía uma.es
#Volume number:.........0
#Volume size:...........1,27 MiB
#Compression level: ....0 -> ninguno
#Identificator:.........12442509728668372730=ACACACACCB9ECEFA
#Filesystem:............ntfs
#Description:...........Sin descripcion
#Original device:......./dev/nvme0n1p2
#Original filepath:.... stdout
#Flags:.................0: Bandera sin activar
#Creation date:.........Mon Nov 11 21:00:22 2024
#Partition size:........476,84 GiB
#Hostname:..............ING-LTR-083
#Compatible Version:....0.6.1
#Encryption algorithm:..0 -> ninguno
#MBR saved count:.......0
partimageinfo = re.sub (r':\s*\.+', ' : ', partimageinfo)
if 'Partition' in partimageinfo:
tools = 'PARTIMAGE'
m = re.search (r'Filesystem *: *(\S+)', partimageinfo)
fs = m.group(1).upper() if m else ''
m = re.search (r'Partition size *: *(\S+)', partimageinfo)
size = m.group(1) if m else ''
size = re.sub (r' [MGT]i?B$', '', size)
size = float (size.replace (',', '.'))
size = int (size*1024*1024)
imgdetect = True
if 'boot sector' in subprocess.run (['file', filehead], capture_output=True, text=True).stdout:
tools = 'partclone.dd'
fs = ''
size = 0
imgdetect = True
if not tools or not compressor or False == imgdetect:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f'Image format is not valid {imgfile}')
return
compressor = compressor.upper()
return ':'.join ([tools, compressor, fs, str (size)])
#/**
# ogGetImageProgram str_REPO str_imagen
#@brief muestra información sobre la imagen monolitica.
#@see ogGetImageInfo
#@param 1 REPO o CACHE contenedor de la imagen
#@param 2 filename nombre de la imagen sin extension
#@return nombre del programa usado para generar la imagen
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero no encontrado.
#@note ogGetImageProgram REPO imagenA -> partclone
#*/ ##
#ogGetImageProgram ('REPO', 'prueba') ==> 'PARTCLONE'
def ogGetImageProgram (container, filename):
imgfile = FileLib.ogGetPath (container, f'{filename}.img')
if not os.path.exists (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
return None
i = ogGetImageInfo (imgfile)
return i.split (':')[0]
#/**
# ogGetImageCompressor str_REPO str_imagen
#@brief muestra información sobre la imagen monolitica.
#@see ogGetImageInfo
#@param 1 REPO o CACHE contenedor de la imagen
#@param 2 filename nombre de la imagen sin extension
#@return tipo de compresión usada al generar la imagen
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero no encontrado.
#@note ogGetImageCompressor REPO imagenA -> lzop
#*/ ##
#ogGetImageCompressor ('REPO', 'prueba') ==> 'LZOP'
def ogGetImageCompressor (container, filename):
imgfile = FileLib.ogGetPath (container, f'{filename}.img')
if not os.path.exists (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
return None
i = ogGetImageInfo (imgfile)
return i.split (':')[1]
#/**
# ogGetImageType str_REPO str_imagen
#@brief muestra información sobre el sistema de archivos de imagen monolitica.
#@see ogGetImageInfo
#@param 1 REPO o CACHE contenedor de la imagen
#@param 2 filename nombre de la imagen sin extension
#@return tipo de compresión usada al generar la imagen
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero no encontrado.
#@note ogGetImageType REPO imagenA -> NTFS
#*/ ##
#ogGetImageType ('REPO', 'imgprueba') ==> 'NTFS'
#ogGetImageType ('CACHE', 'testimg') ==> 'EXTFS'
def ogGetImageType (repo, imgname):
imgfile = FileLib.ogGetPath (src=repo, file=f'{imgname}.img')
if not os.path.exists (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
return None
i = ogGetImageInfo (imgfile)
return i.split (':')[2]
#/**
# ogGetImageSize str_REPO str_imagen
#@brief muestra información sobre el tamaño (KB) del sistema de archivos de imagen monolitica.
#@see ogGetImageInfo
#@param 1 REPO o CACHE contenedor de la imagen
#@param 2 filename nombre de la imagen sin extension
#@return tipo de compresión usada al generar la imagen
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero no encontrado.
#@note ogGetImagesize REPO imagenA -> 56432234 > Kb
#*/ ##
#ogGetImageSize ('REPO', 'prueba') ==> '5642158'
def ogGetImageSize (repo, imgname):
imgfile = FileLib.ogGetPath (src=repo, file=f'{imgname}.img')
if not os.path.exists (imgfile):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile)
return None
i = ogGetImageInfo (imgfile)
return i.split (':')[3]
#/**
# ogCreateGptImage int_ndisk str_repo path_image
#@brief Crea una imagen de la tabla de particiones GPT de un disco.
#@param int_ndisk nº de orden del disco
#@param str_repo repositorio de imágenes (remoto o caché local)
#@param path_image camino de la imagen (sin extensión)
#@return (nada, por determinar)
#@note repo = { REPO, CACHE }
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@exception OG_ERR_IMAGE error al crear la imagen del sistema.
#*/ ##
#/**
# ogRestoreGptImage str_repo path_image int_ndisk
#@brief Restaura la imagen de la tabla de particiones GPT de un disco.
#@param str_repo repositorio de imágenes o caché local
#@param path_image camino de la imagen
#@param int_ndisk nº de orden del disco
#@return (por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero de imagen o partición no detectados.
#@exception OG_ERR_IMAGE error al restaurar la imagen del sistema.
#*/ ##

View File

@ -0,0 +1,528 @@
#!/bin/bash
#/**
#@file Inventory.lib
#@brief Librería o clase Inventory
#@class Inventory
#@brief Funciones para recogida de datos de inventario de hardware y software de los clientes.
#@version 1.1.0
#@warning License: GNU GPLv3+
#*/
#/**
# ogGetArch
#@brief Devuelve el tipo de arquitectura del cliente.
#@return str_arch - Arquitectura (i386 para 32 bits, x86_64 para 64 bits).
#@version 0.9.2 - Primera versión para OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010-07-17
#*/
function ogGetArch ()
{
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME => x86_64"
return
fi
[ -d /lib64 ] && echo "x86_64" || echo "i386"
}
#/**
# ogGetOsType int_ndisk int_npartition
#@brief Devuelve el tipo del sistema operativo instalado.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return OSType - Tipo de sistema operativo.
#@see ogGetOsVersion
#*/ ##
function ogGetOsType ()
{
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_npartition" \
"$FUNCNAME 1 2 => Linux"
return
fi
ogGetOsVersion "$@" | cut -sf1 -d:
}
#/**
# ogGetOsUuid int_ndisk int_nfilesys
#@brief Devuelve el UUID del sistema operativo instalado en un sistema de archivos.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden de la partición
#@return str_uuid - UUID del sistema operativo.
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o partición no corresponden con un dispositiv
#@version 1.1.0 - Primera versión para OpenGnsys
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2015-09-09
#*/ ##
function ogGetOsUuid ()
{
# Variables locales.
local MNTDIR
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_nfilesys" \
"$FUNCNAME 1 2 => 540e47c6-8e78-4178-aa46-042e4803fb16"
return
fi
# Error si no se reciben 2 parametros.
[ $# = 2 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Montar la particion, si no lo estaba previamente.
MNTDIR=$(ogMount $1 $2) || return $?
# Obtener UUID según el tipo de sistema operativo.
case "$(ogGetOsType $1 $2)" in
Linux)
# Leer el UUID del sistema de ficheros raíz o el fichero de identificador.
findmnt -no UUID $MNTDIR 2>/dev/null || cat $MNTDIR/etc/machine-id 2>/dev/null
;;
Windows)
# Leer identificador en clave de registro.
ogGetRegistryValue $MNTDIR SOFTWARE '\Microsoft\Cryptography\MachineGuid' 2>/dev/null
;;
esac
}
#/**
# ogGetSerialNumber
#@brief Obtiene el nº de serie del cliente.
#@version 1.1.0 - Primeras versión con OpenGnsys
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2015-06-08
#*/ ##
function ogGetSerialNumber ()
{
# Variables locales.
local SERIALNO
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME => 123456"
return
fi
# Obtener nº de serie (ignorar los no especificados).
SERIALNO=$(dmidecode -s system-serial-number | egrep -vi "(^[ 0]+$|not specified|to be filled|invalid entry|default string)")
# Quitar espacios y truncar cadena si >25 caracteres.
SERIALNO="${SERIALNO// /}"
[ ${#SERIALNO} -gt 25 ] && SERIALNO="${SERIALNO:0:22}..."
[ -n "$SERIALNO" ] && echo "$SERIALNO"
return 0
}
#/**
# ogIsEfiActive
#@brief Comprueba si el sistema tiene activo el arranque EFI.
#*/ ##
function ogIsEfiActive ()
{
test -d /sys/firmware/efi
}
#/**
# ogListHardwareInfo
#@brief Lista el inventario de hardware de la máquina cliente.
#@return TipoDispositivo:Modelo (por determinar)
#@warning Se ignoran los parámetros de entrada.
#@note TipoDispositivo = { bio, boa, bus, cha, cdr, cpu, dis, fir, mem, mod, mul, net, sto, usb, vga }
#@note Requisitos: dmidecode, lshw, awk
#@version 0.1 - Primeras pruebas con OpenGnSys
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-07-28
#@version 1.1.0 - Incluir nuevos componentes al inventario.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2014-04-23
#*/ ##
function ogListHardwareInfo ()
{
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME"
return
fi
# Recopilación de dispositivos procesando la salida de \c lshw
ogEcho info "$MSG_HARDWAREINVENTORY}"
echo "cha=$(dmidecode -s chassis-type)" | grep -v "Other"
[ -e /sys/firmware/efi ] && echo "boo=UEFI" || echo "boo=BIOS"
lshw | awk 'BEGIN {type="mod";}
/product:/ {sub(/ *product: */,""); prod=$0;}
/vendor:/ {sub(/ *vendor: */,""); vend=$0;}
/version:/ {sub(/ *version: */,"v.");vers=$0;}
/size:/ {size=$2;}
/clock:/ {clock=$2;}
/slot:/ {sub(/ *slot: */,""); slot=$0;}
/\*-/ {if (type=="mem"){
if (size!=""){
numbank++;
print type"="vend,prod,size,clock" ("slot")";}
}else{
if (type=="totalmem"){
if (size!=""){
totalmemory="mem="size;}
}else{
if (type!="" && prod!=""){
if (prod=="v."vers)
vers="";
print type"="vend,prod,size,vers;} }
}
type=prod=vend=vers=size=clock=slot="";}
$1~/-core/ {type="boa";}
$1~/-firmware/ {type="bio";}
$1~/-cpu/ {type="cpu";}
$1~/-bank/ {type="mem";}
$1~/-memory/ {type="totalmem";}
$1~/-ide/ {type="ide";}
$1~/-storage/ {type="sto";}
$1~/-disk/ {type="dis";}
$1~/-cdrom/ {type="cdr";}
$1~/-display/ {type="vga";}
$1~/-network/ {type="net";}
$1~/-multimedia/ {type="mul";}
$1~/-usb/ {type="usb";}
$1~/-firewire/ {type="fir";}
$1~/-serial/ {type="bus";}
END {if (type!="" && prod!="")
print type"="vend,prod,size,vers;
if (length(numbank)==0 && length(totalmemory)>=4)
print totalmemory; }
'
# */ (comentario para Doxygen)
}
#/**
# ogListSoftware int_ndisk int_npartition
#@brief Lista el inventario de software instalado en un sistema operativo.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return programa versión ...
#@warning Se ignoran los parámetros de entrada.
#@note Requisitos: ...
#@todo Detectar software en Linux
#@version 0.1 - Primeras pruebas con OpenGnSys
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-09-23
#@version 1.0.5 - Aproximación para inventario de software de Mac OS.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2013-10-08
#@version 1.0.6 - Proceso depende del tipo de SO y soporte para FreeBSD.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2014-11-13
#@version 1.1.0 - Se muestra el sistema operativo en la primera línea de la salida
#@author Irina Gomez, ETSII Universidad de Sevilla
#@date 2016-04-26
#*/ ##
function ogListSoftware ()
{
# Variables locales.
local APPS HIVE k KEYS KEYS32 MNTDIR PKGDIR PROG VERS TMPFILE TYPE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME 1 1"
return
fi
# Error si no se reciben 2 parametros.
[ $# = 2 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Obtener tipo de sistema de archivos y montarlo.
MNTDIR=$(ogMount $1 $2) || return $?
TYPE=$(ogGetOsType $1 $2) || return $?
# Ficheros temporales.
APPS=$(mktemp /tmp/apps.XXXXX)
TMPFILE=$(mktemp /tmp/tmp.XXXXX)
trap "rm -f $APPS $TMPFILE" 1 2 3 9 15
case "$TYPE" in
Linux) # Software de GNU/Linux.
# Procesar paquetes dpkg.
PKGDIR="${MNTDIR}/var/lib/dpkg"
if [ -r $PKGDIR ]; then
# Proceso de fichero en sistemas de 64 bits.
awk '/Package:/ {if (pack!="") print pack,vers;
sub(/-dev$/,"",$2);
pack=$2}
/Version:/ {sub(/^.*:/,"",$2); sub(/-.*$/,"",$2);
vers=$2}
/Status:/ {if ($2!="install") pack=vers=""}
END {if (pack!="") print pack,vers}
' $PKGDIR/status > $APPS
fi
# Procesar paquetes RPM.
PKGDIR="${MNTDIR}/var/lib/rpm"
if [ -r $PKGDIR ]; then
# Listar si está instalado el paquete "rpm" en el cliente.
if which rpm &>/dev/null; then
rm -f ${PKGDIR}/__db.*
rpm --dbpath $PKGDIR -qa --qf "%{NAME} %{VERSION}\n" 2>/dev/null | \
awk '$1!~/-devel$/ {sub(/-.*$/,"",$2); print $0}' > $APPS
rm -f ${PKGDIR}/__db.*
else
# Obtener el nombre de cada paquete en la BD de RPM.
python <<<"
import re;
import bsddb;
db=bsddb.hashopen('$PKGDIR/Name','r');
for k in db.keys():
print re.sub('-devel$','',k);" > $APPS
fi
fi
# Procesar paquetes pacman.
PKGDIR="${MNTDIR}/var/lib/pacman/local"
if [ -r $PKGDIR ]; then
ls $PKGDIR | awk -F- '/-/ {print gensub(/-/, " ", NF-2);}' > $APPS
fi
# Procesar aplicaciones Snappy.
PKGDIR="${MNTDIR}/snap"
find $PKGDIR/*/current/meta -name snap.yaml -exec \
awk '/name:/ {pack=$2}
/version:/ {vers=$2}
END {if (pack!="") print pack,"(snap)",vers}' {} 2>/dev/null \; >> $APPS
# Procesar aplicaciones Flatpak.
PKGDIR="${MNTDIR}/var/lib/flatpak"
ls -1 $PKGDIR/app/*/current/active/deploy 2> /dev/null | python -c "
import sys
for f in sys.stdin:
p = open(f.strip()).read().split('\0')
try:
if(p[0] != 'flathub'):
raise ValueError
print('{} (flatpak) {}'.format(p[p.index('appdata-name') + 4], p[p.index('appdata-version') + 1]))
except ValueError:
pass
" >> $APPS
;;
Windows) # Software de Windows.
# Comprobar tipo de proceso del registro de Windows.
if which hivexregedit &>/dev/null; then
# Nuevo proceso más rápido basado en "hivexregedit".
HIVE=$(ogGetHivePath $MNTDIR software 2>/dev/null)
if [ -n "$HIVE" ]; then
# Claves de registro para programas instalados.
hivexregedit --unsafe-printable-strings --export "$HIVE" '\Microsoft\Windows\CurrentVersion\Uninstall' > $TMPFILE 2>/dev/null
hivexregedit --unsafe-printable-strings --export "$HIVE" '\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall' >> $TMPFILE 2>/dev/null
# Mostrar los valores "DisplayName" y "DisplayVersion" para cada clave.
awk -F\" '$1~/^\[/ {n=""}
$2~/DisplayName/ {n=$4}
$2~/DisplayVersion/ {print n,$4}
' $TMPFILE > $APPS
fi
else
# Compatibilidad con clientes ogLive antiguos.
# Claves de registro para programas instalados: formato "{clave}".
KEYS=$(ogListRegistryKeys $MNTDIR software '\Microsoft\Windows\CurrentVersion\Uninstall')
KEYS32=$(ogListRegistryKeys $MNTDIR software '\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall')
# Mostrar los valores "DisplayName" y "DisplayVersion" para cada clave.
for k in $KEYS; do
PROG=$(ogGetRegistryValue $MNTDIR software "\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\$k\\DisplayName")
if [ -n "$PROG" ]; then
VERS=$(ogGetRegistryValue $MNTDIR software "\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\$k\\DisplayVersion")
echo "$PROG $VERS"
fi
done > $APPS
for k in $KEYS32; do
PROG=$(ogGetRegistryValue $MNTDIR software "\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\$k\\DisplayName")
if [ -n "$PROG" ]; then
VERS=$(ogGetRegistryValue $MNTDIR software "\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\$k\\DisplayVersion")
echo "$PROG $VERS"
fi
done >> $APPS
fi
;;
MacOS) # Software de Mac OS.
# Listar directorios de aplicaciones e intentar obtener la versión del fichero .plist (tanto original como descomprimido).
find "${MNTDIR}/Applications" -type d -name "*.app" -prune -print | \
while read k; do
FILE="$k/Contents/version.plist"
[ -s "$FILE" ] || FILE="$k/Contents/version.plist.uncompress"
[ -s "$FILE" ] && VERSION=$(awk -F"[<>]" '/ShortVersionString/ {getline;v=$3}
END {print v}' "$FILE")
echo "$(basename "$k" .app) $VERSION"
done > $APPS
;;
BSD) # Software de FreeBSD.
sqlite3 $MNTDIR/var/db/pkg/local.sqlite <<<"SELECT name FROM pkg_search;" 2>/dev/null | \
sed 's/\(.*\)-\(.*\)/\1 \2/g' > $APPS
;;
*) ogRaiseError $OG_ERR_NOTOS "$1, $2 ${TYPE+($TYPE)}"
return $? ;;
esac
# Mostrar sistema Operativo y aplicaciones.
ogGetOsVersion $1 $2 | awk -F: '{print $2}'
sort $APPS | uniq | iconv -ct utf-8
rm -f $APPS $TMPFILE
}
#/**
# ogGetOsVersion int_ndisk int_nfilesys
#@brief Devuelve la versión del sistema operativo instalado en un sistema de archivos.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden de la partición
#@return OSType:OSVersion - tipo y versión del sistema operativo.
#@note OSType = { Android, BSD, GrubLoader, Hurd, Linux, MacOS, Solaris, Windows, WinLoader }
#@note Requisitos: awk, head, chroot
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o partición no corresponden con un dispositiv
#@exception OG_ERR_PARTITION Fallo al montar el sistema de archivos.
#@version 0.9 - Primera versión para OpenGnSys
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-09-15
#@version 1.0.4 - Incluir tipos BSD, MacOS y Solaris.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2012-06-29
#@version 1.0.5 - Incluir tipos GrubLoader, Hurd y WinLoader, leer por defecto fichero /etc/os-release.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2013-10-07
#@version 1.0.6 - Detectar GrubLoader al final y sistemas basados en EFI.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2014-08-27
#*/ ##
function ogGetOsVersion ()
{
# Variables locales.
local MNTDIR TYPE DISTRIB VERSION IS64BIT FILE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_nfilesys" \
"$FUNCNAME 1 2 => Linux:Ubuntu precise (12.04 LTS) 64 bits"
return
fi
# Error si no se reciben 2 parametros.
[ $# = 2 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Montar la particion, si no lo estaba previamente.
MNTDIR=$(ogMount $1 $2) || return $?
# Buscar tipo de sistema operativo.
# Para GNU/Linux: leer descripción.
TYPE="Linux"
FILE="$MNTDIR/etc/os-release"
[ -r $FILE ] && VERSION="$(awk -F= '$1~/PRETTY_NAME/ {gsub(/\"/,"",$2); print $2}' $FILE)"
# Si no se puede obtener, buscar en ficheros del sistema.
if [ -z "$VERSION" ]; then
FILE="$MNTDIR/etc/lsb-release"
[ -r $FILE ] && VERSION="$(awk -F= '$1~/DESCRIPTION/ {gsub(/\"/,"",$2); print $2}' $FILE)"
for DISTRIB in redhat SuSE mandrake gentoo; do
FILE="$MNTDIR/etc/${DISTRIB}-release"
[ -r $FILE ] && VERSION="$(head -1 $FILE)"
done
FILE="$MNTDIR/etc/arch-release"
[ -r $FILE ] && VERSION="Arch Linux"
FILE="$MNTDIR/etc/slackware-version"
[ -r $FILE ] && VERSION="Slackware $(cat $FILE)"
fi
# Si no se encuentra, intentar ejecutar "lsb_release".
[ -z "$VERSION" ] && VERSION=$(chroot $MNTDIR lsb_release -d 2>/dev/null | awk -F":\t" '{print $2}')
# Comprobar Linux de 64 bits.
[ -n "$VERSION" ] && [ -e $MNTDIR/lib64 ] && IS64BIT="$MSG_64BIT"
# Para Android, leer fichero de propiedades.
if [ -z "$VERSION" ]; then
TYPE="Android"
FILE="$MNTDIR/android*/system/build.prop"
[ -r $FILE ] && VERSION="Android $(awk -F= '$1~/(product.brand|build.version.release)/ {print $2}' $FILE | tr '\n' ' ')"
[ -e $MNTDIR/lib64 ] && IS64BIT="$MSG_64BIT"
fi
# Para GNU/Hurd, comprobar fichero de inicio (basado en os-prober).
if [ -z "$VERSION" ]; then
TYPE="Hurd"
FILE="$MNTDIR/hurd/init"
[ -r $FILE ] && VERSION="GNU/Hurd"
fi
# Para Windows: leer la version del registro.
if [ -z "$VERSION" ]; then
TYPE="Windows"
FILE="$(ogGetHivePath $MNTDIR SOFTWARE)"
if [ -n "$FILE" ]; then
# Nuevo método más rápido para acceder al registro de Windows..
VERSION=$(echo $(hivexsh << EOT 2>/dev/null
load $FILE
cd \Microsoft\Windows NT\CurrentVersion
lsval ProductName
lsval ReleaseId
EOT
))
[ -n "$(reglookup -H -p "Microsoft/Windows/CurrentVersion/ProgramW6432Dir" "$FILE" 2>/dev/null)" ] && IS64BIT="$MSG_64BIT"
if [ -z "$VERSION" ]; then
# Compatibilidad con métrodo antiguo y más lento de acceder al registro.
VERSION=$(ogGetRegistryValue $MNTDIR software '\Microsoft\Windows NT\CurrentVersion\ProductName' 2>/dev/null)
[ -n "$(ogGetRegistryValue $MNTDIR software '\Microsoft\Windows\CurrentVersion\ProgramW6432Dir' 2>/dev/null)" ] && IS64BIT="$MSG_64BIT"
fi
fi
fi
# Para cargador Windows: buscar versión en fichero BCD (basado en os-prober).
if [ -z "$VERSION" ]; then
TYPE="WinLoader"
FILE="$(ogGetPath $MNTDIR/boot/bcd)"
[ -z "$FILE" ] && FILE="$(ogGetPath $MNTDIR/EFI/Microsoft/boot/bcd)"
if [ -n "$FILE" ]; then
for DISTRIB in "Windows Recovery" "Windows Boot"; do
if grep -aqs "$(echo "$DISTRIB" | sed 's/./&./g')" $FILE; then
VERSION="$DISTRIB loader"
fi
done
fi
fi
# Para macOS: detectar kernel y completar con fichero plist de información del sistema.
if [ -z "$VERSION" ]; then
TYPE="MacOS"
# Kernel de Mac OS (no debe ser fichero de texto).
FILE="$MNTDIR/mach_kernel"
if [ -z "$(file -b $FILE | grep 'text')" ]; then
# Obtener tipo de kernel.
[ -n "$(file -b $FILE | grep 'Mach-O')" ] && VERSION="macOS"
[ -n "$(file -b $FILE | grep 'Mach-O 64-bit')" ] && IS64BIT="$MSG_64BIT"
# Datos de configuración de versión de Mac OS.
FILE="$MNTDIR/System/Library/CoreServices/SystemVersion.plist"
[ -r $FILE ] && VERSION=$(awk -F"[<>]" '
/ProductName/ {getline;s=$3}
/ProductVersion/ {getline;v=$3}
END {print s,v}' $FILE)
# Datos de recuperación de macOS.
FILE="$MNTDIR/com.apple.recovery.boot"
[ -r $FILE -a -n "$VERSION" ] && VERSION="$VERSION recovery"
fi
fi
# Para FreeBSD: obtener datos del Kernel.
### TODO Revisar solución.
if [ -z "$VERSION" ]; then
TYPE="BSD"
FILE="$MNTDIR/boot/kernel/kernel"
if [ -r $FILE ]; then
VERSION="$(strings $FILE|awk '/@.*RELEASE/ {sub(/@\(#\)/,""); print $1,$2}')"
[ -n "$(file -b $FILE | grep 'x86-64')" ] && IS64BIT="$MSG_64BIT"
fi
fi
# Para Solaris: leer el fichero de versión.
### TODO Revisar solución.
if [ -z "$VERSION" ]; then
TYPE="Solaris"
FILE="$MNTDIR/etc/release"
[ -r $FILE ] && VERSION="$(head -1 $FILE)"
fi
# Para cargador GRUB, comprobar fichero de configuración.
if [ -z "$VERSION" ]; then
TYPE="GrubLoader"
for FILE in $MNTDIR/{,boot/}grub/menu.lst; do
[ -r $FILE ] && VERSION="GRUB Loader"
done
#/* (comentario Doxygen)
for FILE in $MNTDIR/{,boot/}{grub{,2},EFI/*}/grub.cfg; do
[ -r $FILE ] && VERSION="GRUB2 Loader"
done
fi
#*/ (Comentario Doxygen)
# Mostrar resultado y salir sin errores.
[ -n "$VERSION" ] && echo "$TYPE:$VERSION $IS64BIT"
return 0
}

View File

@ -1,531 +0,0 @@
#/**
#@file InventoryLib.py
#@brief Librería o clase Inventory
#@class Inventory
#@brief Funciones para recogida de datos de inventario de hardware y software de los clientes.
#@warning License: GNU GPLv3+
#*/
import platform
import sys
import os
import subprocess
import re
import json
import shutil
import glob
import plistlib
#import bsddb
import ogGlobals
import SystemLib
import FileSystemLib
import RegistryLib
import FileLib
#/**
# ogGetArch
#@brief Devuelve el tipo de arquitectura del cliente.
#@return str_arch - Arquitectura (i386 para 32 bits, x86_64 para 64 bits).
#*/
def ogGetArch():
if os.path.isdir ('/lib64'):
return 'x86_64'
else:
return 'i386'
#/**
# ogGetOsType int_ndisk int_npartition
#@brief Devuelve el tipo del sistema operativo instalado.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return OSType - Tipo de sistema operativo.
#@see ogGetOsVersion
#*/ ##
def ogGetOsType(disk, partition):
try:
os_version = ogGetOsVersion(disk, partition)
if os_version:
return os_version.split(":", 1)[0]
else:
return None
except Exception as e:
print(f"Error en ogGetOsType: {e}")
return "Unknown"
#/**
# ogGetOsUuid int_ndisk int_nfilesys
#@brief Devuelve el UUID del sistema operativo instalado en un sistema de archivos.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden de la partición
#@return str_uuid - UUID del sistema operativo.
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o partición no corresponden con un dispositiv
#*/ ##
def ogGetOsUuid (disk, par):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir: return None
# Obtener UUID según el tipo de sistema operativo.
os_type = ogGetOsType (disk, par)
if 'Linux' == os_type:
# Leer el UUID del sistema de ficheros raíz o el fichero de identificador.
uuid = subprocess.run (['findmnt', '-no', 'UUID', mntdir], capture_output=True, text=True).stdout.strip()
if not uuid:
uuid = open (os.path.join (mntdir, 'etc', 'machine-id')).read().strip()
return uuid
elif 'Windows' == os_type:
# Leer identificador en clave de registro.
uuid = RegistryLib.ogGetRegistryValue (mntdir, 'SOFTWARE', r'\Microsoft\Cryptography\MachineGuid')
return uuid
#/**
# ogGetSerialNumber
#@brief Obtiene el nº de serie del cliente.
#*/ ##
def ogGetSerialNumber():
SERIALNO = subprocess.check_output(["dmidecode", "-s", "system-serial-number"]).decode().strip()
SERIALNO = re.sub(r"(not specified|to be filled|invalid entry|default string)", "", SERIALNO, flags=re.IGNORECASE)
SERIALNO = SERIALNO.replace(" ", "")
SERIALNO = SERIALNO[:25] if len(SERIALNO) > 25 else SERIALNO
if SERIALNO: return SERIALNO
return None
#/**
# ogIsEfiActive
#@brief Comprueba si el sistema tiene activo el arranque EFI.
#*/ ##
def ogIsEfiActive():
return os.path.isdir("/sys/firmware/efi")
#/**
# ogListHardwareInfo
#@brief Lista el inventario de hardware de la máquina cliente.
#@return TipoDispositivo:Modelo (por determinar)
#@warning Se ignoran los parámetros de entrada.
#@note TipoDispositivo = { bio, boa, bus, cha, cdr, cpu, dis, fir, mem, mod, mul, net, sto, usb, vga }
#@note Requisitos: dmidecode, lshw, awk
#*/ ##
def ogListHardwareInfo():
ret = ''
SystemLib.ogEcho ([], 'info', ogGlobals.lang.MSG_HARDWAREINVENTORY)
# Ejecutar dmidecode y obtener tipo de chasis
dmi_out = subprocess.run (['dmidecode', '-s', 'chassis-type'], capture_output=True, text=True).stdout
dmi_out = '\n'.join ([ x for x in dmi_out.splitlines() if 'Other' not in x ])
ret += f'cha={dmi_out}\n'
if os.path.exists ('/sys/firmware/efi'):
ret += f'boo=UEFI\n'
else:
ret += f'boo=BIOS\n'
awk_script = r'''
BEGIN {type="mod";}
/product:/ {sub(/ *product: */,""); prod=$0;}
/vendor:/ {sub(/ *vendor: */,""); vend=$0;}
/version:/ {sub(/ *version: */,"v.");vers=$0;}
/size:/ {size=$2;}
/clock:/ {clock=$2;}
/slot:/ {sub(/ *slot: */,""); slot=$0;}
/\*-/ {if (type=="mem"){
if (size!=""){
numbank++;
print type"="vend,prod,size,clock" ("slot")";}
}else{
if (type=="totalmem"){
if (size!=""){
totalmemory="mem="size;}
}else{
if (type!="" && prod!=""){
if (prod=="v."vers)
vers="";
print type"="vend,prod,size,vers;} }
}
type=prod=vend=vers=size=clock=slot="";}
$1~/-core/ {type="boa";}
$1~/-firmware/ {type="bio";}
$1~/-cpu/ {type="cpu";}
$1~/-bank/ {type="mem";}
$1~/-memory/ {type="totalmem";}
$1~/-ide/ {type="ide";}
$1~/-storage/ {type="sto";}
$1~/-disk/ {type="dis";}
$1~/-cdrom/ {type="cdr";}
$1~/-display/ {type="vga";}
$1~/-network/ {type="net";}
$1~/-multimedia/ {type="mul";}
$1~/-usb/ {type="usb";}
$1~/-firewire/ {type="fir";}
$1~/-serial/ {type="bus";}
END {if (type!="" && prod!="")
print type"="vend,prod,size,vers;
if (length(numbank)==0 && length(totalmemory)>=4)
print totalmemory; }
'''
lshw_out = subprocess.run (['lshw'], capture_output=True, text=True).stdout
awk_out = subprocess.run (['awk', awk_script], input=lshw_out, capture_output=True, text=True).stdout
ret += awk_out
return ret
#/**
# ogListSoftware int_ndisk int_npartition
#@brief Lista el inventario de software instalado en un sistema operativo.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@return programa versión ...
#@warning Se ignoran los parámetros de entrada.
#@note Requisitos: ...
#@todo Detectar software en Linux
#*/ ##
def ogListSoftware (disk, par):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir: return None
ostype = ogGetOsType (disk, par)
if not ostype: return None
apps = []
if 'Linux' == ostype:
# Procesar paquetes dpkg.
pkgdir = f'{mntdir}/var/lib/dpkg'
if os.path.exists (pkgdir):
status_file = os.path.join(pkgdir, "status")
awk_script = '''
/Package:/ {if (pack!="") print pack,vers;
sub(/-dev$/,"",$2);
pack=$2}
/Version:/ {sub(/^.*:/,"",$2); sub(/-.*$/,"",$2);
vers=$2}
/Status:/ {if ($2!="install") pack=vers=""}
END {if (pack!="") print pack,vers}
'''
awk_out = subprocess.run (['awk', awk_script, status_file], capture_output=True, text=True).stdout
apps = awk_out.splitlines()
# Procesar paquetes RPM.
pkgdir = f'{mntdir}/var/lib/rpm'
if os.path.exists (pkgdir):
if shutil.which ('rpm'):
for f in glob.glob (f'{pkgdir}/__db.*'):
os.unlink (f)
rpm_out = subprocess.run (['rpm', '--dbpath', pkgdir, '-qa', '--qf', '%{NAME} %{VERSION}\n'], capture_output=True, text=True).stdout
for l in rpm_out.splitlines():
words = l.split()
if (not re.search ('-devel$', words[0])):
words[1] = re.sub ('-.*', '', words[1])
apps.append (' '.join (words))
for f in glob.glob (f'{pkgdir}/__db.*'):
os.unlink (f)
else:
pass
#db = bsddb.hashopen (f'{pkgdir}/Name', 'r');
#for k in db.keys():
# apps.append (re.sub ('-devel$', '', k))
# Procesar paquetes pacman.
pkgdir = f'{mntdir}/var/lib/pacman/local'
if os.path.exists (pkgdir):
for f in glob.glob (f'{pkgdir}/*'):
if '-' not in f: continue
idx = f[0:f.rfind ('-')].rfind ('-') ## index of 2nd-to-last dash
apps.append (f[0:idx] + ' ' + f[idx+1:])
# Procesar aplicaciones Snappy.
pkgdir = f'{mntdir}/snap'
out = ''
awk_script = '''
/name:/ {pack=$2}
/version:/ {vers=$2}
END {if (pack!="") print pack,"(snap)",vers}
'''
files = subprocess.run (['find', f'{pkgdir}/*/current/meta', '-name', 'snap.yaml'], capture_output=True, text=True).stdout.splitlines()
for f in files:
awk_out = subprocess.run (['awk', awk_script, f], capture_output=True, text=True).stdout
out += awk_out
apps += out.splitlines()
# Procesar aplicaciones Flatpak.
pkgdir = f'{mntdir}/var/lib/flatpak'
files = glob.glob (f'{pkgdir}/app/*/current/active/deploy/*')
for f in files:
p = open (f.strip()).read().split ('\0')
try:
if (p[0] != 'flathub'): raise ValueError
apps.append ('{} (flatpak) {}'.format (p[p.index('appdata-name') + 4], p[p.index('appdata-version') + 1]))
except ValueError:
pass
elif 'Windows' == ostype:
if shutil.which ('hivexregedit'):
hive = RegistryLib.ogGetHivePath (mntdir, 'software')
if hive:
cmd1_out = subprocess.run (['hivexregedit', '--unsafe-printable-strings', '--export', hive, r'\Microsoft\Windows\CurrentVersion\Uninstall'], capture_output=True, text=True).stdout
cmd1_out += subprocess.run (['hivexregedit', '--unsafe-printable-strings', '--export', hive, r'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'], capture_output=True, text=True).stdout
out = name = ''
for l in cmd1_out.splitlines():
words = l.split ('"')
if len(words) < 4: continue
if (re.match (r'\[', words[0])): name=''
if (re.search ('DisplayName', words[1])): name=words[3]
if (re.search ('DisplayVersion', words[1])): apps.append (f'{name} {words[3]}')
else:
keys = RegistryLib.ogListRegistryKeys (mntdir, 'software', r'\Microsoft\Windows\CurrentVersion\Uninstall')
keys32 = RegistryLib.ogListRegistryKeys (mntdir, 'software', r'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall')
for k in keys:
prog = RegistryLib.ogGetRegistryValue (mntdir, 'software', rf'\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayName')
if prog:
vers = RegistryLib.ogGetRegistryValue (mntdir, 'software', rf'\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayVersion')
apps.append (f'{prog} {vers}')
for k in keys32:
prog = RegistryLib.gGetRegistryValue (mntdir, 'software', rf'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayName')
if prog:
vers = RegistryLib.ogGetRegistryValue (mntdir, 'software', rf'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayVersion')
apps.append (f'{prog} {vers}')
elif 'MacOS' == ostype:
files = subprocess.run (['find', f'{mntdir}/Applications', '-type', 'd', '-name', '*.app', '-prune', '-print'], capture_output=True, text=True).stdout.splitlines()
for k in files:
FILE = f'{k}/Contents/version.plist'
if not os.stat (FILE).st_size:
FILE = f'{k}/Contents/version.plist.uncompress'
if os.stat (FILE).st_size:
VERSION = subprocess.run (['awk', '-F[<>]', '/ShortVersionString/ {getline;v=$3} END {print v}', FILE], capture_output=True, text=True).stdout.strip()
bn = os.path.basename (k)
bn = re.sub ('.app$', '', bn)
apps.append (f'{bn} {VERSION}')
elif 'BSD' == ostype:
sqlite_out = subprocess.run (['sqlite3', f'{mntdir}/var/db/pkg/local.sqlite'], input='SELECT name FROM pkg_search;\n', capture_output=True, text=True).stdout
for l in sqlite_out.splitlines():
apps.append (' '.join (re.search ('(.*)-(.*)', l).groups()))
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk}, {par} ({ostype})')
return None
os_version = ogGetOsVersion (disk, par).split (':')[1]
return [os_version] + sorted (set (apps))
## https://stackoverflow.com/questions/2522651/find-a-key-inside-a-deeply-nested-dictionary/2522706#2522706
def _find_key_recursive(plist_dict, key_substr):
for k in plist_dict.keys():
if key_substr in k: return plist_dict[k]
for k, v in plist_dict.items():
if type(v) is dict: # Only recurse if we hit a dict value
value = _find_key_recursive(v, key_substr)
if value:
return value
return ''
#/**
# ogGetOsVersion int_ndisk int_nfilesys
#@brief Devuelve la versión del sistema operativo instalado en un sistema de archivos.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden de la partición
#@return OSType:OSVersion - tipo y versión del sistema operativo.
#@note OSType = { Android, BSD, GrubLoader, Hurd, Linux, MacOS, Solaris, Windows, WinLoader }
#@note Requisitos: awk, head, chroot
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o partición no corresponden con un dispositiv
#@exception OG_ERR_PARTITION Fallo al montar el sistema de archivos.
#*/ ##
#ogGetOsVersion ("1", "2") => "Linux:Ubuntu precise (12.04 LTS) 64 bits"
def ogGetOsVersion(disk, part):
mntdir = FileSystemLib.ogMount (disk, part)
if not mntdir:
return None
type = version = None
is64bit = ''
# Buscar tipo de sistema operativo.
# Para GNU/Linux: leer descripción.
os_release = os.path.join(mntdir, "etc/os-release")
if os.path.isfile(os_release):
type = 'Linux'
with open(os_release, "r") as f:
for line in f:
if line.startswith("PRETTY_NAME"):
version = line.split("=", 1)[1].strip().strip('"')
break
if not version:
lsb_release = os.path.join(mntdir, "etc/lsb-release")
if os.path.isfile(lsb_release):
type = 'Linux'
with open(lsb_release, "r") as f:
for line in f:
if line.startswith("DISTRIB_DESCRIPTION"):
version = line.split("=", 1)[1].strip().strip('"')
break
if not version:
for distrib in ["redhat", "SuSE", "mandrake", "gentoo"]:
distrib_file = os.path.join(mntdir, f"etc/{distrib}-release")
if os.path.isfile(distrib_file):
type = 'Linux'
with open(distrib_file, "r") as f:
version = f.readline().strip()
break
if not version:
arch_release_file = os.path.join(mntdir, "etc/arch-release")
if os.path.isfile(arch_release_file):
type = 'Linux'
version = "Arch Linux"
if not version:
slack_release_file = os.path.join(mntdir, "slackware-version")
if os.path.isfile(slack_release_file):
type = 'Linux'
with open (slack_release_file, 'r') as fd:
c = fd.read()
version = "Slackware {c}"
# Si no se encuentra, intentar ejecutar "lsb_release".
if not version:
out = subprocess.run (['chroot', mntdir, 'lsb_release', '-d'], capture_output=True, text=True).stdout
m = re.search (':\t(.*)', out)
if m:
type = 'Linux'
version = m.group(1)
# Comprobar Linux de 64 bits.
if version and os.path.exists(os.path.join(mntdir, "lib64")):
is64bit = ogGlobals.lang.MSG_64BIT
# Para Android, leer fichero de propiedades.
if not version:
type = 'Android'
files = glob.glob (os.path.join (mntdir, 'android*/system/build.prop'))
if files and os.path.isfile (files[0]):
v = []
with open (files[0], 'r') as f:
for line in f:
if 'product.brand' in line or 'build.version.release' in line:
v.append (line.split('=')[1].strip())
version = ' '.join (v)
if os.path.exists(os.path.join(mntdir, "lib64")):
is64bit = ogGlobals.lang.MSG_64BIT
# Para GNU/Hurd, comprobar fichero de inicio (basado en os-prober).
if not version:
type = 'Hurd'
if os.path.exists(os.path.join(mntdir, "hurd/init")):
version = 'GNU/Hurd'
# Para Windows: leer la version del registro.
if not version:
type = 'Windows'
build = 0
file = RegistryLib.ogGetHivePath (mntdir, 'SOFTWARE')
if file:
# Nuevo método más rápido para acceder al registro de Windows..
i = '\n'.join ([
f'load {file}',
r'cd \Microsoft\Windows NT\CurrentVersion',
'lsval ProductName',
'lsval DisplayVersion',
])
version = subprocess.run (['hivexsh'], input=i, capture_output=True, text=True).stdout
version = version.replace ('\n', ' ')
# Recoge el valor del número de compilación para ver si es Windows 10/11
i = '\n'.join ([
f'load {file}',
r'cd \Microsoft\Windows NT\CurrentVersion',
'lsval CurrentBuildNumber',
])
build = subprocess.run (['hivexsh'], input=i, capture_output=True, text=True).stdout
if subprocess.run (['reglookup', '-H', '-p', 'Microsoft/Windows/CurrentVersion/ProgramW6432Dir', file], capture_output=True, text=True).stdout:
is64bit = ogGlobals.lang.MSG_64BIT
if not version:
# Compatibilidad con métrodo antiguo y más lento de acceder al registro.
version = RegistryLib.ogGetRegistryValue (mntdir, 'software', r'\Microsoft\Windows NT\CurrentVersion\ProductName')
if RegistryLib.ogGetRegistryValue (mntdir, 'software', r'\Microsoft\Windows\CurrentVersion\ProgramW6432Dir'):
is64bit = ogGlobals.lang.MSG_64BIT
# Si la compilación es mayor o igual a 22000 es Windows 11
if int (build) >= 22000:
version = version.replace ('10', '11')
# Para cargador Windows: buscar versión en fichero BCD (basado en os-prober).
if not version:
type = 'WinLoader'
file = FileLib.ogGetPath (file=f'{mntdir}/boot/bcd')
if not file:
file = FileLib.ogGetPath (file=f'{mntdir}/EFI/Microsoft/boot/bcd')
if file:
for distrib in 'Windows Recovery', 'Windows Boot':
with open (file, 'rb') as fd:
contents = fd.read()
distrib_utf16_regex = re.sub (r'(.)', '\\1.', distrib)
distrib_utf16_regex = bytes (distrib_utf16_regex, 'ascii')
if re.search (distrib_utf16_regex, contents):
version = f'{distrib} loader'
# Para macOS: detectar kernel y completar con fichero plist de información del sistema.
if not version:
type = 'MacOS'
# Kernel de Mac OS (no debe ser fichero de texto).
file = f'{mntdir}/mach_kernel'
out = subprocess.run (['file', '--brief', file], capture_output=True, text=True).stdout
if not 'text' in out:
# Obtener tipo de kernel.
if 'Mach-O' in out: version = 'macOS'
if 'Mach-O 64-bit' in out: is64bit = ogGlobals.lang.MSG_64BIT
# Datos de configuración de versión de Mac OS.
file = f'{mntdir}/System/Library/CoreServices/SystemVersion.plist'
if os.path.exists (file):
with open (file, 'rb') as fd:
contents = fd.read()
plist_dict = plistlib.loads (contents)
n = _find_key_recursive (plist_dict, 'ProductName')
v = _find_key_recursive (plist_dict, 'ProductVersion')
version = f'{n} {v}'.strip()
# Datos de recuperación de macOS.
if version and os.path.exists (f'{mntdir}/com.apple.recovery.boot'):
version += ' recovery'
# Para FreeBSD: obtener datos del Kernel.
### TODO Revisar solución.
if not version:
type = 'BSD'
file = f'{mntdir}/boot/kernel/kernel'
if os.path.exists (file):
lines = subprocess.run (['strings', file], capture_output=True, text=True).stdout.splitlines()
release_search = list (filter (lambda x: re.search ('@.*RELEASE', x), lines))
if release_search:
first, second, *rest = release_search[0].split()
first = first.replace ('@(#)', '')
version = f'{first} {second}'
out = subprocess.run (['file', '--brief', file], capture_output=True, text=True).stdout
if 'x86-64' in out: is64bit = ogGlobals.lang.MSG_64BIT
# Para Solaris: leer el fichero de versión.
### TODO Revisar solución.
if not version:
type = 'Solaris'
file = f'{mntdir}/etc/release'
if os.path.exists (file):
with open (file, 'r') as fd:
version = fd.readline().strip
# Para cargador GRUB, comprobar fichero de configuración.
if not version:
type = 'GrubLoader'
for file in f'{mntdir}/grub/menu.lst', f'{mntdir}/boot/grub/menu.lst':
if os.path.exists (file):
VERSION = 'GRUB Loader'
for entry in f'{mntdir}/grub/grub.cfg', f'{mntdir}/grub2/grub.cfg', f'{mntdir}/EFI/*/grub.cfg', f'{mntdir}/boot/grub/grub.cfg', f'{mntdir}/boot/grub2/grub.cfg', f'{mntdir}/boot/EFI/*/grub.cfg':
for file in glob.glob (entry):
if os.path.exists (file):
version = 'GRUB2 Loader'
# Mostrar resultado y salir sin errores.
if version: return f"{type}:{version} {is64bit}"
return None

View File

@ -0,0 +1,345 @@
#!/bin/bash
#/**
#@file Net.lib
#@brief Librería o clase Net
#@class Net
#@brief Funciones básicas de red.
#@version 1.0.6
#@warning License: GNU GPLv3+
#*/
#/**
# ogChangeRepo IPREPO [ OgUnit ]
#@brief Cambia el repositorio para el recurso remoto images.
#@param 1 Ip Repositorio
#@param 2 Abreviatura Unidad Organizativa
#@return Cambio recurso remoto en OGIMG.
#@version 1.1 - Primera versión para OpenGnSys.
#@author Irina Gomez, ETSII Universidad de Sevilla
#@date 2015-06-16
#*/
function ogChangeRepo ()
{
local SRCIMG NEWREPO REPO OGUNIT
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME IPREPO [ OgUnit ]" \
"$FUNCNAME 10.1.120.3" \
"$FUNCNAME 10.1.120.3 cdc"
return
fi
if [ $# -lt 1 ]; then
ogRaiseError $OG_ERR_FORMAT "$MSG_FORMAT: $FUNCNAME IPREPO [ OgUnit ]"
return $?
fi
# Opciones de montaje: lectura o escritura
mount |grep "ogimages.*rw," &>/dev/null && RW=",rw" || RW=",ro"
# Si REPO tomamos el repositorio y la unidad organizativa actual
REPO=$(ogGetRepoIp)
OGUNIT="$(df | awk -F " " '/ogimages/ {sub("//.*/ogimages","",$1); sub("/","",$1); print $1}')"
# Parametros de entrada. Si $1 = "REPO" dejo el repositorio actual
[ "${1^^}" == "REPO" ] && NEWREPO="$REPO" || NEWREPO="${1}"
# Si $1 y $2 son el repositorio y la OU actual me salgo
[ "$NEWREPO" == "$REPO" ] && [ "$2" == "$OGUNIT" ] && return 0
source /scripts/functions
source /scripts/ogfunctions
umount $OGIMG
[ "$2" == "" ] && SRCIMG="ogimages" || SRCIMG="ogimages/$2"
eval $(grep "OPTIONS=" /scripts/ogfunctions)
ogEcho session log "$MSG_HELP_ogChangeRepo $NEWREPO ${2%/}"
ogConnect $NEWREPO $ogprotocol $SRCIMG $OGIMG $RW
# Si da error volvemos a montar el inicial
if [ $? -ne 0 ]; then
ogConnect $REPO $ogprotocol $SRCIMG $OGIMG $RW
ogRaiseError session $OG_ERR_REPO "$NEWREPO"
return $?
fi
}
#/**
# ogGetGroupDir [ str_repo ]
#@brief Devuelve el camino del directorio para el grupo del cliente.
#@param str_repo repositorio de imágenes (opcional)
#@return path_dir - Camino al directorio del grupo.
#@note repo = { REPO, CACHE } REPO por defecto
#@exception OG_ERR_FORMAT formato incorrecto.
#@version 1.0.2 - Primera versión para OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-10-03
#*/
function ogGetGroupDir ()
{
local REPO DIR GROUP
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME str_repo" \
"$FUNCNAME REPO ==> /opt/opengnsys/images/groups/Grupo1"
return
fi
# Error si se recibe más de 1 parámetro.
case $# in
0) REPO="REPO" ;;
1) REPO="$1" ;;
*) ogRaiseError $OG_ERR_FORMAT "$*"
return $? ;;
esac
GROUP="$(ogGetGroupName)"
if [ -n "$GROUP" ]; then
DIR=$(ogGetPath "$REPO" "/groups/$GROUP" 2>/dev/null)
[ -d "$DIR" ] && echo "$DIR"
fi
# Para que no haya error al fallar la condición anterior
return 0
}
#/**
# ogGetGroupName
#@brief Devuelve el nombre del grupo al que pertenece el cliente.
#@return str_group - Nombre de grupo.
#@version 1.0.2 - Primera versión para OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-10-03
#*/
function ogGetGroupName ()
{
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME => Grupo1"
return
fi
[ -n "$group" ] && echo "$group"
}
#/**
# ogGetHostname
#@brief Muestra el nombre del cliente.
#@return str_host - nombre de máquina
#@version 0.10 - Integración en OpenGnSys 0.10
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010-02-11
#*/ ##
function ogGetHostname ()
{
local HOST
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME => pc1"
return
fi
# Tomar nombre de la variable HOSTNAME
HOST="$HOSTNAME"
# Si no, tomar del DHCP, opción host-name /* (comentario para Doxygen)
[ -z "$HOST" ] && HOST=$(awk -F\" '/option host-name/ {gsub(/;/,""); host=$2}
END {print host}
' /var/lib/dhcp3/dhclient.leases)
# Si no, leer el parámetro del kernel hostname (comentario para Doxygen) */
[ -z "$HOST" ] && HOST=$(awk 'BEGIN {RS=""; FS="="}
$1~/hostname/ {print $2}' /proc/cmdline)
[ "$HOSTNAME" != "$HOST" ] && export HOSTNAME="$HOST"
[ -n "$HOST" ] && echo $HOST
}
#/**
# ogGetIpAddress
#@brief Muestra la dirección IP del sistema
#@return str_ip - Dirección IP
#@version 0.10 - Integración en OpenGnSys 0.10
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010-02-11
#@version 1.0 - Integración OpenGnSys 0.10 Opengnsys 0.10-testing
#@note Usa las variables utilizadas por el initrd "/etc/net-ethX.conf
#@author Antonio J. Doblas Viso. Universidad de Malaga.
#@date 2011-02-24
#@version 1.0.2 - Soporte para varias tarjetas de red
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-06-17
#*/ ##
function ogGetIpAddress ()
{
local IP
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME => 192.168.0.10"
return
fi
if [ -n "$IPV4ADDR" ]; then
IP="$IPV4ADDR"
else
# Obtener direcciones IP.
if [ -n "$DEVICE" ]; then
IP=$(ip -o address show up dev "$DEVICE" 2>/dev/null | awk '{if ($3~/inet$/) {printf ("%s ", $4)}}')
else
IP=$(ip -o address show up | awk '$2!~/lo/ {if ($3~/inet$/) {printf ("%s ", $4)}}')
fi
fi
# Mostrar solo la primera.
echo "${IP%%/*}" # (comentario para Doxygen) */
}
#/**
# ogGetMacAddress
#@brief Muestra la dirección Ethernet del cliente.
#@return str_ether - Dirección Ethernet
#@version 0.10 - Integración en OpenGnSys 0.10
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2010-02-11
#@version 1.0.2 - Soporte para varias tarjetas de red
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-06-17
#*/ ##
function ogGetMacAddress ()
{
local MAC
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME => 00:11:22:33:44:55"
return
fi
# Obtener direcciones Ethernet.
if [ -n "$DEVICE" ]; then
MAC=$(ip -o link show up dev "$DEVICE" 2>/dev/null | awk '{sub (/.*\\/, ""); if ($1~/ether/) printf ("%s ", toupper($2));}')
else
MAC=$(ip -o link show up | awk '$2!~/lo/ {sub (/.*\\/, ""); if ($1~/ether/) printf ("%s ", toupper($2));}')
fi
# Mostrar sólo la primera.
echo ${MAC%% *}
}
#/**
# ogGetNetInterface
#@brief Muestra la interfaz de red del sistema
#@return str_interface - interfaz de red
#@version 1.0 - Integración OpenGnSys 0.10 Opengnsys 0.10-testing
#@note Usa las variables utilizadas por el initrd "/etc/net-ethX.conf
#@author Antonio J. Doblas Viso. Universidad de Malaga.
#@date 2011-02-24
#*/ ##
function ogGetNetInterface ()
{
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME => eth0"
return
fi
[ -n "$DEVICE" ] && echo "$DEVICE"
}
#/**
# ogGetRepoIp
#@brief Muestra la dirección IP del repositorio de datos.
#@return str_ip - Dirección IP
#@version 0.10 - Integración en OpenGnSys 0.10
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-01-13
#@version 1.0 - Integración OpenGnSys 0.10 Opengnsys 0.10-testing
#@note Comprobacion segun protocolo de conexion al Repo
#@author Antonio J. Doblas Viso. Universidad de Malaga.
#@date 2011-02-24
#@version 1.0.6 - Obtener datos del punto de montaje, evitando fallo si $ogprotocol está vacía.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2014-08-27
#*/ ##
function ogGetRepoIp ()
{
# Variables locales.
local SOURCE FSTYPE
# Mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME => 192.168.0.2"
return
fi
# Obtener direcciones IP, según el tipo de montaje.
eval $(findmnt -P -o SOURCE,FSTYPE $OGIMG)
case "$FSTYPE" in
nfs) echo "$SOURCE" | cut -f1 -d: ;;
cifs) echo "$SOURCE" | cut -f3 -d/ ;;
esac
}
#/**
# ogGetServerIp
#@brief Muestra la dirección IP del Servidor de OpenGnSys.
#@return str_ip - Dirección IP
#@version 0.10 - Integración en OpenGnSys 0.10
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-01-13
#@version 1.0 - Integración OpenGnSys 0.10 Opengnsys 0.10-testing
#@note Comprobacion segun protocolo de conexion al Repo
#@author Antonio J. Doblas Viso. Universidad de Malaga.
#@date 2011-02-24
#@version 1.0.6 - Obtener datos del punto de montaje, evitando fallo si $ogprotocol está vacía.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2014-08-27
#*/ ##
function ogGetServerIp ()
{
# Variables locales.
local SOURCE FSTYPE
# Mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" "$FUNCNAME => 192.168.0.2"
return
fi
# Obtener direcciones IP, según el tipo de montaje.
eval $(findmnt -P -o SOURCE,FSTYPE $OPENGNSYS)
case "$FSTYPE" in
nfs) echo "$SOURCE" | cut -f1 -d: ;;
cifs) echo "$SOURCE" | cut -f3 -d/ ;;
esac
}
#/**
# ogMakeGroupDir [ str_repo ]
#@brief Crea el directorio para el grupo del cliente.
#@param str_repo repositorio de imágenes (opcional)
#@return (nada)
#@note repo = { REPO, CACHE } REPO por defecto
#@exception OG_ERR_FORMAT formato incorrecto.
#@version 1.0.5 - Primera versión para OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2013-09-26
#*/
function ogMakeGroupDir ()
{
local REPO DIR GROUP
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME str_repo" \
"$FUNCNAME" "$FUNCNAME REPO"
return
fi
# Error si se recibe más de 1 parámetro.
case $# in
0) REPO="REPO" ;;
1) REPO="$1" ;;
*) ogRaiseError $OG_ERR_FORMAT "$*"
return $? ;;
esac
# Comprobar tipo de repositorio.
DIR=$(ogGetPath "$REPO" / 2>/dev/null)
[ -n "$DIR" ] || ogRaiseError $OG_ERR_FORMAT "$1"
GROUP="$(ogGetGroupName)"
if [ -n "$GROUP" ]; then
mkdir -p "$DIR/groups/$GROUP" 2>/dev/null
fi
}

View File

@ -1,315 +0,0 @@
#/**
#@file NetLib.py
#@brief Librería o clase Net
#@class Net
#@brief Funciones básicas de red.
#@warning License: GNU GPLv3+
#*/
import subprocess
import sys
import os
import json
import re
import ogGlobals
import SystemLib
import FileLib
def _ogConnect_options():
## the original bash code does: eval $(grep "OPTIONS=" /scripts/ogfunctions)
## this is highly insecure but we need to keep it for now
opt = subprocess.run (['grep', '-o', 'OPTIONS=.*', '/scripts/ogfunctions'], capture_output=True, text=True).stdout.strip()
exec (opt, globals())
return OPTIONS
## defined in /scripts/ogfunctions. We can't tackle that yet.
## this is a quick implementation just to unblock development
def _ogConnect (server, protocol, src, dst, options, readonly):
if 'smb' != protocol: return None ## only supported value right now
write_option = ',ro' if readonly else ',rw'
options += write_option
return not subprocess.run (['mount.cifs', f'//{server}/{src}', dst] + options.split()).returncode
#/**
# ogChangeRepo IPREPO [ OgUnit ]
#@brief Cambia el repositorio para el recurso remoto images.
#@param 1 Ip Repositorio
#@param 2 Abreviatura Unidad Organizativa
#@return Cambio recurso remoto en OGIMG.
#*/
def ogChangeRepo(ip_repo, og_unit=None):
ogprotocol = os.environ['ogprotocol'] or 'smb'
if og_unit:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, 'the og_unit parameter became unsupported')
return None
try:
mount = subprocess.run (['mount'], capture_output=True, text=True).stdout
ro = bool (list (filter (lambda line: re.search (r'ogimages.*\bro,', line), mount.splitlines())))
current_repo = ogGetRepoIp()
new_repo = current_repo if ip_repo.upper() == "REPO" else ip_repo
if new_repo == current_repo: return True
subprocess.run(["umount", ogGlobals.OGIMG], check=True)
SystemLib.ogEcho (['session', 'log'], None, f'{ogGlobals.lang.MSG_HELP_ogChangeRepo} {new_repo}')
options = _ogConnect_options()
if not _ogConnect (new_repo, ogprotocol, 'ogimages', ogGlobals.OGIMG, options, ro):
_ogConnect (current_repo, ogprotocol, 'ogimages', ogGlobals.OGIMG, options, ro)
SystemLib.ogRaiseError(
"session",
ogGlobals.OG_ERR_REPO,
f"Error connecting to the new repository: {new_repo}",
)
return False
SystemLib.ogEcho(
["session", "log"],
None,
f"Repository successfully changed to {new_repo}".strip(),
)
return True
except Exception as e:
SystemLib.ogRaiseError(
"session",
ogGlobals.OG_ERR_GENERIC,
f"Error executing ogChangeRepo: {e}",
)
return None
#/**
# ogGetGroupDir [ str_repo ]
#@brief Devuelve el camino del directorio para el grupo del cliente.
#@param str_repo repositorio de imágenes (opcional)
#@return path_dir - Camino al directorio del grupo.
#@note repo = { REPO, CACHE } REPO por defecto
#@exception OG_ERR_FORMAT formato incorrecto.
#*/
def ogGetGroupDir(repo=None):
try:
repo = repo or "REPO"
group = ogGetGroupName()
if group:
dir_path = FileLib.ogGetPath(repo, f"/groups/{group}")
if dir_path and os.path.isdir(dir_path):
return dir_path
return None
except Exception as e:
SystemLib.ogRaiseError(
"session",
ogGlobals.OG_ERR_FORMAT,
f"Error in ogGetGroupDir: {e}"
)
return None
#/**
# ogGetGroupName
#@brief Devuelve el nombre del grupo al que pertenece el cliente.
#@return str_group - Nombre de grupo.
#*/
def ogGetGroupName():
try:
group = globals().get("group", None)
return group if group else None
except Exception as e:
print(f"Error in ogGetGroupName: {e}")
return None
#/**
# ogGetHostname
#@brief Muestra el nombre del cliente.
#@return str_host - nombre de máquina
#*/ ##
def ogGetHostname():
# Tomar nombre de la variable HOSTNAME
host = os.getenv("HOSTNAME", "").strip()
if host: return host
# Si no, tomar del DHCP, opción host-name /* (comentario para Doxygen)
dhcp_file = "/var/lib/dhcp3/dhclient.leases"
if os.path.exists(dhcp_file):
with open(dhcp_file, "r") as f:
for line in f:
if 'option host-name' in line:
return line.split('"')[1].strip(";")
# Si no, leer el parámetro del kernel hostname (comentario para Doxygen) */
cmdline_file = "/proc/cmdline"
if os.path.exists(cmdline_file):
with open(cmdline_file, "r") as f:
for entry in f.read().split():
if entry.startswith("hostname="):
return entry.split("=")[1].strip()
#/**
# ogGetIpAddress
#@brief Muestra la dirección IP del sistema
#@return str_ip - Dirección IP
#@note Usa las variables utilizadas por el initrd "/etc/net-ethX.conf
#*/ ##
def ogGetIpAddress():
if "IPV4ADDR" in os.environ:
ip = os.environ["IPV4ADDR"]
if '/' in ip: ip = ip.split ('/')[0]
return ip
extra_args = []
if "DEVICE" in os.environ:
extra_args = [ "dev", os.environ["DEVICE"] ]
ipas = subprocess.run (['ip', '-json', 'address', 'show', 'up'] + extra_args, capture_output=True, text=True).stdout
ipasj = json.loads (ipas)
addresses = []
for e in ipasj:
if 'lo' == e['ifname']: continue
if 'addr_info' not in e: continue
addrs = e['addr_info']
for a in addrs:
if 'inet' != a['family']: continue
addresses.append ({ 'local': a['local'], 'prefixlen': a['prefixlen'] })
if 1 != len (addresses):
raise Exception ('more than one local IP address found')
return addresses[0]
#/**
# ogGetMacAddress
#@brief Muestra la dirección Ethernet del cliente.
#@return str_ether - Dirección Ethernet
#*/ ##
def ogGetMacAddress():
try:
if "DEVICE" in os.environ:
device = os.environ["DEVICE"]
result = subprocess.run(
["ip", "-o", "link", "show", "up", "dev", device],
capture_output=True,
text=True,
check=True
).stdout
else:
result = subprocess.run(
["ip", "-o", "link", "show", "up"],
capture_output=True,
text=True,
check=True
).stdout
mac_addresses = []
for line in result.splitlines():
if "link/ether" in line:
parts = line.split()
for i, part in enumerate(parts):
if part == "link/ether":
mac_addresses.append(parts[i + 1].upper())
if mac_addresses:
print (f'nati: ogGetMacAddress: {mac_addresses[0]}')
return mac_addresses[0]
else:
print("No active mac address found")
return None
except subprocess.CalledProcessError as e:
print(f"Error executing ip command: {e.stderr}")
return None
except Exception as e:
print(f"Unexpected error: {str(e)}")
return None
#/**
# ogGetNetInterface
#@brief Muestra la interfaz de red del sistema
#@return str_interface - interfaz de red
#@note Usa las variables utilizadas por el initrd "/etc/net-ethX.conf
#*/ ##
def ogGetNetInterface():
if len(sys.argv) >= 2 and sys.argv[1] == "help":
SystemLib.ogHelp("ogGetNetInterface", "ogGetNetInterface", "ogGetNetInterface => eth0")
return
if "DEVICE" in os.environ:
print(os.environ["DEVICE"])
return 0
#/**
# ogGetRepoIp
#@brief Muestra la dirección IP del repositorio de datos.
#@return str_ip - Dirección IP
#*/ ##
def ogGetRepoIp():
out = subprocess.run (["findmnt", "--json", "--output", "SOURCE,FSTYPE", ogGlobals.OGIMG], capture_output=True, text=True).stdout
try:
j = json.loads (out)
except json.decoder.JSONDecodeError:
return None
if 'filesystems' not in j: return None
source = j['filesystems'][0]['source']
fstype = j['filesystems'][0]['fstype']
if 'nfs' == fstype: return source.split(":")[0]
elif 'cifs' == fstype: return source.split("/")[2]
return None
#/**
# ogGetServerIp
#@brief Muestra la dirección IP del Servidor de OpenGnSys.
#@return str_ip - Dirección IP
#@note Comprobacion segun protocolo de conexion al Repo
#*/ ##
def ogGetServerIp():
return os.environ['ogcore']
#/**
# ogGetServerPort
#@brief Muestra el puerto del Servidor de OpenGnSys.
#@return str_port - Puerto
#*/ ##
def ogGetServerPort():
if 'ogcore_port' in os.environ:
return os.environ['ogcore_port']
else:
return '8443'
#/**
# ogMakeGroupDir [ str_repo ]
#@brief Crea el directorio para el grupo del cliente.
#@param str_repo repositorio de imágenes (opcional)
#@return (nada)
#@note repo = { REPO, CACHE } REPO por defecto
#@exception OG_ERR_FORMAT formato incorrecto.
#*/
def ogMakeGroupDir():
REPO = ""
DIR = ""
GROUP = ""
if len(sys.argv) < 2:
SystemLib.ogHelp("ogMakeGroupDir", "ogMakeGroupDir str_repo", "ogMakeGroupDir", "ogMakeGroupDir REPO")
return
if len(sys.argv) == 1:
REPO = "REPO"
else:
REPO = sys.argv[1]
DIR = FileLib.ogGetPath(REPO, "/groups/" + ogGetGroupName(), stderr=subprocess.DEVNULL)
if DIR:
subprocess.run(["mkdir", "-p", DIR], stderr=subprocess.DEVNULL)
return 0

View File

@ -0,0 +1,543 @@
#!/bin/bash
#/**
#@file PostConf.lib
#@brief Librería o clase PostConf
#@class PostConf
#@brief Funciones para la postconfiguración de sistemas operativos.
#@version 1.1.0
#@warning License: GNU GPLv3+
#*/
#/**
# ogCleanOs int_ndisk int_nfilesys
#@brief Elimina los archivos que no son necesarios en el sistema operativo.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#@exception OG_ERR_PARTITION Partición desconocida o no accesible.
#@note Antes incluido en la funcion ogReduceFs
#@author Irina Gomez. Universidad de Sevilla.
#@return (nada)
#@date 2014-10-27
#*/ ##
function ogCleanOs ()
{
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_nfilesys" \
"$FUNCNAME 1 1"
return
fi
# Error si no se reciben 2 parámetros.
[ $# == 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_nfilesys" || return $?
case "$(ogGetOsType $1 $2)" in
Linux)
# Borramos los ficheros de dispositivos y los temporales.
ogCleanLinuxDevices $1 $2
rm -rf $(ogMount $1 $2)/tmp/* #*/ Comentario Doxygen
;;
Windows)
# Borrar ficheros de hibernación y paginación de Windows.
[ -n "$(ogGetPath $1 $2 pagefile.sys)" ] && ogDeleteFile $1 $2 pagefile.sys
[ -n "$(ogGetPath $1 $2 hiberfil.sys)" ] && ogDeleteFile $1 $2 hiberfil.sys
[ -n "$(ogGetPath $1 $2 swapfile.sys)" ] && ogDeleteFile $1 $2 swapfile.sys
;;
esac
}
#/**
# ogInstallMiniSetup int_ndisk int_npartition str_filename [str_admuser str_admpassword bool_autologin [str_autouser str_autopassword] ]
#@brief Metafunción para instalar archivo que se ejecutará en el arranque de Windows.
#@see ogInstallFirstBoot ogInstallRunonce
#*/ ##
function ogInstallMiniSetup ()
{
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$MSG_SEE ogInstallFirstBoot ogInstallRunonce"
return
fi
case $# in
3) # Ejecución en el primer arranque de la máquina.
ogInstallFirstBoot "$@" ;;
6|8) # Ejecución en el "runonce".
ogInstallRunonce "$@" ;;
*) ogRaiseError $OG_ERR_FORMAT
return $? ;;
esac
}
#/**
# ogInstallFirstBoot int_ndisk int_npartition str_filename
#@brief Crea unas claves del registro y el archivo cmd que se ejecutara en el primer arranque estando la maquina en un estado bloqueado
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_filename nombre del archivo .cmd a ejecutar en el arranque
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@note El archivo estará en system32 y será visible por el sistema.
#@version 1.0.2 - Nueva función
#@author Jonathan Alonso Martinez - Universidad Autonoma de Barcelona
#@date 2011-06-29
#@version 1.0.4 - Heredada de antigua función ogInstallMiniSetup.
#@author Jonathan Alonso Martinez - Universidad Autonoma de Barcelona
#@date 2012-04-16
#*/ ##
function ogInstallFirstBoot ()
{
local MNTDIR DIR CMDDIR CMDFILE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_npartition str_filename" \
"$FUNCNAME 1 1 filename.cmd"
return
fi
# Error si no se reciben 3 parámetros.
[ $# == 3 ] || return $(ogRaiseError $OG_ERR_FORMAT; echo $?)
# Comprobar que existe el directorio del fichero de comandos.
MNTDIR=$(ogMount "$1" "$2") || return $?
for i in winnt windows; do
DIR=$(ogGetPath $MNTDIR/$i/system32)
[ -n "$DIR" ] && CMDDIR=$DIR
done
[ -n "$CMDDIR" ] || ogRaiseError $OG_ERR_NOTFOUND "$MNTDIR/windows/system32" || return $?
CMDFILE="$CMDDIR/$3"
# Creamos el archivo cmd y creamos un par de comandos para que una vez acabe la
# postconfiguracion resetee el mini setup, sino lo haria en cada arranque.
cat > "$CMDFILE" << EOF
REG ADD HKLM\System\Setup /v SystemSetupInProgress /t REG_DWORD /d 0 /f
REG ADD HKLM\System\Setup /v CmdLine /t REG_SZ /d "" /f
EOF
# Crear los valores de registro necesarios para que se haga la ejecución del .cmd al aranque.
ogSetRegistryValue "$MNTDIR" SYSTEM "\Setup\SystemSetupInProgress" 1
ogSetRegistryValue "$MNTDIR" SYSTEM "\Setup\SetupType" 4
#ogDeleteRegistryValue "$MNTDIR" SYSTEM "\Setup\CmdLine"
ogAddRegistryValue "$MNTDIR" SYSTEM "\Setup\CmdLine"
ogSetRegistryValue "$MNTDIR" SYSTEM "\Setup\CmdLine" "cmd.exe /c $(basename $CMDFILE)"
}
#/**
# ogInstallRunonce int_ndisk int_npartition str_filename str_adm_user str_adm_password bool_autologin [str_auto_user str_auto_password]
#@brief Crea el archivo cmd que se ejecutara en el runonce de un usuario administrador
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_filename nombre del archivo .cmd a ejecutar en el arranque (estara en system32 y sera visible por el sistema)
#@param str_adm_user usuario administrador para hacer autologin y ejecutar el runonce
#@param str_adm_password password del usuario administrador
#@param bool_autologin si despues de la postconfiguracion queremos que la maquina haga autologin (0 o 1)
#@param str_auto_user Usuario con el que queremos que haga autologin despues de la postconfiguracion
#@param str_auto_password Password del usuario que hara autologin
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@version 1.0.2 - Nueva función
#@author Jonathan Alonso Martinez - Universidad Autonoma de Barcelona
#@date 2011-06-29
#@version 1.0.4 - Heredado de antigua función ogInstallMiniSetup
#@author Jonathan Alonso Martinez - Universidad Autonoma de Barcelona
#@date 2012-04-16
#@version 1.1.0 - Resuelve problemas a partir de Windows 10
#@author Carmelo Cabezuelo Aguilar - Universidad Politécnica de Valencia
#@date 2018-02-20
#*/ ##
function ogInstallRunonce ()
{
local MOUNTPOINT DIR CMDDIR CMDFILE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_npartition str_filename str_adm_user str_adm_password bool_autologin [str_auto_user str_auto_password]" \
"$FUNCNAME 1 1 filename.cmd administrator passadmin 1 userauto passuserauto" \
"$FUNCNAME 1 1 filename.cmd administrator passadmin 0"
return
fi
# Error si no se reciben 6 u 8 parámetros.
[ $# == 6 -o $# == 8 ] || return $(ogRaiseError $OG_ERR_FORMAT; echo $?)
# Punto de montaje.
MOUNTPOINT="$(ogGetPath "$1" "$2" /)"
# Comprobar que existe el directorio del fichero de comandos.
for i in winnt windows; do
DIR=$(ogGetPath $MOUNTPOINT/$i/system32)
[ -n "$DIR" ] && CMDDIR=$DIR
done
[ -n "$CMDDIR" ] || ogRaiseError $OG_ERR_NOTFOUND "$MOUNTPOINT/Windows/System32" || return $?
CMDFILE="$CMDDIR/$3"
if [ $6 == 0 ]; then
# Si no queremos hacer autologin despues de la postconfiguracion lo indicamos en las claves de registro
cat > "$CMDFILE" << EOF
DEL C:\ogboot.*
REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon /t REG_SZ /d 0 /f
REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName /t REG_SZ /d "" /f
REG DELETE "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword /f
EOF
else
# Si queremos hacer autologin despues de la postconfiguracion introducimos la informacion en las claves de registro
cat > "$CMDFILE" << EOF
DEL C:\ogboot.*
REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon /t REG_SZ /d 1 /f
REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName /t REG_SZ /d "$7" /f
REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword /t REG_SZ /d "$8" /f
EOF
fi
#Creamos las claves de registro necesarias para que meter el cmd en el runonce del usuario y este haga autologin
ogAddRegistryValue $MOUNTPOINT software '\Microsoft\Windows\CurrentVersion\RunOnce\PostConfiguracion' 2>/dev/null
ogSetRegistryValue $MOUNTPOINT software '\Microsoft\Windows\CurrentVersion\RunOnce\PostConfiguracion' "C:\windows\system32\\$3" 2>/dev/null
ogAddRegistryValue $MOUNTPOINT software '\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoAdminLogon' 2>/dev/null
ogSetRegistryValue $MOUNTPOINT software '\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoAdminLogon' 1 2>/dev/null
ogAddRegistryValue $MOUNTPOINT software '\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName' 2>/dev/null
ogSetRegistryValue $MOUNTPOINT software '\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName' "$4" 2>/dev/null
ogAddRegistryValue $MOUNTPOINT software '\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultDomainName' 2>/dev/null
ogSetRegistryValue $MOUNTPOINT software '\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultDomainName' ".\\" 2>/dev/null
ogAddRegistryValue $MOUNTPOINT software '\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultPassword' 2>/dev/null
ogSetRegistryValue $MOUNTPOINT software '\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultPassword' "$5" 2>/dev/null
ogDeleteRegistryValue $MOUNTPOINT software '\Microsoft\Windows NT\CurrentVersion\Winlogon\ForceAutoLockOnLogon' 2>/dev/null
ogDeleteRegistryValue $MOUNTPOINT software '\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoLogonCount' 2>/dev/null
}
#/**
# ogAddCmd int_ndisk int_npartition str_filename str_commands
#@brief Añade comandos al cmd creado por ogInstalMiniSetup
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_filename nombre del fichero cmd (siempre se guardara en windows\system32\para que sea visible por el sistema
#@param str_commands comando o comandos que se añadiran al fichero
#@return
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar.
#@version 1.0.2 - Nueva función
#@author Jonathan Alonso Martinez - Universidad Autonoma de Barcelona
#@date 2011-06-29
#@version 1.0.4 - Cambios en los parametros de entrada de la funcion
#@author Jonathan Alonso Martinez - Universidad Autonoma de Barcelona
#@date 2012-04-16
#*/ ##
function ogAddCmd ()
{
local MOUNTPOINT CMDFILE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_npartition str_filename str_commands" \
"$FUNCNAME 1 1 filename.cmd command"
return
fi
# Error si no se reciben 4 parámetros.
[ $# == 4 ] || return $(ogRaiseError $OG_ERR_FORMAT; echo $?)
# Punto de montaje
MOUNTPOINT="$(ogMount "$1" "$2")" || return $?
# Crear fichero de comandos, si no existe.
CMDFILE="$(ogGetPath "$MOUNTPOINT/windows/system32")/$3"
[ -n "$CMDFILE" ] || ogInstallMiniSetup "$1" "$2" "$3"
[ -n "$CMDFILE" ] || ogRaiseError $OG_ERR_NOTFOUND "$MOUNTPOINT/windows/system32/$3" || return $?
# Concatenamos el comando en el fichero de comandos
cat >> "$CMDFILE" << EOF
$4
EOF
}
#/**
# ogDomainScript int_ndisk int_npartition str_domain str_user str_password
#@brief Crea un script .vbs para unir al dominio una maquina windows y el comando adequado en el archivo cmd creado por ogInstallMiniSetup
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_filename nombre del fichero cmd donde deberemos introducir el comando de ejecutar el script vbs
#@param str_domain dominio donde se quiere conectar
#@param str_user usuario con privilegios para unir al dominio
#@param str_password password del usuario con privilegios
#@return
#@exception OG_ERR_FORMAT Formato incorrecto.
#@version 1.0.2 - Nueva función
#@author Jonathan Alonso Martinez - Universidad Autonoma de Barcelona
#@date 2011-06-29
#@version 1.0.4 - Cambios en los parametros de entrada de la funcion
#@author Jonathan Alonso Martinez - Universidad Autonoma de Barcelona
#@date 2012-04-16
#*/ ##
function ogDomainScript ()
{
local CMDDIR
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" \
"$FUNCNAME int_ndisk int_npartition str_filename str_domain str_user str_password" \
"$FUNCNAME 1 1 filename.cmd domain user password_user"
return
fi
# Error si no se reciben 6 parámetros.
[ $# == 6 ] || return $(ogRaiseError $OG_ERR_FORMAT; echo $?)
# Punto de montaje
MOUNTPOINT="$(ogMount "$1" "$2")" || return $?
# Comprobar que existe el directorio de comandos.
CMDDIR=$(ogGetPath "$MOUNTPOINT/windows/system32")
[ -n "$CMDDIR" ] || ogRaiseError $OG_ERR_NOTFOUND "$1/windows/system32" || return $?
# Añadimos en el cmd que se ejecutara al arranque, el comando de ejecutar el script que añade al dominio.
ogAddCmd $1 $2 "$3" "CSCRIPT joindomain.vbs"
# Eliminamos el script porque tiene el usuario de administrador de dominio en claro
ogAddCmd $1 $2 "$3" "DEL /Q C:\Windows\System32\joindomain.vbs"
# Metemos unas claves de registro para que el dominio salga seleccionado por defecto
ogAddCmd $1 $2 "$3" "REG ADD \"HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\" /v DefaultDomainName /t REG_SZ /d \"$4\" /f"
# Creamos el archivo joindomain.vbs que nos introduce la maquina en el dominio
cat > "$CMDDIR/joindomain.vbs" << EOF
Const JOIN_DOMAIN = 1
Const ACCT_CREATE = 2
Const ACCT_DELETE = 4
Const WIN9X_UPGRADE = 16
Const DOMAIN_JOIN_IF_JOINED = 32
Const JOIN_UNSECURE = 64
Const MACHINE_PASSWORD_PASSED = 128
Const DEFERRED_SPN_SET = 256
Const INSTALL_INVOCATION = 262144
strDomain = "$4"
strUser = "$5"
strPassword = "$6"
Set objNetwork = CreateObject("WScript.Network")
strComputer = objNetwork.ComputerName
Set objComputer = GetObject("winmgmts:{impersonationLevel=Impersonate}!\\\" & _
strComputer & "\root\cimv2:Win32_ComputerSystem.Name='" & strComputer & "'")
ReturnValue = objComputer.JoinDomainOrWorkGroup(strDomain, strPassword, _
strDomain & "\" & strUser, NULL, JOIN_DOMAIN + ACCT_CREATE)
EOF
#*/ " (comentario Doxygen)
}
### PRUEBAS.
#/**
# ogConfigureOgagent int_ndisk int_filesys
#@brief Modifica el fichero de configuración del nuevo agente OGAent para sistemas operativos.
#@param int_ndisk nº de orden del disco
#@param int_filesys nº de orden del sistema de archivos
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero o dispositivo no encontrado.
#@exception OG_ERR_LOCKED Sistema de archivos bloqueado.
#@version 1.1.0 - Primera adaptación para OpenGnsys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2016-07-15
#*/ ##
function ogConfigureOgagent ()
{
# Variables locales.
local MNTDIR AGENTDIR CFGFILE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_filesys" \
"$FUNCNAME 1 1"
return
fi
# Error si no se reciben 2 parámetros.
[ $# == 2 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Obtener sistema de archvios.
MNTDIR=$(ogMount $1 $2) || return $?
# Comprobar si existe el fichero de configuración de OGAgent.
for AGENTDIR in usr/share/OGAgent "Program Files/OGAgent" "Program Files (x86)/OGAgent" Applications/OGAgent.app; do
CFGFILE=$(ogGetPath "$MNTDIR/$AGENTDIR/cfg/ogagent.cfg")
[ -n "$CFGFILE" ] && break
done
[ -n "$CFGFILE" ] || ogRaiseError $OG_ERR_NOTFOUND "ogagent.cfg" || return $?
# Parchear dirección del servidor OpenGnsys en el fichero de configuración de OGAgent.
sed -i "0,/remote=/ s,remote=.*,remote=https://$(ogGetServerIp):8443/opengnsys/rest/," "$CFGFILE"
}
#/**
# ogInstallLaunchDaemon int_ndisk int_nfilesys str_filename
#@brief Instala archivo que se ejecutará en el arranque de macOS.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@param str_filename nombre del script
#return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero o directorio no encontrado.
#@npte Crea ficheros de configuración /Library/LaunchDaemon/es.opengnsys.Script.plist.
#@version 1.0.6 - Primera versión para OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2014-10-06
#*/ ##
function ogInstallLaunchDaemon ()
{
# Variables locales.
local LAUNCHDIR SCRIPTDIR
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_filesys str_scriptname" \
"$FUNCNAME 1 2 postconf"
return
fi
# Error si no se reciben 3 parámetros.
[ $# == 3 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Comprobar directorios.
LAUNCHDIR=$(ogGetPath $1 $2 /Library/LaunchDaemons)
[ -n "$LAUNCHDIR" ] || ogRaiseError $OG_ERR_NOTFOUND "$1 $2 /Library/LaunchDaemons" || return $?
SCRIPTDIR=$(ogGetPath $1 $2 /usr/share)
[ -n "$SCRIPTDIR" ] || ogRaiseError $OG_ERR_NOTFOUND "$1 $2 /usr/share" || return $?
# Crear fichero de configuración del servicio de arranque.
cat << EOT $LAUNCHDIR/es.opengnsys.$3.plist
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>es.opengnsys.$3</string>
<key>ProgramArguments</key>
<array>
<string>$SCRIPTDIR/$3.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/var/log/$3.log</string>
<key>StandardErrorPath</key>
<string>/var/log/$3.err</string>
<true/>
</dict>
</plist>
EOT
# Crear un fichero de script vacío.
rm -f $SCRIPTDIR/$3.sh
touch $SCRIPTDIR/$3.sh
chmod +x $SCRIPTDIR/$3.sh
}
### PRUEBAS.
#/**
# ogAddToLaunchDaemon int_ndisk int_nfilesys str_filename str_commands
#@brief Añade comandos al script creado por ogInstalLaunchDaemon.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@param str_filename nombre del script (siempre se guardará en /usr/share para que sea visible por el sistema
#@param str_commands comando o comandos que se añadiran al fichero
#return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero o directorio no encontrado.
#@version 1.0.6 - Primera versión para OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2014-10-06
#*/ ##
function ogAddToLaunchDaemon ()
{
# Variables locales.
local SCRIPTFILE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_filesys str_scriptname" \
"$FUNCNAME 1 2 postconf \"diskutil enableJournal disk0s2\""
return
fi
# Error si no se reciben 4 parámetros.
[ $# == 4 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Comprobar que existe el fichero de comandos.
SCRIPTFILE=$(ogGetPath $1 $2 "/usr/share/$3.sh")
[ -n "$SCRIPTFILE" ] || ogRaiseError $OG_ERR_NOTFOUND "$1 $2 /usr/share/$3" || return $?
# Concatenamos el comando en el fichero de comandos
cat >> "$SCRIPTFILE" << EOT
$4
EOT
}
#/**
# ogUninstallLinuxClient int_ndisk int_filesys
#@brief Desinstala el cliente OpenGnSys para sistemas operativos GNU/Linux.
#@param int_ndisk nº de orden del disco
#@param int_filesys nº de orden del sistema de archivos
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_PARTITION Paritición o sistema de archivos incorrectos.
#@exception OG_ERR_LOCKED Sistema de archivos bloqueado.
#@version 1.1.0 - Primera adaptación para OpenGnsys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2016-08-22
#*/ ##
function ogUninstallLinuxClient ()
{
# Variables locales.
local MNTDIR
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_filesys" \
"$FUNCNAME 1 1"
return
fi
# Error si no se reciben 2 parámetros.
[ $# == 2 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Obtener sistema de archvios.
MNTDIR=$(ogMount $1 $2) || return $?
# Borrar ficheros y quitar llamada al cliente durante el proceso de inicio.
rm -f $MNTDIR/{usr/sbin,sbin,usr/local/sbin}/ogAdmLnxClient
rm -f $MNTDIR/{etc,usr/local/etc}/ogAdmLnxClient.cfg
sed -i -e '/ogAdmLnxClient/ d' $MNTDIR/{etc,usr/local/etc}/{rc.local,rc.d/rc.local} 2>/dev/null
}
#/**
# ogUninstallWindowsClient int_ndisk int_filesys str_filename
#@brief Desinstala el cliente OpenGnSys para sistemas operativos Windows.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_filename nombre del fichero cmd donde deberemos introducir el comando de ejecutar el script vbs
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_PARTITION Paritición o sistema de archivos incorrectos.
#@exception OG_ERR_LOCKED Sistema de archivos bloqueado.
#@version 1.1.0 - Primera adaptación para OpenGnsys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2016-08-22
#*/ ##
function ogUninstallWindowsClient ()
{
# Variables locales.
local MNTDIR
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_filesys str_filename" \
"$FUNCNAME 1 1 filename.cmd"
return
fi
# Error si no se reciben 3 parámetros.
[ $# == 3 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Obtener sistema de archvios.
MNTDIR=$(ogMount "$1" "$2") || return $?
# Crear órdenes para desinstalar servicio y borrar ejecutable del cliente.
if [ -n "$(ogGetPath $MNTDIR/windows/ogAdmWinClient.exe)" -o -n "$(ogGetPath $MNTDIR/winnt/ogAdmWinClient.exe)" ]; then
ogAddCmd $1 $2 "$3" 'ogAdmWinClient -remove'
ogAddCmd $1 $2 "$3" 'DEL C:\Windows\ogAdmWinClient.exe'
ogAddCmd $1 $2 "$3" 'DEL C:\Winnt\ogAdmWinClient.exe'
fi
}

View File

@ -0,0 +1,699 @@
#!/bin/bash
# ogLoadHiveWindows int_ndisk int_partiton
#@brief Localiza los hive del registro de windows (de sistema y usuarios)
#@param int_ndisk nº de orden del disco
#@param int_partition nº de particion
#@return
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar.
#@version 0.9 - Adaptación a OpenGNSys.
#@author Antonio J. Doblas Viso. Universidad de Málaga
#@date 2009-09-24
#*/ ##
function ogLoadHiveWindows () {
# Variables locales.
local PART DISK
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_partition" \
"$FUNCNAME 1 1 "
return
fi
# Error si no se reciben 2 parámetros.
[ $# == 2 ] || return $(ogRaiseError $OG_ERR_FORMAT; echo $?)
DISK=$1; PART=$2;
#Comprobaciones redundantes: borrar"
#ogDiskToDev $DISK $PART || return $(ogRaiseError $OG_ERR_PARTITION "particion de windows no detectada"; echo $?)
#ogGetOsType $DISK $PART | grep "Windows" || return $(ogRaiseError $OG_ERR_NOTOS "no es windows"; echo $?)
#VERSION=$(ogGetOsVersion $DISK $PART)
#Fin Comprobaciones redundantes: borrar"
# primera fase, carga de los hive del sistema
if ogGetPath $DISK $PART WINDOWS
then
SYSTEMROOT="Windows"
elif ogGetPath $DISK $PART WINNT
then
SYSTEMROOT="winnt"
else
return $(ogRaiseError $OG_ERR_NOTOS "version windows no detectada"; echo $?)
fi
hiveSAM=$(ogGetPath $DISK $PART /${SYSTEMROOT}/system32/config/SAM)
[ -n "$hiveSAM" ] && export hiveSAM || return $(ogRaiseError $OG_ERR_NOTOS " hive SAM no detectada"; echo $?)
hiveSYSTEM=$(ogGetPath $DISK $PART /${SYSTEMROOT}/system32/config/system)
[ -n "$hiveSYSTEM" ] && export hiveSYSTEM || return $(ogRaiseError $OG_ERR_NOTOS "hive SYSTEM no detectada"; echo $?)
hiveSOFTWARE=$(ogGetPath $DISK $PART /${SYSTEMROOT}/system32/config/software)
[ -n "$hiveSOFTWARE" ] && export hiveSOFTWARE || return $(ogRaiseError $OG_ERR_NOTOS "hive SOFTWARE no detectada"; echo $?)
export TEMPhive=/tmp/tmpregistry
# segunda fase, carga de los hive de usuarios windows.
declare -i COUNT
COUNT=3
#TODO WINDOWS XP WINDOWS7
BASEHOMEDIR=$(ogGetPath $DISK $PART /"Documents and Settings")
TMPUSERFILE="/tmp/WuserRegAndDAT.tmp"
find "$BASEHOMEDIR/" -type f -name NTUSER.DAT > $TMPUSERFILE
LISTUSERS=$(drbl-chntpw -l $hiveSAM | grep RID | awk -F"<" '{print $2}' | awk -F">" '{print $1}')
#echo "$BASEHOMEDIR" $LISTUSERS
for user in $LISTUSERS
do
# Comprobamos que el usuario registrado tiene .DAT
if HOMEDIR=$(cat $TMPUSERFILE | grep -w $user)
then
#echo "$user exportamos los usuarios de windows como variables, y como valor hiveUSERX; donde la X es 3 4 5 6 ... X"
export `echo $user=hiveUSER$COUNT`
#echo "$user exportamos la variable hiveUSERX con el valor del home de la variable-usuario_windows"
##export `echo hiveUSER$COUNT`="$(echo $HOMEDIR | sed -e 's/ /\\ /'g | sed -e 's/\\/\\\\/g')"
export `echo hiveUSER$COUNT`="$(echo $HOMEDIR)"
#echo " estas variables \$USUARIO -> Identificador del HIVE ; \${!USUARIO} -> path del HIVE "
COUNT=${COUNT}+1
fi
done
COUNT=0
}
# ogUpdateHiveWindows
#@brief Actualiza los hive de windows.
#@param int_ndisk
#@param int_partition
#@return
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar.
#@version 0.9 - Adaptación a OpenGNSys.
#@author Antonio J. Doblas Viso. Universidad de Málaga
#@date 2009-09-24
#*/ ##
function ogUpdateHiveWindows (){
# Variables locales.
local PART DISK FILE
#TODO detectar llamada a ogLoadHiveWindows
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME " \
"$FUNCNAME "
return
fi
echo drbl-chntpw -f $TEMPhive $hiveSAM $hiveSYSTEM $hiveSOFTWARE \"${hiveUSER3}\" \"${hiveUSER4}\" \"${hiveUSER5}\" \"${hiveUSER6}\" \"${hiveUSER7}\" \"${hiveUSER8}\" \"${hiveUSER9}\" > /tmp/run.sh
cat /tmp/run.sh; sh /tmp/run.sh; rm -fr $TEMPhive; rm /tmp/run.sh
unset hiveSAM hiveSYSTEM hiveSOFTWARE TEMPhive hiveUSER3 hiveUSER4 hiveUSER5 hiveUSER6 hiveUSER7 hiveUSER8 hiveUSER9
}
function ogHiveNTRunMachine () {
#echo sintaxis: PathScripts idScripts
#echo ejemplo: c:\\\\WINDOSWS\\\\crearusuarios.bat scripts1
#echo IMPORTANTE: el path debe llevar dos barras \\, pero como se deben 'escapar' debes poner cuatro \\\\
#echo "identifica 0=$hiveSAM 1=$hiveSystem 2=$hiveSoftware 3=$HiveUser3"
local PART DISK FILE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME PathScripts|command keyName " \
"$FUNCNAME c:\\\\Windows\\\\crearusuarios.cmd scripts_crearUsuarios "\
"$FUNCNAME "cmd /c del c:\ogboot.*" ogcleanboot "\
"$FUNCNAME Requiere la previa ejecución de ogLoadHive int_disk int_part"\
"$FUNCNAME Despues requiere el ogUpdateHive"
return
fi
# Error si no se reciben al menos 1 parámetros.
[ $# == 2 ] || return $(ogRaiseError $OG_ERR_FORMAT; echo $?)
cat >> $TEMPhive << EOF
h 2
cd \Microsoft\Windows\CurrentVersion\Run
nv 1 $2
ed $2
$1
EOF
#ogGetRegistryValue /mnt/sda1 software '\Microsoft\Windows\CurrentVersion\Run\og3'
}
function ogNTPolUserOn () {
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME id_hive_user " \
"$FUNCNAME NombreUsuario"\
"$FUNCNAME "
return
fi
# TODO: error si no se ha llamado previamente a ogLoadHiveWindows
[ -n $hiveSAM ] || return $(ogRaiseError $OG_ERR_FORMAT "se debe utilizar primero la utilidad ogLoadHiveWindows"; echo $?)
# TODO: error si el usuario no tiene cuenta en windows.
drbl-chntpw -l $hiveSAM | grep RID | grep -w $1 || return $(ogRaiseError $OG_ERR_FORMAT "el usuario $1 no tiene cuenta en este windows: Compruebe mayusculas o minusculas"; echo $?)
# TODO: error si no el usario no no tiene HIVE asociado.
[ -n "${!1}" ] || return $(ogRaiseError $OG_ERR_FORMAT "el usuario no tiene hive creado"; echo $?)
HIVEID=$(echo ${!1} | tr -d "hiveUSER")
#echo "IMPORTANTE: la variable HiveUser3=/mnt/windows/Document/\ and/\ Seeting\alumnmos\NTUSER.dat"
echo $HIVEID
#cp /var/EAC/admin/utilswin/Fondo.BMP ${particion}/WINDOWS/
cat >> $TEMPhive << EOF
h $HIVEID
cd \Control Panel\Desktop
ed Wallpaper
C:\\WINDOWS\\fondo.bmp
cd \Software\Microsoft\Windows\CurrentVersion\Policies
nk Explorer
cd Explorer
nv 4 NoDesktop
ed NoDesktop
1
nv 4 NoSimpleStartMenu
ed NoSimpleStartMenu
1
nv 4 NoWindowsUpdate
ed NoWindowsUpdate
1
nv 4 NoSMConfigurePrograms
ed NoSMConfigurePrograms
1
nv 4 NoChangeStartMenu
ed NoChangeStartMenu
1
nv 4 Intellimenus
ed Intellimenus
1
nv 4 NoRun
ed NoRun
1
nv 4 NoRecentDocsHistory
ed NoRecentDocsHistory
1
EOF
}
##########################################################
##########################################################
#####librerias de PostConfiguracion v0.1para Advanced Deploy enViorenment###########
# Liberado bajo licencia GPL <http://www.gnu.org/licenses/gpl.html>################
############# 2008 Antonio Jes<65>s Doblas Viso adv@uma.es ##########################
########### Universidad de Malaga (Spain)############################
##########################################################
function NTChangeName () {
if [ $# = 0 ]
then
echo sintaxis: NTChangeNAME str_$var
echo ejemplos: NTCHangeName adi${IPcuatro}-xp
fi
cat >> $temporal << EOF
h 1
ed ControlSet001\Control\ComputerName\ComputerName\ComputerName
$1
ed ControlSet001\Services\Tcpip\Parameters\Hostname
$1
ed ControlSet001\Services\Tcpip\Parameters\NV Hostname
$1
h 2
cd \Microsoft\Windows NT\CurrentVersion\Winlogon
ed DefaultDomainName
$1
EOF
}
function NTSetGroupName () {
if [ $# = 0 ]
then
echo sintaxis: NTSetGroupName str_$var
echo ejemplos: NTSetGroupName adi
fi
cat >> $temporal << EOF
h 2
ed \Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultDomainName
$1
EOF
}
function NTSetOwner (){
if [ $# = 0 ]
then
echo sintaxis: NtSetOwner str_propietario str_organizacion
echo ejemplos: NTSetOwner eu\ politecnica universidad\ de\ malaga
fi
cat >> $temporal << EOF
h 2
ed \Microsoft\Windows NT\CurrentVersion\RegisteredOwner
$1
ed \Microsoft\Windows NT\CurrentVersion\RegisteredOrganization
$2
EOF
}
function NTAutoLogon (){
if [ $# = 0 ]
then
echo sintaxis: Int_Activar Int_nves str_usuario str_passwd str_equipo
echo ejemplos: 1 2 administrador 3451 $equipo
echo IMPORTANTE: cuando AutoLogonCount llegue a 0, activa el AutoAdminLogon a 0. Pero no borra los valores de DefaultPassword
return 2
fi
#echo la pass es $4
export temporal=/tmp/tmpregistry
cat >> $temporal << EOF
hive 2
cd \Microsoft\Windows NT\CurrentVersion\Winlogon
nv 1 AutoAdminLogon
ed AutoAdminLogon
$1
nv 1 AutoLogonCount
ed AutoLogonCount
$2
nv 1 DefaultUserName
ed DefaultUserName
$3
nv 1 DefaultDomainName
ed DefaultDomainName
$5
EOF
if [ "$4" == none ]
then
echo "debe aparecer done" $4
cat >> $temporal << EOF
dv DefaultPassword
EOF
else
cat >> $temporal << EOF
nv 1 DefaultPassword
ed DefaultPassword
$4
EOF
fi
}
function NTStatusRatonTeclado (){
if [ $# = 0 ]
then
echo sintaxis: Int-StatusRaton Int-StatusTeclado
echo ejemplos: int=1 activo int=4 desactivado
return 2
fi
cat >> $temporal << EOF
hive 1
cd \ControlSet001\Services\Mouclass
ed Start
$1
cd \ControlSet001\Services\Kbdclass
ed Start
$2
EOF
}
function NTRunOnceMachine () {
if [ $# = 0 ]
then
echo sintaxis: PathScripts idScripts
echo "ejemplo: c:\\\\WINDOSWS\\\\crearusuarios.bat scripts1"
echo "IMPORTANTE: el path debe llevar dos barras \\, pero como se deben 'escapar' debes poner cuatro \\\\"
return 2
fi
export temporal=/tmp/tmpregistry
cat >> $temporal << EOF
h 2
cd \Microsoft\Windows\CurrentVersion\RunOnce
nv 1 $2
ed $2
$1
EOF
}
function NTRunMachine () {
if [ $# = 0 ]
then
echo sintaxis: PathScripts idScripts
echo ejemplo: c:\\\\WINDOSWS\\\\crearusuarios.bat scripts1
echo IMPORTANTE: el path debe llevar dos barras \\, pero como se deben 'escapar' debes poner cuatro \\\\
return 2
fi
export temporal=/tmp/tmpregistry
cat >> $temporal << EOF
h 2
cd \Microsoft\Windows\CurrentVersion\Run
nv 1 $2
ed $2
$1
EOF
}
function NTRunUser () {
if [ $# = 0 ]
then
echo sintaxis: str_PathWINScripts str_idScripts Int_hive||\$usuario
echo ejemplo: c:\\\\WINDOSWS\\\\crearusuarios.bat scripts1 3
echo IMPORTANTE: el pathWIN debe llevar dos barras \\, pero como se deben 'escapar' debes poner cuatro \\\\
echo IMPORTANTE: el pathLinux si lleva espacios debe escaparse con una barra \\
echo IMPORTANTE Int_hive: 3 para el primer usuario, 4 para el segundo usuario
echo requiere export un HiveUser3=/mnt/windows/Document\ and\ Seeting\alumnmos\NTUSER.dat
return 2
fi
cat >> $temporal << EOF
h $3
cd \Software\Microsoft\Windows\CurrentVersion\Run
nv 1 $2
ed $2
$1
EOF
}
function NTPolUserOn () {
if [ $# = 0 ]
then
Msg "requiere LoadRegistryUser str_user1 str_user2..." orange
echo "sintaxis: Int_hive"
echo "ejemplo: NTPolUserOn 3"
echo "IMPORTANTE: la variable HiveUser3=/mnt/windows/Document/\ and/\ Seeting\alumnmos\NTUSER.dat"
return 2
fi
cp /var/EAC/admin/utilswin/Fondo.BMP ${particion}/WINDOWS/
cat >> $temporal << EOF
h $1
cd \Control Panel\Desktop
ed Wallpaper
C:\\WINDOWS\\fondo.bmp
cd \Software\Microsoft\Windows\CurrentVersion\Policies
nk Explorer
cd Explorer
nv 4 NoDesktop
ed NoDesktop
1
nv 4 NoSimpleStartMenu
ed NoSimpleStartMenu
1
nv 4 NoWindowsUpdate
ed NoWindowsUpdate
1
nv 4 NoSMConfigurePrograms
ed NoSMConfigurePrograms
1
nv 4 NoChangeStartMenu
ed NoChangeStartMenu
1
nv 4 Intellimenus
ed Intellimenus
1
nv 4 NoRun
ed NoRun
1
nv 4 NoRecentDocsHistory
ed NoRecentDocsHistory
1
EOF
}
function NTPolUserOFF () {
if [ $# = 0 ]
then
Msg "requiere LoadRegistryUser str_user1 str_user2..." orange
echo "sintaxis: Int_hive"
echo "ejemplo: NTPolUserOFF 3"
echo "IMPORTANTE: la variable HiveUser3=/mnt/windows/Document/\ and/\ Seeting\alumnmos\NTUSER.dat"
return 2
fi
cat >> $temporal << EOF
h $1
cd \Control Panel\Desktop
ed Wallpaper
C:\\WINDOWS\\web\\wallpaper\\Felicidad.bmp
cd \Software\Microsoft\Windows\CurrentVersion\
rdel Policies
nk Policies
1
EOF
}
function ogSetWindowsChkdisk() {
if [ $# = 0 ]
then
echo sintaxis: true|TRUE|0 false|false|1
echo ejemplos: int=0 desactivado int=1 activado
return 2
fi
case $1 in
0|true|TRUE)
valor="autocheck autochk *";;
1|false|FALSE)
valor="none";;
*)
return 0 ;;
esac
cat >> $TEMPhive << EOF
hive 1
cd \ControlSet001\Control\Session Manager
ed BootExecute
$valor
--n
EOF
}
### FASE DE PRUEBAS NO FUNCIONA
function NTStartRecovery () {
if [ $# = 0 ]
then
echo sintaxis: Int-Status
echo ejemplos: int=0 desactivado int=1 activado
return 2
fi
[ $1 = 0 ] && valor="none"
[ $1 = 1 ] && valor="00000000"
cat >> $TEMPhive << EOF
hive 2
#cd \Policies\Microsoft\Windows\WinRE
#ed DisableSetup
cd \Policies\Microsoft\Windows
nk WinRE
nv 4 DisableSetup
ed DisableSetup
$valor
--n
EOF
#Activado
#[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRE]
#"DisableSetup"=-
# Desactivado
#[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WinRE]
#"DisableSetup"=dword:00000000
}
function ogSchrootLinux () {
# Variables locales.
local PART DISK DIRCONF SCHROOTDEVICE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_partition" \
"$FUNCNAME 1 1 "
return
fi
# Error si no se reciben 2 parámetros.
[ $# == 2 ] || return $(ogRaiseError $OG_ERR_FORMAT; echo $?)
DISK=$1; PART=$2; DIRCONF="/etc/schroot"
VERSION=$(ogGetOsVersion $DISK $PART)
echo $VERSION | grep "Linux" || return $(ogRaiseError $OG_ERR_NOTOS "no es linux"; echo $?)
ogUnmount $DISK $PART || return $(ogRaiseError $OG_ERR_NOTOS "no es linux"; echo $?)
SCHROOTDEVICE=$(ogDiskToDev $DISK $PART)
rm ${DIRCONF}/mount-defaults
rm ${DIRCONF}/schroot.conf
cat >> ${DIRCONF}/mount-defaults << EOF
# <file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
/dev /dev none rw,bind 0 0
/dev/pts /dev/pts none rw,bind 0 0
/dev/shm /dev/shm none rw,bind 0 0
EOF
cat >> ${DIRCONF}/schroot.conf << EOF
[linux]
description=$VERSION
type=block-device
device=$SCHROOTDEVICE
EOF
schroot -c linux
schroot -end-sessiona --all-sessions
}
#/** @function ogDiskToRelativeDev: @brief Traduce los ID de discos o particiones EAC a ID Linux relativos, es decir 1 1 => sda1
#@param Admite 1 parametro: $1 int_numdisk
#@param Admite 2 parametro: $1 int_numdisk $2 int_partition
#@return Para 1 parametros traduce Discos Duros: Devuelve la ruta relativa linux del disco duro indicado con nomenclatura EAC.........ejemplo: IdPartition 1 => sda
#@return Para 2 parametros traduce Particiones: Devuelve la ruta relativa linux de la particion indicado con nomenclatura EAC........... ejemplo: IdPartition 2 1 => sdb1
#@warning No definidas
#@attention
#@note Notas sin especificar
#@version 0.1 - Integracion para Opengnsys - EAC: IdPartition en ATA.lib
#@author Antonio J. Doblas Viso. Universidad de Malaga
#@date 27/10/2008
#*/
function ogDiskToRelativeDev () {
if [ $# = 0 ]
then
Msg "Info: Traduce el identificador del dispositivo EAC a dispositivo linux \n" info
Msg "Sintaxis1: IdPartition int_disk -----------------Ejemplo1: IdPartition 1 -> sda " example
Msg "Sintaxis2: IdPartition int_disk int_partition --Ejemplo2: IdPartition 1 2 -> sda2 " example
return
fi
#PART="$(Disk|cut -f$1 -d' ')$2" # se comenta esta linea porque doxygen no reconoce la funcion disk y no crea los enlaces y referencias correctas.
PART=$(ogDiskToDev|cut -f$1 -d' ')$2
echo $PART | cut -f3 -d \/
}
#/** @function ogDeletePartitionsLabels: @brief Elimina la informacion que tiene el kernel del cliente og sobre los labels de los sistemas de archivos
#@param No requiere
#@return Nada
#@warning
#@attention Requisitos: comando interno linux rm
#@note
#@version 0.1 - Integracion para Opengnsys - EAC: DeletePartitionTable() en ATA.lib
#@author Antonio J. Doblas Viso. Universidad de Malaga
#@date 27/10/2008
#*/
function ogDeletePartitionsLabels () {
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME " \
"$FUNCNAME "
return
fi
rm /dev/disk/by-label/* # */ COMENTARIO OBLIGATORIO PARA DOXYGEN
}
#/** @function ogInfoCache: @brief muestra la informacion de la CACHE.
#@param sin parametros
#@return texto que se almacena en $IP.-InfoCache. punto_montaje, tama?oTotal, TamanioOcupado, TaminioLibre, imagenes dentro de la cahce
#@warning Salidas de errores no determinada
#@warning printf no soportado por busybox
#@attention
#@version 0.1 Date: 27/10/2008 Author Antonio J. Doblas Viso. Universidad de Malaga
#*/
function ogInfoCache ()
{
local info infoFilesystem infoSize infoUsed infoUsedPorcet infoMountedOn content
if ogMountCache
then
info=`df -h | grep $OGCAC`
infoFilesystem=`echo $info | cut -f1 -d" "`
infoSize=`echo $info | cut -f2 -d" "`
infoUsed=`echo $info | cut -f3 -d" "`
infoAvail=`echo $info | cut -f4 -d" "`
infoUsedPorcet=`echo $info | cut -f5 -d" "`
infoMountedOn=`echo $info | cut -f2 -d" "`
if `ls ${OGCAC}$OGIMG > /dev/null 2>&1`
then
cd ${OGCAC}${OPENGNSYS}
#content=`find images/ -type f -printf "%h/ %f %s \n"` busybox no soporta printf
content=`find images/ -type f`
cd /
echo $info
echo -ne $content
echo " "
#echo "$info" > ${OGLOG}/${IP}-InfoCache
#echo "$content" >> {$OGLOG}/${IP}-InfoCache
else
echo $info
#echo "$info" > {$OGLOG}/${IP}-InfoCache
fi
ogUnmountCache
else
echo " "
#echo " " > {$OGLOG}/${IP}-InfoCache
fi
}

View File

@ -1,320 +0,0 @@
#/**
#@file PostConfLib.py
#@brief Librería o clase PostConf
#@class PostConf
#@brief Funciones para la postconfiguración de sistemas operativos.
#@warning License: GNU GPLv3+
#*/
import os
import glob
import subprocess
import ogGlobals
import SystemLib
import FileSystemLib
import FileLib
import NetLib
import RegistryLib
import InventoryLib
import BootLib
#/**
# ogCleanOs int_ndisk int_nfilesys
#@brief Elimina los archivos que no son necesarios en el sistema operativo.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#@exception OG_ERR_PARTITION Partición desconocida o no accesible.
#@note Antes incluido en la funcion ogReduceFs
#@return (nada)
#*/ ##
#ogCleanOs (1, 1)
def ogCleanOs (disk, par):
t = InventoryLib.ogGetOsType (disk, par)
if 'Linux' == t:
BootLib.ogCleanLinuxDevices (disk, par)
mntdir = FileSystemLib.ogMount (disk, par)
for t in glob.glob ('{mntdir}/tmp/*'):
shutil.rmtree (t)
elif 'Windows' == t:
for f in 'pagefile.sys', 'hiberfil.sys', 'swapfile.sys':
p = FileLib.ogGetPath (src=f'{disk} {par}', file=f)
if p: FileLib.ogDeleteFile (disk=disk, par=par, file=f)
#/**
# ogInstallMiniSetup int_ndisk int_npartition str_filename [str_admuser str_admpassword bool_autologin [str_autouser str_autopassword] ]
#@brief Metafunción para instalar archivo que se ejecutará en el arranque de Windows.
#@see ogInstallFirstBoot ogInstallRunonce
#*/ ##
def ogInstallMiniSetup (disk, par, cmdfile, user=None, pwd=None, autologin=False, userauto=None, pwdauto=None):
if user:
ogInstallRunonce (disk, par, cmdfile, user, pwd, autologin, userauto, pwdauto)
else:
ogInstallFirstBoot (disk, par, cmdfile)
#/**
# ogInstallFirstBoot int_ndisk int_npartition str_filename
#@brief Crea unas claves del registro y el archivo cmd que se ejecutara en el primer arranque estando la maquina en un estado bloqueado
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_filename nombre del archivo .cmd a ejecutar en el arranque
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@note El archivo estará en system32 y será visible por el sistema.
#*/ ##
#ogInstallFirstBoot ('1', '1', 'filename.cmd')
def ogInstallFirstBoot (disk, par, cmdfile):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir: return
for i in ['winnt', 'windows']:
dir = FileLib.ogGetPath (file=f'{mntdir}/{i}/system32')
if dir: cmddir = dir
if not cmddir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{mntdir}/windows/system32')
return
full_cmdfile = f'{cmddir}/{cmdfile}'
bn = os.path.basename (full_cmdfile)
# Creamos el archivo cmd y creamos un par de comandos para que una vez acabe la
# postconfiguracion resetee el mini setup, sino lo haria en cada arranque.
with open (full_cmdfile, 'w') as fd:
fd.write (r'REG ADD HKLM\System\Setup /v SystemSetupInProgress /t REG_DWORD /d 0 /f' + '\n')
fd.write (r'REG ADD HKLM\System\Setup /v CmdLine /t REG_SZ /d "" /f' + '\n')
# Crear los valores de registro necesarios para que se haga la ejecución del .cmd al aranque.
RegistryLib.ogSetRegistryValue (mntdir, 'SYSTEM', r'\Setup\SystemSetupInProgress', 1)
RegistryLib.ogSetRegistryValue (mntdir, 'SYSTEM', r'\Setup\SetupType', 4)
#RegistryLib.ogDeleteRegistryValue (mntdir, 'SYSTEM', r'\Setup\CmdLine')
RegistryLib.ogAddRegistryValue (mntdir, 'SYSTEM', r'\Setup\CmdLine')
RegistryLib.ogSetRegistryValue (mntdir, 'SYSTEM', r'\Setup\CmdLine', f'cmd.exe /c {bn}')
#/**
# ogInstallRunonce int_ndisk int_npartition str_filename str_adm_user str_adm_password bool_autologin [str_auto_user str_auto_password]
#@brief Crea el archivo cmd que se ejecutara en el runonce de un usuario administrador
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_filename nombre del archivo .cmd a ejecutar en el arranque (estara en system32 y sera visible por el sistema)
#@param str_adm_user usuario administrador para hacer autologin y ejecutar el runonce
#@param str_adm_password password del usuario administrador
#@param bool_autologin si despues de la postconfiguracion queremos que la maquina haga autologin (0 o 1)
#@param str_auto_user Usuario con el que queremos que haga autologin despues de la postconfiguracion
#@param str_auto_password Password del usuario que hara autologin
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#*/ ##
#ogInstallRunonce ('1', '1', 'filename.cmd', 'administrator', 'passadmin', '1', 'userauto', 'pwdauto')
#ogInstallRunonce ('1', '1', 'filename.cmd', 'administrator', 'passadmin', '0')
def ogInstallRunonce (disk, par, cmdfile, user, pwd, autologin, userauto=None, pwdauto=None):
mountpoint = FileLib.ogGetPath (src=f'{disk} {par}', file='/')
for i in ['winnt', 'windows']:
dir = FileLib.ogGetPath (file=f'{mountpoint}/{i}/system32')
if dir: cmddir = dir
if not cmddir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{mountpoint}/Windows/System32')
return
full_cmdfile = f'{cmddir}/{cmdfile}'
if not autologin:
# Si no queremos hacer autologin despues de la postconfiguracion lo indicamos en las claves de registro
with open (full_cmdfile, 'w') as fd:
fd.write (r'DEL C:\ogboot.*' + '\n')
fd.write (r'REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon /t REG_SZ /d 0 /f' + '\n')
fd.write (r'REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName /t REG_SZ /d "" /f' + '\n')
fd.write (r'REG DELETE "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword /f' + '\n')
else:
# Si queremos hacer autologin despues de la postconfiguracion introducimos la informacion en las claves de registro
with open (full_cmdfile, 'w') as fd:
fd.write (r'DEL C:\ogboot.*' + '\n')
fd.write (r'REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon /t REG_SZ /d 1 /f' + '\n')
fd.write (fr'REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName /t REG_SZ /d "{userauto}" /f' + '\n')
fd.write (fr'REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword /t REG_SZ /d "{pwdauto}" /f' + '\n')
#Creamos las claves de registro necesarias para que meter el cmd en el runonce del usuario y este haga autologin
RegistryLib.ogAddRegistryValue (mountpoint, 'software', r'\Microsoft\Windows\CurrentVersion\RunOnce\PostConfiguracion')
RegistryLib.ogSetRegistryValue (mountpoint, 'software', r'\Microsoft\Windows\CurrentVersion\RunOnce\PostConfiguracion', rf'C:\windows\system32\{cmdfile}')
RegistryLib.ogAddRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoAdminLogon')
RegistryLib.ogSetRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoAdminLogon', 1)
RegistryLib.ogAddRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName')
RegistryLib.ogSetRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName', user)
RegistryLib.ogAddRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultDomainName')
RegistryLib.ogSetRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultDomainName', '.\\')
RegistryLib.ogAddRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultPassword')
RegistryLib.ogSetRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultPassword', pwd)
RegistryLib.ogDeleteRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\ForceAutoLockOnLogon')
RegistryLib.ogDeleteRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoLogonCount')
#/**
# ogAddCmd int_ndisk int_npartition str_filename str_commands
#@brief Añade comandos al cmd creado por ogInstalMiniSetup
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_filename nombre del fichero cmd (siempre se guardara en windows\system32\para que sea visible por el sistema
#@param str_commands comando o comandos que se añadiran al fichero
#@return
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar.
#*/ ##
#ogAddCmd ('1', '1', 'filename.cmd', 'command')
def ogAddCmd (disk, par, cmdfile, cmd):
mountpoint = FileSystemLib.ogMount (disk, par)
if not mountpoint: return
full_cmdfile = FileLib.ogGetPath (file=f'{mountpoint}/windows/system32') + '/' + cmdfile
if not full_cmdfile:
ogInstallMiniSetup (disk, par, cmdfile)
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{mountpoint}/windows/system32/{cmdfile}')
return
# Concatenamos el comando en el fichero de comandos
with open (full_cmdfile, 'a') as fd:
fd.write (cmd + '\n')
#/**
# ogDomainScript int_ndisk int_npartition str_domain str_user str_password
#@brief Crea un script .vbs para unir al dominio una maquina windows y el comando adequado en el archivo cmd creado por ogInstallMiniSetup
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_filename nombre del fichero cmd donde deberemos introducir el comando de ejecutar el script vbs
#@param str_domain dominio donde se quiere conectar
#@param str_user usuario con privilegios para unir al dominio
#@param str_password password del usuario con privilegios
#@return
#@exception OG_ERR_FORMAT Formato incorrecto.
#*/ ##
### PRUEBAS.
#/**
# ogConfigureOgagent int_ndisk int_filesys
#@brief Modifica el fichero de configuración del nuevo agente OGAent para sistemas operativos.
#@param int_ndisk nº de orden del disco
#@param int_filesys nº de orden del sistema de archivos
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero o dispositivo no encontrado.
#@exception OG_ERR_LOCKED Sistema de archivos bloqueado.
#*/ ##
def ogConfigureOgagent (disk, par):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir:
return
for agentdir in ['usr/share/OGAgent', 'Program Files/OGAgent', 'Program Files (x86)/OGAgent', 'Applications/OGAgent.app']:
cfgfile = FileLib.ogGetPath (file=f'{mntdir}/{agentdir}/cfg/ogagent.cfg')
if cfgfile: break
if not cfgfile:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'ogagent.cfg')
return
ogcore_scheme = 'https'
ogcore_ip = NetLib.ogGetServerIp()
ogcore_port = NetLib.ogGetServerPort()
cfgfile_patched = cfgfile + '.patched'
in_opengnsys_section = False
with open (cfgfile, 'r') as fdin:
with open (cfgfile_patched, 'w') as fdout:
while True:
lineout = linein = fdin.readline()
if not linein: break
if in_opengnsys_section:
if 'remote' == linein[0:6]:
lineout = f'remote={ogcore_scheme}://{ogcore_ip}:{ogcore_port}/opengnsys/rest/\n'
if '[' == linein[0:1]:
in_opengnsys_section = False
if '[opengnsys]' == linein[0:11]:
in_opengnsys_section = True
fdout.write (lineout)
os.rename (cfgfile_patched, cfgfile)
#/**
# ogInstallLaunchDaemon int_ndisk int_nfilesys str_filename
#@brief Instala archivo que se ejecutará en el arranque de macOS.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@param str_filename nombre del script
#return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero o directorio no encontrado.
#@npte Crea ficheros de configuración /Library/LaunchDaemon/es.opengnsys.Script.plist.
#*/ ##
### PRUEBAS.
#/**
# ogAddToLaunchDaemon int_ndisk int_nfilesys str_filename str_commands
#@brief Añade comandos al script creado por ogInstalLaunchDaemon.
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@param str_filename nombre del script (siempre se guardará en /usr/share para que sea visible por el sistema
#@param str_commands comando o comandos que se añadiran al fichero
#return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero o directorio no encontrado.
#*/ ##
#/**
# ogUninstallLinuxClient int_ndisk int_filesys
#@brief Desinstala el cliente OpenGnSys para sistemas operativos GNU/Linux.
#@param int_ndisk nº de orden del disco
#@param int_filesys nº de orden del sistema de archivos
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_PARTITION Paritición o sistema de archivos incorrectos.
#@exception OG_ERR_LOCKED Sistema de archivos bloqueado.
#*/ ##
def ogUninstallLinuxClient (disk, par):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir:
return
for f in [
f'{mntdir}/usr/sbin/ogAdmLnxClient',
f'{mntdir}/sbin/ogAdmLnxClient',
f'{mntdir}/usr/local/sbin/ogAdmLnxClient',
f'{mntdir}/etc/ogAdmLnxClient.cfg',
f'{mntdir}/usr/local/etc/ogAdmLnxClient.cfg',
]:
try: os.remove (f)
except: pass
for f in [
f'{mntdir}/etc/rc.local',
f'{mntdir}/etc/rc.d/rc.local',
f'{mntdir}/usr/local/etc/rc.local',
f'{mntdir}/usr/local/etc/rc.d/rc.local',
]:
subprocess.run (['sed', '-i', '-e', '/ogAdmLnxClient/ d', f], stderr=subprocess.DEVNULL)
#/**
# ogUninstallWindowsClient int_ndisk int_filesys str_filename
#@brief Desinstala el cliente OpenGnSys para sistemas operativos Windows.
#@param int_ndisk nº de orden del disco
#@param int_npartition nº de orden de la partición
#@param str_filename nombre del fichero cmd donde deberemos introducir el comando de ejecutar el script vbs
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_PARTITION Paritición o sistema de archivos incorrectos.
#@exception OG_ERR_LOCKED Sistema de archivos bloqueado.
#*/ ##
#ogUninstallWindowsClient ('1', '1', 'filename.cmd')
def ogUninstallWindowsClient (disk, par, cmdfile):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir: return
exe1 = FileLib.ogGetPath (file=f'{mntdir}/windows/ogAdmWinClient.exe')
exe2 = FileLib.ogGetPath (file=f'{mntdir}/winnt/ogAdmWinClient.exe')
if exe1 or exe2:
ogAddCmd (disk, par, cmdfile, 'ogAdmWinClient -remove')
ogAddCmd (disk, par, cmdfile, r'DEL C:\Windows\ogAdmWinClient.exe')
ogAddCmd (disk, par, cmdfile, r'DEL C:\Winnt\ogAdmWinClient.exe')

File diff suppressed because it is too large Load Diff

View File

@ -1,915 +0,0 @@
#!/usr/bin/python3
import subprocess
import re
import json
import os.path
import shutil
import ogGlobals
import SystemLib
import ImageLib
import FileSystemLib
import StringLib
import NetLib
import DiskLib
import FileLib
import CacheLib
#/**
#@file ProtocolLib.py
#@brief Librería o clase Protocol
#@class Protocol
#@brief Funciones para transmisión de datos
#@warning License: GNU GPLv3+
#*/
##################### FUNCIONES UNICAST ################
#/**
# ogUcastSyntax
#@brief Función para generar la instrucción de transferencia de datos unicast
#@param 1 Tipo de operación [ SENDPARTITION RECEIVERPARTITION SENDFILE RECEIVERFILE ]
#@param 2 Sesion Unicast
#@param 3 Dispositivo (opción PARTITION) o fichero(opción FILE) que será enviado.
#@param 4 Tools de clonación (opcion PARTITION)
#@param 5 Tools de compresion (opcion PARTITION)
#@return instrucción para ser ejecutada.
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_UCASTSYNTAXT formato de la sesion unicast incorrecta.
#@note Requisitos: mbuffer
#@todo: controlar que mbuffer esta disponible para los clientes.
#*/ ##
#ogUcastSyntax SENDPARTITION 8000:172.17.36.11:172.17.36.12 device tool level
#ogUcastSyntax RECEIVERPARTITION 8000:172.17.36.249 device tool level
#ogUcastSyntax SENDFILE 8000:172.17.36.11:172.17.36.12 file
#ogUcastSyntax RECEIVERFILE 8000:172.17.36.249 file
def ogUcastSyntax (op, sess, file=None, device=None, tool=None, level=None):
if 'SENDPARTITION' == op or 'RECEIVERPARTITION' == op:
if device is None:
raise TypeError ('missing required argument: "device"')
if tool is None:
raise TypeError ('missing required argument: "tool"')
if tool.lower() not in ['partclone', 'partimage', 'ntfsclone']:
raise TypeError (f'argument "tool" has unsupported value "{tool}"')
if level is None:
raise TypeError ('missing required argument: "level"')
if level.lower() not in ['lzop', 'gzip', '0', '1']:
raise TypeError (f'argument "level" has unsupported value "{level}"')
elif 'SENDFILE' == op or 'RECEIVERFILE' == op:
if file is None:
raise TypeError ('missing required argument: "file"')
else:
raise TypeError ('first parameter should match (SEND|RECEIVER)(PARTITION|FILE), eg. "SENDFILE"')
if 'SEND' in op: mode = 'server'
else: mode = 'client'
session = sess.split (':')
portbase = int (session[0])
if portbase not in range (8000, 8006):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession portbase {portbase}') ## || PERROR=3
return
if 'server' == mode:
address = ''
for i in range (1, len (session)):
address += f' -O {session[i]}:{portbase}'
else:
address = f'{session[1]}:{portbase}'
if 'SENDPARTITION' == op:
syn = ImageLib.ogCreateImageSyntax (device, ' ', tool, level)
## REQUIRES package mbuffer to be installed!!
## otherwise, param2 in ImageLib.ogCreateImageSyntax() is not '| mbuffer' but empty
## and then parts[2] is out of range
parts = syn.split ('|')
prog1 = f'{parts[0]}|{parts[2]}'.strip()
prog1 = prog1.replace ('>', '').strip()
return f'{prog1} | mbuffer {address}'
elif 'RECEIVERPARTITION' == op:
syn = ImageLib.ogRestoreImageSyntax (' ', device, tool, level)
parts = syn.split ('|')
compressor = parts[0].strip()
tools = parts[-1].strip()
return f'mbuffer -I {address} | {compressor} | {tools}'
elif 'SENDFILE' == op:
return f'mbuffer {address} -i {file}'
elif 'RECEIVERFILE' == op:
return f'mbuffer -I {address} -i {file}'
else:
pass ## shouldn't happen
#/**
# ogUcastSendPartition
#@brief Función para enviar el contenido de una partición a multiples particiones remotas usando UNICAST.
#@param 1 disk
#@param 2 partition
#@param 3 sesionUcast
#@param 4 tool image
#@param 5 tool compresor
#@return
#@exception $OG_ERR_FORMAT
#@exception $OG_ERR_UCASTSENDPARTITION
#@note
#@todo: ogIsLocked siempre devuelve 1
#*/ ##
def ogUcastSendPartition (disk, par, sess, tool, level):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return None
FileSystemLib.ogUnmount (disk, par)
cmd = ogUcastSyntax ('SENDPARTITION', sess, device=PART, tool=tool, level=level)
if not cmd: return None
try:
subprocess.run (cmd, shell=True, check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_UCASTSENDPARTITION, ' ')
return None
#/**
# ogUcastReceiverPartition
#@brief Función para recibir directamente en la partición el contenido de un fichero imagen remoto enviado por UNICAST.
#@param 1 disk
#@param 2 partition
#@param 3 session unicast
#@param 4 tool image
#@param 5 tool compresor
#@return
#@exception OG_ERR_FORMAT
#@exception OG_ERR_UCASTRECEIVERPARTITION
#@note
#@todo:
#*/ ##
def ogUcastReceiverPartition (disk, par, sess, tool, level):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return None
FileSystemLib.ogUnmount (disk, par)
cmd = ogUcastSyntax ('RECEIVERPARTITION', sess, device=PART, tool=tool, level=level)
if not cmd: return None
try:
subprocess.run (cmd, shell=True, check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_UCASTRECEIVERPARTITION, ' ')
return None
#/**
# ogUcastSendFile [ str_repo | int_ndisk int_npart ] /Relative_path_file sessionMulticast
#@brief Envía un fichero por unicast ORIGEN(fichero) DESTINO(sessionmulticast)
#@param (2 parámetros) $1 path_aboluto_fichero $2 sesionMcast
#@param (3 parámetros) $1 Contenedor REPO|CACHE $2 path_absoluto_fichero $3 sesionMulticast
#@param (4 parámetros) $1 disk $2 particion $3 path_absoluto_fichero $4 sesionMulticast
#@return
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception $OG_ERR_NOTFOUND
#@exception OG_ERR_UCASTSENDFILE
#@note Requisitos:
#*/ ##
#
## TODO esta función es idéntica a ogMcastSendFile pero con s/Ucast/Mcast/;
#ogUcastSendFile ([str_REPOSITORY] [int_ndisk int_npart] /Relative_path_file sesionMcast(puerto:ip:ip:ip)" \
#ogUcastSendFile (disk=1, par=1, file='/aula1/winxp.img', sess='8000:172.17.36.11:172.17.36.12')
#ogUcastSendFile (container='REPO', file='/aula1/ubuntu.iso', sess='sesionUcast')
#ogUcastSendFile (container='CACHE', file='/aula1/winxp.img', sess='sesionUcast')
#ogUcastSendFile ( file='/opt/opengnsys/images/aula1/hd500.vmx', sess='sesionUcast')
def ogUcastSendFile (disk=None, par=None, container=None, file=None, sess=None):
if file is None:
raise TypeError ('missing required argument: "file"')
if sess is None:
raise TypeError ('missing required argument: "sess"')
if container is not None:
if disk is None and par is None:
## we were given container=
source = FileLib.ogGetPath (src=container, file=file)
dev_err = f'{container} {file}'
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
source = FileLib.ogGetPath (src=f'{disk} {par}', file=file)
dev_err = f'{disk} {par} {file}'
elif disk is None and par is None:
## we were given nothing
source = FileLib.ogGetPath (file=file)
dev_err = file
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
if not source:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found')
return
path2 = FileLib.ogGetPath (file=source)
if not path2:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found')
return
cmd = ogUcastSyntax ('SENDFILE', sess, file=source)
if not cmd: return None
try:
subprocess.run (cmd, shell=True, check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_UCASTSENDFILE, ' ')
return None
def _clientip():
ipas = subprocess.run (['ip', '-json', 'address', 'show', 'up'], capture_output=True, text=True).stdout
ipasj = json.loads (ipas)
addresses = []
for e in ipasj:
if 'lo' == e['ifname']: continue
if 'addr_info' not in e: continue
addrs = e['addr_info']
for a in addrs:
if 'inet' != a['family']: continue
addresses.append ({ 'local': a['local'], 'prefixlen': a['prefixlen'] })
return addresses
def _binary_ip (ip):
for l in subprocess.run (['ipcalc', '--nocolor', ip ], capture_output=True, text=True).stdout.splitlines():
if 'Address' not in l: continue
match = re.search (r'^(Address:)\s+(\S+)\s+(.*$)', l).group(3).replace (' ', '').replace ('.', '')
break
return match
#/**
# ogMcastSyntax
#@brief Función para generar la instrucción de ejucción la transferencia de datos multicast
#@param 1 Tipo de operación [ SENDPARTITION RECEIVERPARTITION SENDFILE RECEIVERFILE ]
#@param 2 Sesión Mulicast
#@param 3 Dispositivo (opción PARTITION) o fichero(opción FILE) que será enviado.
#@param 4 Tools de clonación (opcion PARTITION)
#@param 5 Tools de compresion (opcion PARTITION)
#@return instrucción para ser ejecutada.
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTEXEC
#@exception OG_ERR_MCASTSYNTAXT
#@note Requisitos: upd-cast 2009 o superior
#@todo localvar check versionudp
#*/ ##
#
#ogMcastSyntax SENDPARTITION 9000:full-duplex|half-duplex|broadcast:239.194.17.36:80M:50:60 device tools level
#ogMcastSyntax RECEIVERPARTITION 9000 device tools level
#ogMcastSyntax RECEIVERPARTITION 9000:172.17.88.161:40:120 device tools level
#ogMcastSyntax SENDFILE 9000:full-duplex|half-duplex|broadcast:239.194.17.36:80M:50:60 file
#ogMcastSyntax RECEIVERFILE 9000 file
#ogMcastSyntax RECEIVERFILE 9000:172.17.88.161:40:120 file
def ogMcastSyntax (op, sess, file=None, device=None, tool=None, level=None):
if 'SENDPARTITION' == op or 'RECEIVERPARTITION' == op:
if device is None:
raise TypeError ('missing required argument: "device"')
if tool is None:
raise TypeError ('missing required argument: "tool"')
if tool.lower() not in ['partclone', 'partimage', 'ntfsclone']:
raise TypeError (f'argument "tool" has unsupported value "{tool}"')
if level is None:
raise TypeError ('missing required argument: "level"')
if level.lower() not in ['lzop', 'gzip', '0', '1']:
raise TypeError (f'argument "level" has unsupported value "{level}"')
elif 'SENDFILE' == op or 'RECEIVERFILE' == op:
if file is None:
raise TypeError ('missing required argument: "file"')
else:
raise TypeError ('first parameter should match (SEND|RECEIVER)(PARTITION|FILE), eg. "SENDFILE"')
if 'SEND' in op: mode = 'server'
else: mode = 'client'
try:
isudpcast = subprocess.run (['udp-receiver', '--help'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTEXEC, 'upd-cast no existe')
return
session = sess.split (':')
PERROR = 0
if 'server' == mode:
if 6 != len (session):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'parametros session de servidor multicast no completa')
PERROR = 2
elif 'client' == mode:
if 4 < len (session):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'parametros session de cliente multicast no completa')
PERROR = 2
mbuffer = " --pipe 'mbuffer -q -m 20M' "
portbase = int (session[0])
if portbase not in range (9000, 9100, 2):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession portbase {portbase}')
PERROR = 3
if 'server' == mode:
method, address, bitrate, nclients, maxtime = session[1:]
if method.lower() not in ['full-duplex', 'half-duplex', 'broadcast']:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession method {method}')
PERROR = 4
if not StringLib.ogCheckIpAddress (address):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession address {address}')
PERROR = 5
## the original regex has a backslash: ^[0-9]{1,3}\M$
## not sure why
if not re.search (r'^[0-9]{1,3}M$', bitrate):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession bitrate {bitrate}')
PERROR = 6
if not re.search (r'^[0-9]{1,10}$', nclients):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession nclients {nclients}')
PERROR = 7
if not re.search (r'^[0-9]{1,10}$', maxtime):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession maxtime {maxtime}')
PERROR = 8
cerror = '8x8/128'
syntaxserver = f'udp-sender {mbuffer} --nokbd --portbase {portbase} --{method} --mcast-data-address {address} --fec {cerror} --max-bitrate {bitrate} --ttl 16 --min-clients {nclients} --max-wait {maxtime} --autostart {maxtime} --log /tmp/mcast.log'
if PERROR:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_MCASTSYNTAXT, f' {PERROR}')
return
if 'client' == mode:
other = session[1:]
serveraddress = other[0] if len (other) > 0 else ''
starttimeout = other[1] if len (other) > 1 else ''
receivertimeout = other[2] if len (other) > 2 else ''
## serveraddres
if StringLib.ogCheckIpAddress (serveraddress):
serveraddress = f' --mcast-rdv-address {serveraddress}'
else:
repoip = NetLib.ogGetRepoIp()
clientip = _clientip()
if 1 != len (clientip):
raise Exception ('more than one local IP address found')
c = clientip[0]
clientip = c['local']
mascara = c['prefixlen']
ripbt = _binary_ip (repoip)
ipbt = _binary_ip (clientip)
reposubred = ripbt[0:mascara]
clientsubred = ipbt[0:mascara]
if reposubred == clientsubred: serveraddress = ' '
else: serveraddress = f' --mcast-rdv-address {repoip}'
## starttimeout
if re.search (r'^[0-9]{1,10}$', starttimeout):
if 0 == starttimeout: starttimeout = ' '
else: starttimeout = f' --start-timeout {starttimeout}'
else:
starttimeout = f' --start-timeout {ogGlobals.MCASTERRORSESSION}'
if 'start-timeout' not in isudpcast: starttimeout = ' '
## receivertimeout
if re.search (r'^[0-9]{1,10}$', receivertimeout):
if 0 == receivertimeout: receivertimeout = ' '
else: receivertimeout = f' --receive-timeout {receivertimeout}'
else:
receivertimeout = f' --receive-timeout {ogGlobals.MCASTWAIT}'
if 'receive-timeout' not in isudpcast: receivertimeout = ' '
syntaxclient = f'udp-receiver {mbuffer} --portbase {portbase} {serveraddress} {starttimeout} {receivertimeout} --log /tmp/mcast.log'
if 'SENDPARTITION' == op:
syn = ImageLib.ogCreateImageSyntax (device, ' ', tool, level)
## REQUIRES package mbuffer to be installed!!
## otherwise, param2 in ImageLib.ogCreateImageSyntax() is not '| mbuffer' but empty
## and then parts[2] is out of range
parts = syn.split ('|')
prog1 = f'{parts[0]}|{parts[2]}'.strip()
prog1 = prog1.replace ('>', '').strip()
return f'{prog1} | {syntaxserver}'
elif 'RECEIVERPARTITION' == op:
syn = ImageLib.ogRestoreImageSyntax (' ', device, tool, level)
parts = syn.split ('|')
compressor = parts[0].strip()
tools = parts[-1].strip()
return f'{syntaxclient} | {compressor} | {tools} '
elif 'SENDFILE' == op:
return f'{syntaxserver} --file {file}'
elif 'RECEIVERFILE' == op:
return f'{syntaxclient} --file {file}'
else:
raise Exception (f'unknown op ({op})--this should not happen')
#/**
# ogMcastSendFile [ str_repo | int_ndisk int_npart ] /Relative_path_file sessionMulticast
#@brief Envía un fichero por multicast ORIGEN(fichero) DESTINO(sessionmulticast)
#@param (2 parámetros) $1 path_aboluto_fichero $2 sesionMcast
#@param (3 parámetros) $1 Contenedor REPO|CACHE $2 path_absoluto_fichero $3 sesionMulticast
#@param (4 parámetros) $1 disk $2 particion $3 path_absoluto_fichero $4 sesionMulticast
#@return
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception $OG_ERR_NOTFOUND
#@exception OG_ERR_MCASTSENDFILE
#*/ ##
#
#ogMcastSendFile [str_REPOSITORY] [int_ndisk int_npart] /Relative_path_file sesionMcast" \
#ogMcastSendFile (disk=1, par=1, file='/aula1/winxp.img', sess='sesionMcast')
#ogMcastSendFile (container='REPO', file='/aula1/ubuntu.iso', sess='sesionMcast')
#ogMcastSendFile (container='CACHE', file='/aula1/winxp.img', sess='sesionMcast')
#ogMcastSendFile ( file='/opt/opengnsys/images/aula1/hd500.vmx', sess='sesionMcast')
def ogMcastSendFile (disk=None, par=None, container=None, file=None, sess=None):
if file is None:
raise TypeError ('missing required argument: "file"')
if sess is None:
raise TypeError ('missing required argument: "sess"')
if container is not None:
if disk is None and par is None:
## we were given container=
source = FileLib.ogGetPath (src=container, file=file)
dev_err = f'{container} {file}'
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
source = FileLib.ogGetPath (src=f'{disk} {par}', file=file)
dev_err = f'{disk} {par} {file}'
elif disk is None and par is None:
## we were given nothing
source = FileLib.ogGetPath (file=file)
dev_err = file
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
if not source:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found')
return
path2 = FileLib.ogGetPath (file=source)
if not path2:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found')
return
cmd = ogMcastSyntax ('SENDFILE', sess, file=source)
if not cmd: return None
try:
subprocess.run (cmd, shell=True, check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_MCASTSENDFILE, ' ')
return None
#/**
# ogMcastReceiverFile sesion Multicast [ str_repo | int_ndisk int_npart ] /Relative_path_file
#@brief Recibe un fichero multicast ORIGEN(sesionmulticast) DESTINO(fichero)
#@param (2 parámetros) $1 sesionMcastCLIENT $2 path_aboluto_fichero_destino
#@param (3 parámetros) $1 sesionMcastCLIENT $2 Contenedor REPO|CACHE $3 path_absoluto_fichero_destino
#@param (4 parámetros) $1 sesionMcastCLIENT $2 disk $3 particion $4 path_absoluto_fichero_destino
#@return
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception $OG_ERR_MCASTRECEIVERFILE
#@note Requisitos:
#*/ ##
#
#ogMcastReceiverFile ([ str_portMcast] [ [Relative_path_file] | [str_REPOSITORY path_file] | [int_ndisk int_npart path_file ] ]" \
#ogMcastReceiverFile ( file='/PS1_PH1.img', sess='9000')
#ogMcastReceiverFile (container='CACHE', file='/aula1/PS2_PH4.img', sess='9000')
#ogMcastReceiverFile (disk=1, par=1, file='/isos/linux.iso', sess='9000')
def ogMcastReceiverFile (disk=None, par=None, container=None, file=None, sess=None):
if file is None:
raise TypeError ('missing required argument: "file"')
if sess is None:
raise TypeError ('missing required argument: "sess"')
if container is not None:
if disk is None and par is None:
## we were given container=
targetdir = FileLib.ogGetParentPath (src=container, file=file)
dev_err = f'{container} {file}'
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
targetdir = FileLib.ogGetParentPath (src=f'{disk} {par}', file=file)
dev_err = f'{disk} {par} {file}'
elif disk is None and par is None:
## we were given nothing
targetdir = FileLib.ogGetParentPath (file=file)
dev_err = file
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
if not targetdir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'target directory {targetdir} not found')
return
targetfile = os.path.basename (file)
cmd = ogMcastSyntax ('RECEIVERFILE', sess, file=os.path.join (targetdir, targetfile))
if not cmd: return None
try:
subprocess.run (cmd, shell=True, check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_MCASTRECEIVERFILE, targetfile)
return None
#/**
# ogMcastSendPartition
#@brief Función para enviar el contenido de una partición a multiples particiones remotas.
#@param 1 disk
#@param 2 partition
#@param 3 session multicast
#@param 4 tool clone
#@param 5 tool compressor
#@return
#@exception OG_ERR_FORMAT
#@exception OG_ERR_MCASTSENDPARTITION
#@note
#@todo: ogIsLocked siempre devuelve 1. crear ticket
#*/ ##
#ogMcastSendPartition (disk, par, SessionMulticastSERVER, tools, compresor)
#ogMcastSendPartition (1, 1, '9000:full-duplex:239.194.37.31:50M:20:2', 'partclone', 'lzop')
def ogMcastSendPartition (disk, par, sess, tool, compressor):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return
FileSystemLib.ogUnmount (disk, par)
cmd = ogMcastSyntax ('SENDPARTITION', sess, device=PART, tool=tool, level=compressor)
if not cmd: return None
try:
subprocess.run (cmd, shell=True, check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_MCASTSENDPARTITION, ' ')
return None
#/**
# ogMcastReceiverPartition
#@brief Función para recibir directamente en la partición el contenido de un fichero imagen remoto enviado por multicast.
#@param 1 disk
#@param 2 partition
#@param 3 session multicast
#@param 4 tool clone
#@param 5 tool compressor
#@return
#@exception $OG_ERR_FORMAT
#*/ ##
def ogMcastReceiverPartition (disk, par, sess, tool, compressor):
PART = DiskLib.ogDiskToDev (disk, par)
if not PART: return
FileSystemLib.ogUnmount (disk, par)
cmd = ogMcastSyntax ('RECEIVERPARTITION', sess, device=PART, tool=tool, level=compressor)
if not cmd: return None
try:
subprocess.run (cmd, shell=True, check=True)
except subprocess.CalledProcessError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_MCASTRECEIVERPARTITION, ' ') ## original code has OG_ERR_MCASTSENDPARTITION
return None
#/**
# ogMcastRequest
#@brief Función temporal para solicitar al ogRepoAux el envio de un fichero por multicast
#@param 1 Fichero a enviar ubicado en el REPO. puede ser ruta absoluta o relatica a /opt/opengnsys/images
#@param 2 PROTOOPT opciones protocolo multicast
#*/ ##
## now ogCore takes this responsibility
def ogMcastRequest (img, proto):
return True
##########################################
############## funciones torrent
#/**
# ogTorrentStart [ str_repo | int_ndisk int_npart ] Relative_path_file.torrent | SessionProtocol
#@brief Función iniciar P2P - requiere un tracker para todos los modos, y un seeder para los modos peer y leecher y los ficheros .torrent.
#@param str_pathDirectory str_Relative_path_file
#@param int_disk int_partition str_Relative_path_file
#@param str_REPOSITORY(CACHE - LOCAL) str_Relative_path_file
#@param (2 parámetros) $1 path_aboluto_fichero_torrent $2 Parametros_Session_Torrent
#@param (3 parámetros) $1 Contenedor CACHE $2 path_absoluto_fichero_Torrent $3 Parametros_Session_Torrent
#@param (4 parámetros) $1 disk $2 particion $3 path_absoluto_fichero_Torrent 4$ Parametros_Session_Torrent
#@return
#@note protocoloTORRENT=mode:time mode=seeder -> Dejar el equipo seedeando hasta que transcurra el tiempo indicado o un kill desde consola, mode=peer -> seedear mientras descarga mode=leecher -> NO seedear mientras descarga time tiempo que una vez descargada la imagen queremos dejar al cliente como seeder.
#*/ ##
#ogTorrentStart ( torrentfile='/opt/opengnsys/cache/linux.iso', torrentsess='peer:60')
#ogTorrentStart (container='CACHE', torrentfile='/PS1_PH1.img.torrent', torrentsess='seeder:10000')
#ogTorrentStart (disk=1, par=1, torrentfile='/linux.iso.torrent', torrentsess='leecher:60')
def ogTorrentStart (disk=None, par=None, container=None, torrentfile=None, torrentsess=None):
if torrentfile is None:
raise TypeError ('missing required argument: "torrentfile"')
if torrentsess is None:
raise TypeError ('missing required argument: "torrentsess"')
if container is not None:
if disk is None and par is None:
## we were given container=
if 'CACHE' != container.upper():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'La descarga torrent solo se hace desde local, copia el torrent a la cache y realiza la operación desde esa ubicación')
return None
source = FileLib.ogGetPath (src=container, file=torrentfile)
dev_err = f'{container} {torrentfile}'
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
source = FileLib.ogGetPath (src=f'{disk} {par}', file=torrentfile)
dev_err = f'{disk} {par} {torrentfile}'
elif disk is None and par is None:
## we were given nothing
if torrentfile.startswith ('/opt/opengnsys/images'):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'La descarga torrent solo se hace desde local, copia el torrent a la cache y realiza la operación desde esa ubicación')
return None
source = FileLib.ogGetPath (file=torrentfile)
dev_err = torrentfile
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
if not source:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or torrentfile {dev_err} not found')
return
if subprocess.run (['ctorrent', '-x', source]).returncode:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, '')
return None
target = re.sub (r'\.torrent$', '', source)
dirsource = FileLib.ogGetParentPath (file=source)
ERROR = None
sess = torrentsess.split (':')
if 2 != len (sess):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'parametros session Torrent no completa: modo:tiempo')
return None
mode = sess[0].lower()
if mode not in ['seeder', 'peer', 'leecher']:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'valor modo Torrent no valido {sess[0]}')
return None
time = sess[1]
if not re.search (r'^[0-9]{1,10}$', time):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'valor tiempo no valido {sess[1]}')
return None
time = int (time)
OPTION = None
cwd = os.getcwd()
# si No fichero .bf, y Si fichero destino imagen ya descargada y su chequeo fue comprobado en su descarga inicial.
if not os.path.exists (f'{source}.bf') and os.path.exists (target):
print ('imagen ya descargada')
if 'seeder' != mode: return 'success' ## return any true value
print ('MODE seeder ctorrent')
os.chdir (dirsource)
subprocess.run (['timeout', '--signal', 'INT', time, 'ctorrent', '-f', source])
os.chdir (cwd)
return 'success'
#Si no existe bf ni fichero destino descarga inicial.
if not os.path.exists (f'{source}.bf') and not os.path.exists (target):
print ('descarga inicial')
OPTION = 'DOWNLOAD'
# Si fichero bf descarga anterior no completada -.
if os.path.exists (f'{source}.bf') and os.path.exists (target):
print ('Continuar con Descargar inicial no terminada.')
OPTION = 'DOWNLOAD'
if 'DOWNLOAD' != OPTION: return 'success'
os.chdir (dirsource)
if 'peer' == mode:
print ('Donwloading Torrent as peer')
# Creamos el fichero de resumen por defecto
open (f'{source}.bf', 'w').close()
# ctorrent controla otro fichero -b ${SOURCE}.bfog
subprocess.run (['ctorrent', '-f', '-c', '-X', f'sleep {time}; kill -2 $(pidof ctorrent)', '-C', '100', source, '-s', target, '-b', f'{source}.bfog'])
elif 'leecher' == mode:
print ('Donwloading Torrent as leecher')
subprocess.run (['ctorrent', '${SOURCE}', '-X', 'sleep 30; kill -2 $(pidof ctorrent)', '-C', '100', '-U', '0'])
elif 'seeder' == mode:
print ('MODE seeder ctorrent')
# Creamos el fichero de resumen por defecto
open (f'{source}.bf', 'w').close()
# ctorrent controla otro fichero -b ${SOURCE}.bfog
subprocess.run (['ctorrent', '-f', '-c', '-X', f'sleep {time}; kill -2 $(pidof ctorrent)', '-C', '100', source, '-s', target, '-b', f'{source}.bfog'])
else:
print ('this should not happen')
return None
os.chdir (cwd)
#/**
# ogCreateTorrent [ str_repo | int_ndisk int_npart ] Relative_path_file
#@brief Función para crear el fichero torrent.
#@param str_pathDirectory str_Relative_path_file
#@param int_disk int_partition str_Relative_path_file
#@param str_REPOSITORY(CACHE - LOCAL) str_Relative_path_file
#@return
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo.
#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar.
#@exception OG_ERR_NOTOS La partición no tiene instalado un sistema operativo.
#*/ ##
#ogCreateTorrent ([str_REPOSITORY] [int_ndisk int_npart] Relative_path_file IpBttrack)
#ogCreateTorrent (disk=1, par=1, file='/aula1/winxp', ip_bttrack='10.1.15.23')
#ogCreateTorrent (container='REPO', file='/aula1/winxp', ip_bttrack='10.1.15.45')
#ogCreateTorrent (container='CACHE', file='/aula1/winxp', ip_bttrack='10.1.15.45')
def ogCreateTorrent (disk=None, par=None, container=None, file=None, ip_bttrack=None):
if file is None:
raise TypeError ('missing required argument: "file"')
if ip_bttrack is None:
raise TypeError ('missing required argument: "ip_bttrack"')
from_cache = False
if container is not None:
if disk is None and par is None:
## we were given container=
if 'CACHE' == container: from_cache = True
ext = ImageLib.ogGetImageType (container, file)
if ext is None:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{container} {file}')
return
f = f'{file}.{ext}'
source = FileLib.ogGetPath (src=container, file=f)
else:
raise TypeError ('argument "container" can be specified along neither "disk" nor "par"')
else:
if disk is not None and par is not None:
## we were given disk= par=
f = f'{file}.img'
source = FileLib.ogGetPath (src=f'{disk} {par}', file=f)
elif disk is None and par is None:
## we were given nothing
f = f'{file}.img'
source = FileLib.ogGetPath (file=f)
else:
raise TypeError ('if one of "disk" and "par" are specified, then both must be')
if not source:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, '')
return
if from_cache:
if not CacheLib.ogFindCache():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, "CACHE")
#return None
if os.path.exists (f'{source}.torrent'):
os.rename (f'{source}.torrent', f'{source}.torrent.ant')
print ('Esperamos que se refresque el servidor')
time.sleep (20)
cwd = os.getcwd()
os.chdir (os.path.dirname (source))
print (f'ctorrent -t {os.path.basename (source)} -u http://{ip_bttrack}:6969/announce -s {source}.torrent')
subprocess.run (['ctorrent', '-t', os.path.basename (source), '-u', f'http://{ip_bttrack}:6969/announce', '-s', f'{source}.torrent'])
os.chdir (cwd)
#/**
# ogUpdateCacheIsNecesary [ str_repo ] Relative_path_file_OGIMG_with_/
#@brief Comprueba que el fichero que se desea almacenar en la cache del cliente, no esta.
#@param 1 str_REPO
#@param 2 str_Relative_path_file_OGIMG_with_/
#@param 3 md5 to check: use full to check download image torrent
#@return True cache sin imagen, SI es necesario actualizar el fichero.
#@return False imagen en la cache, NO es necesario actualizar el fichero
#@return None error de sintaxis (TODO)
#@note
#@todo: Proceso en el caso de que el fichero tenga el mismo nombre, pero su contenido sea distinto.
#@todo: Se dejan mensajes mientras se confirma su funcionamiento.
#*/ ##
#ogUpdateCacheIsNecesary ('REPO', '/PS1_PH1.img', 'UNICAST')
#ogUpdateCacheIsNecesary ('REPO', '/ogclient.sqfs', 'FULL')
#ogUpdateCacheIsNecesary ('REPO', '/ogclient.sqfs', 'TORRENT')
def ogUpdateCacheIsNecesary (repo, file, proto):
if not CacheLib.ogFindCache():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTCACHE, '')
return None
if repo.lower() != 'repo':
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f' {repo} {file}')
return None
filesource = FileLib.ogGetPath (src=repo, file=file)
if not filesource:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f' {repo} {file}')
return None
# paso 1. si no existe la imagen, confirmar que es necesario actualizar la cache.
filetarget = FileLib.ogGetPath (src='CACHE', file=file)
if not filetarget:
# borramos el fichero bf del torrent, en el caso de que se hubiese quedado de algun proceso fallido
if FileLib.ogGetPath (src='CACHE', file=f'/{file}.torrent.bf'): ogDeleteFile (container='CACHE', file=f'{file}.torrent.bf')
if FileLib.ogGetPath (src='CACHE', file=f'/{file}.sum'): ogDeleteFile (container='CACHE', file=f'{file}.sum')
if FileLib.ogGetPath (src='CACHE', file=f'/{file}.full.sum'): ogDeleteFile (container='CACHE', file=f'{file}.full.sum')
print ('TRUE(0), es necesario actualizar. Paso 1, la cache no contiene esa imagen ')
return True
# Paso 2. Comprobamos que la imagen no estuviese en un proceso previo torrent
if FileLib.ogGetPath (file=f'{filetarget}.torrent.bf'):
#TODO: comprobar los md5 del fichero .torrent para asegurarnos que la imagen a descarga es la misma.
print ('TRUE(0), es necesario actualizar. Paso 2, la imagen esta en un estado de descarga torrent interrumpido')
return True
## En este punto la imagen en el repo y en la cache se llaman igual,
# paso 4. Obtener los md5 del fichero imagen en la cacha segun PROTOCOLO $3
if proto.lower() in ['full', 'torrent']:
#Buscamos MD5 en el REPO SOURCE
if os.path.exists (f'{filesource}.full.sum'):
with open (f'{filesource}.full.sum', 'r') as fd:
md5source = fd.read().strip()
else:
md5source = FileLib.ogCalculateFullChecksum (file=filesource)
# Generamos el MD5 (full) en la CACHE
if not os.path.exists (f'{filetarget}.full.sum'):
fullck = FileLib.ogCalculateFullChecksum (file=filetarget)
with open (f'{filetarget}.full.sum', 'w') as fd:
fd.write (fullck + '\n')
with open (f'{filetarget}.full.sum', 'r') as fd:
md5target = fd.read().strip()
# Generamos el MD5 (little) en la CACHE para posteriores usos del protocolo MULTICAST
if not os.path.exists (f'{filetarget}.sum'):
ck = FileLib.ogCalculateChecksum (file=filetarget)
with open (f'{filetarget}.sum', 'w') as fd:
fd.write (ck + '\n')
else:
#Buscamos MD5 en el REPO SOURCE
if os.path.exists (f'{filesource}.sum'):
with open (f'{filesource}.sum', 'r') as fd:
md5source = fd.read().strip()
else:
md5source = FileLib.ogCalculateChecksum (file=filesource)
# Generamos el MD5 (little) en la CACHE
if not os.path.exists (f'{filetarget}.sum'):
ck = FileLib.ogCalculateChecksum (file=filetarget)
with open (f'{filetarget}.sum', 'w') as fd:
fd.write (ck + '\n')
with open (f'{filetarget}.sum', 'r') as fd:
md5target = fd.read().strip()
#Generamos o copiamos MD5 (full) en la CACHE para posteriores usos con Torrent
# Si no existe el full.sum y si existe el .sum es porque el upateCACHE multicast o unicast ha sido correcto.
if not os.path.exists (f'{filetarget}.full.sum') and os.path.exists (f'{filetarget}.sum'):
if os.path.exists (f'{filesource}.full.sum'):
#Existe el .full.sum en REPO realizamos COPIA
shutil.copy2 (f'{filesource}.full.sum', f'{filetarget}.full.sum')
else:
#No existe .full.sum no en REPO LO GENERAMOS en la cache: situacion dificil que ocurra
fullck = FileLib.ogCalculateFullChecksum (file=filetarget)
with open (f'{filetarget}.full.sum', 'w') as fd:
fd.write (fullck + '\n')
# Paso 5. comparar los md5
if md5source == md5target:
print ('FALSE (1), No es neceario actualizar. Paso5.A la imagen esta en cache')
return False
else:
print ('imagen en cache distinta, borramos la imagen anterior')
for f in [f'{filetarget}', f'{filetarget}.sum', f'{filetarget}.torrent', f'{filetarget}.full.sum']:
os.unlink (f)
print ('TRUE (0), Si es necesario actualizar.')
return True

View File

@ -0,0 +1,455 @@
#!/bin/bash
#/**
#@file Registry.lib
#@brief Librería o clase Registry
#@class Boot
#@brief Funciones para gestión del registro de Windows.
#@version 1.1.0
#@warning License: GNU GPLv3+
#*/
# Función ficticia para lanzar chntpw con timeout de 5 s., evitando cuelgues del programa.
function chntpw ()
{
local CHNTPW
CHNTPW=$(which drbl-chntpw)
CHNTPW=${CHNTPW:-$(which chntpw)}
timeout --foreground 5s $CHNTPW -e "$@"
}
#/**
# ogAddRegistryKey path_mountpoint str_hive str_keyname
#@brief Añade una nueva clave al registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_keyname nombre de la clave
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#@version 1.0.1 - Nueva función
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-05-25
#*/ ##
function ogAddRegistryKey ()
{
# Variables locales.
local FILE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME path_mountpoint str_hive str_key" \
"$FUNCNAME /mnt/sda1 SOFTWARE '\Microsoft\NewKey'"
return
fi
# Error si no se reciben 3 parámetros.
[ $# == 3 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Camino del fichero de registro.
FILE=$(ogGetHivePath "$1" "$2") || return $?
# Añadir nueva clave.
chntpw "$FILE" << EOT &> /dev/null
cd ${3%\\*}
nk ${3##*\\}
q
y
EOT
}
#/**
# ogAddRegistryValue path_mountpoint str_hive str_valuename [str_valuetype]
#@brief Añade un nuevo valor al registro de Windows, indicando su tipo de datos.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor
#@param str_valuetype tipo de datos del valor (opcional)
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { DEFAULT, SAM, SECURITY, SOFTWARE, SYSTEM, COMPONENTS }
#@note valuetype = { STRING, BINARY, DWORD }, por defecto: STRING
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#@version 1.0.1 - Nueva función
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-05-25
#*/ ##
function ogAddRegistryValue ()
{
# Variables locales.
local FILE TYPE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME path_mountpoint str_hive str_valuename [str_valuetype]" \
"$FUNCNAME /mnt/sda1 SOFTWARE '\Microsoft\NewKey\Value1'" \
"$FUNCNAME /mnt/sda1 SOFTWARE '\Microsoft\NewKey\Value1' DWORD"
return
fi
# Error si no se reciben 3 o 4 parámetros.
[ $# == 3 -o $# == 4 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Camino del fichero de registro.
FILE=$(ogGetHivePath "$1" "$2") || return $?
case "${4^^}" in
STRING|"") TYPE=1 ;;
BINARY) TYPE=3 ;;
DWORD) TYPE=4 ;;
*) ogRaiseError $OG_ERR_OUTOFLIMIT "$4"
return $? ;;
esac
# Devolver el dato del valor de registro.
# /* (comentario Doxygen)
chntpw "$FILE" << EOT &> /dev/null
cd ${3%\\*}
nv $TYPE ${3##*\\}
q
y
EOT
# (comentario Doxygen) */
}
#/**
# ogDeleteRegistryKey path_mountpoint str_hive str_keyname
#@brief Elimina una clave del registro de Windows con todo su contenido.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_keyname nombre de la clave
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#@warning La clave debe estar vacía para poder ser borrada.
#@version 1.0.1 - Nueva función
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-05-25
#*/ ##
function ogDeleteRegistryKey ()
{
# Variables locales.
local FILE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME path_mountpoint str_hive str_key" \
"$FUNCNAME /mnt/sda1 SOFTWARE '\Microsoft\NewKey'"
return
fi
# Error si no se reciben 3 parámetros.
[ $# == 3 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Camino del fichero de registro.
FILE=$(ogGetHivePath "$1" "$2") || return $?
# Añadir nueva clave.
chntpw "$FILE" << EOT &> /dev/null
cd ${3%\\*}
dk ${3##*\\}
q
y
EOT
}
#/**
# ogDeleteRegistryValue path_mountpoint str_hive str_valuename
#@brief Elimina un valor del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#@version 1.0.1 - Nueva función
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-05-25
#*/ ##
function ogDeleteRegistryValue ()
{
# Variables locales.
local FILE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME path_mountpoint str_hive str_valuename" \
"$FUNCNAME /mnt/sda1 SOFTWARE '\Microsoft\NewKey\Value1'"
return
fi
# Error si no se reciben 3 parámetros.
[ $# == 3 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Camino del fichero de registro.
FILE=$(ogGetHivePath "$1" "$2") || return $?
# Devolver el dato del valor de registro.
# /* (comentario Doxygen)
chntpw "$FILE" << EOT &> /dev/null
cd ${3%\\*}
dv ${3##*\\}
q
y
EOT
# (comentario Doxygen) */
}
#/**
# ogGetHivePath path_mountpoint [str_hive|str_user]
#@brief Función básica que devuelve el camino del fichero con una sección del registro.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@return str_path - camino del fichero de registro
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { DEFAULT, SAM, SECURITY, SOFTWARE, SYSTEM, COMPONENTS, NombreDeUsuario }
#@warning El sistema de archivos de Windows debe estar montada previamente.
#@version 1.0.1 - Nueva función
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-05-18
#@version 1.1.0 - Soportar registro de un usuario local.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2015-10-14
#*/ ##
function ogGetHivePath ()
{
# Variables locales.
local FILE HIVE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME path_mountpoint [str_hive|str_user]" \
"$FUNCNAME /mnt/sda1 SOFTWARE => /mnt/sda1/WINDOWS/System32/config/SOFTWARE" \
"$FUNCNAME /mnt/sda1 user1 => /mnt/sda1/Users/user1/NTUSER.DAT"
return
fi
# Error si no se reciben 2 parámetros.
[ $# == 2 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Camino del fichero de registro de usuario o de sistema (de menor a mayor prioridad).
FILE="$(ogGetPath "/$1/Windows/System32/config/$2")"
[ -z "$FILE" ] && FILE="$(ogGetPath "/$1/Users/$2/NTUSER.DAT")"
[ -z "$FILE" ] && FILE="$(ogGetPath "/$1/winnt/system32/config/$2")"
[ -z "$FILE" ] && FILE="$(ogGetPath "/$1/Documents and Settings/$2/NTUSER.DAT")"
[ -f "$FILE" ] && echo "$FILE" || ogRaiseError $OG_ERR_NOTFOUND "$1 $2" || return $?
}
#/**
# ogGetRegistryValue path_mountpoint str_hive str_valuename
#@brief Devuelve el dato de un valor del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor
#@return str_valuedata - datos del valor.
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw, awk
#@warning El sistema de archivos de Windows debe estar montado previamente.
#@version 0.9 - Adaptación para OpenGNSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-09-11
#@version 1.1.0 - Soportar tipos BINARY (parejas hexadecimales separadas por espacio).
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2015-09-28
#*/ ##
function ogGetRegistryValue ()
{
# Variables locales.
local FILE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME path_mountpoint str_hive str_valuename" \
"$FUNCNAME /mnt/sda1 SOFTWARE '\Microsoft\NewKey\Value1' ==> 1"
return
fi
# Error si no se reciben 3 parámetros.
[ $# == 3 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Camino del fichero de registro.
FILE=$(ogGetHivePath "$1" "$2") || return $?
# Devolver el dato del valor de registro.
# /* (comentario Doxygen)
chntpw "$FILE" << EOT 2> /dev/null | awk '/> Value/ {if (index($0, "REG_BINARY") > 0)
{data=""}
else
{getline; data=$0;} }
/^:[0-9A-F]+ / {data=data""substr($0, 9, 48);}
END {print data;}'
cd ${3%\\*}
cat ${3##*\\}
q
EOT
# (comentario Doxygen) */
}
#/**
# ogListRegistryKeys path_mountpoint str_hive str_key
#@brief Lista los nombres de subclaves de una determinada clave del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_key clave de registro
#@return str_subkey ... - lista de subclaves
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw, awk
#@warning El sistema de archivos de Windows debe estar montado previamente.
#@version 0.9 - Adaptación para OpenGNSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-09-23
#*/ ##
function ogListRegistryKeys ()
{
# Variables locales.
local FILE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME path_mountpoint str_hive str_key" \
"$FUNCNAME /mnt/sda1 SOFTWARE '\Microsoft\Windows\CurrentVersion'"
return
fi
# Error si no se reciben 3 parámetros.
[ $# == 3 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Camino del fichero de registro.
FILE=$(ogGetHivePath "$1" "$2") || return $?
# Devolver la lista de claves de registro.
chntpw "$FILE" << EOT 2> /dev/null | awk 'BEGIN {FS="[<>]"} $1~/^ $/ {print $2}'
ls $3
q
EOT
}
#/**
# ogListRegistryValues path_mountpoint str_hive str_key
#@brief Lista los nombres de valores de una determinada clave del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_key clave de registro
#@return str_value ... - lista de valores
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw, awk
#@warning El sistema de archivos de Windows debe estar montado previamente.
#@version 1.0.1 - Nueva función.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-05-26
#*/ ##
function ogListRegistryValues ()
{
# Variables locales.
local FILE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME path_mountpoint str_hive str_key" \
"$FUNCNAME /mnt/sda1 SOFTWARE '\Microsoft\Windows\CurrentVersion'"
return
fi
# Error si no se reciben 3 parámetros.
[ $# == 3 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Camino del fichero de registro.
FILE=$(ogGetHivePath "$1" "$2") || return $?
# Devolver la lista de claves de registro.
chntpw "$FILE" << EOT 2> /dev/null | awk 'BEGIN {FS="[<>]"} $1~/REG_/ {print $2}'
ls $3
q
EOT
}
#/**
# ogSetRegistryValue path_mountpoint str_hive str_valuename str_valuedata
#@brief Establece el dato asociado a un valor del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor de registro
#@param str_valuedata dato del valor de registro
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montado previamente.
#@version 0.9 - Adaptación para OpenGNSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-09-24
#@version 1.1.0 - Soportar tipos BINARY (parejas hexadecimales separadas por espacio).
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2015-09-28
#*/ ##
function ogSetRegistryValue ()
{
# Variables locales.
local FILE i n tmpfile
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME path_mountpoint str_hive str_valuename str_data" \
"$FUNCNAME /mnt/sda1 SOFTWARE '\Key\SubKey\StringValue' \"Abcde Fghij\"" \
"$FUNCNAME /mnt/sda1 SOFTWARE '\Key\SubKey\DwordValue' 1" \
"$FUNCNAME /mnt/sda1 SOFTWARE '\Key\SubKey\BinaryValue' \"04 08 0C 10\""
return
fi
# Error si no se reciben 4 parámetros.
[ $# == 4 ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Camino del fichero de registro.
FILE=$(ogGetHivePath "$1" "$2") || return $?
# Fichero temporal para componer la entrada al comando "chntpw".
tmpfile=/tmp/chntpw$$
trap "rm -f $tmpfile" 1 2 3 9 15
# Comprobar tipo de datos del valor del registro.
cat << EOT >$tmpfile
ls ${3%\\*}
q
EOT
if [ -n "$(chntpw "$FILE" < $tmpfile 2> /dev/null | grep "BINARY.*<${3##*\\}>")" ]; then
# Procesar tipo binario (incluir nº de bytes y líneas de 16 parejas hexadecimales).
[[ "$4 " =~ ^([0-9A-F]{2} )*$ ]] || ogRaiseError $OG_ERR_FORMAT "\"$4\"" || return $?
let n=${#4}+1
cat << EOT >$tmpfile
cd ${3%\\*}
ed ${3##*\\}
$[n/3]
EOT
# Formato de líneas hexadecimales: :OFFSET XX YY ZZ ... (hasta 16 parejas).
for (( i=0; i<n; i+=48 )); do
printf ":%05x %s\n" $[i/3] "${4:$i:48}" >> $tmpfile
done
echo -e "s\nq\ny" >> $tmpfile
else
# Cambiar el dato del valor de registro para cadenas y bytes.
cat << EOT >$tmpfile
cd ${3%\\*}
ed ${3##*\\}
$4
q
y
EOT
fi
# Aplicar cambios.
chntpw "$FILE" < $tmpfile &> /dev/null
rm -f $tmpfile
}

View File

@ -1,380 +0,0 @@
#/**
#@file RegistryLib.py
#@brief Librería o clase Registry
#@class Boot
#@brief Funciones para gestión del registro de Windows.
#@warning License: GNU GPLv3+
#*/
import subprocess
import os
import re
import shutil
import tempfile
import ogGlobals
import SystemLib
import FileLib
# Función ficticia para lanzar chntpw con timeout de 5 s., evitando cuelgues del programa.
chntpw_exe = shutil.which ('drbl-chntpw') or shutil.which ('chntpw')
def chntpw (hivefile, input_file):
with open (input_file, 'r') as fd:
input_contents = fd.read()
return subprocess.run ([chntpw_exe, '-e', hivefile], timeout=5, input=input_contents, capture_output=True, text=True).stdout
## en el codigo bash aparecen "${3%\\*}" y "${3##*\\}" varias veces
## ${3%\\*} es el "dirname" de una key del registro
## ${3##*\\} es el "basename"
def _split_k (k):
k_elems = k.split ('\\')
k_dirname = '\\'.join (k_elems[0:-1])
k_basename = k_elems[-1]
return k_dirname, k_basename
#/**
# ogAddRegistryKey path_mountpoint str_hive str_keyname
#@brief Añade una nueva clave al registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_keyname nombre de la clave
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#*/ ##
def ogAddRegistryKey (mntpt, hive, k):
hivefile = ogGetHivePath (mntpt, hive)
if not hivefile: return
k_dirname, k_basename = _split_k (k)
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'cd {k_dirname}\n')
f.write (f'nk {k_basename}\n')
f.write ('q\ny\n')
f.close()
chntpw (hivefile, f.name)
os.remove (f.name)
#/**
# ogAddRegistryValue path_mountpoint str_hive str_valuename [str_valuetype]
#@brief Añade un nuevo valor al registro de Windows, indicando su tipo de datos.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor
#@param str_valuetype tipo de datos del valor (opcional)
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { DEFAULT, SAM, SECURITY, SOFTWARE, SYSTEM, COMPONENTS }
#@note valuetype = { STRING, BINARY, DWORD }, por defecto: STRING
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#*/ ##
#ogAddRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1') ## type STRING by default
#ogAddRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1', 'STRING')
#ogAddRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1', 'BINARY')
#ogAddRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1', 'DWORD')
def ogAddRegistryValue (mntpt, hive, k, vtype='STRING'):
hivefile = ogGetHivePath (mntpt, hive)
if not hivefile: return
k_dirname, k_basename = _split_k (k)
# Determine the value type.
if 'STRING' == vtype.upper(): TYPE = 1
elif 'BINARY' == vtype.upper(): TYPE = 3
elif 'DWORD' == vtype.upper(): TYPE = 4
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_OUTOFLIMIT, vtype)
return
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'cd {k_dirname}\n')
f.write (f'nv {TYPE} {k_basename}\n')
f.write ('q\ny\n')
f.close()
chntpw (hivefile, f.name)
os.remove (f.name)
#/**
# ogDeleteRegistryKey path_mountpoint str_hive str_keyname
#@brief Elimina una clave del registro de Windows con todo su contenido.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_keyname nombre de la clave
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#@warning La clave debe estar vacía para poder ser borrada.
#*/ ##
def ogDeleteRegistryKey (mntpt, hive, k):
hivefile = ogGetHivePath (mntpt, hive)
if not hivefile: return
k_dirname, k_basename = _split_k (k)
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'cd {k_dirname}\n')
f.write (f'dk {k_basename}\n')
f.write ('q\ny\n')
f.close()
chntpw (hivefile, f.name)
os.remove (f.name)
#/**
# ogDeleteRegistryValue path_mountpoint str_hive str_valuename
#@brief Elimina un valor del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montada previamente.
#*/ ##
#ogDeleteRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1')
def ogDeleteRegistryValue (mntpt, hive, k):
hivefile = ogGetHivePath (mntpt, hive)
if not hivefile: return
k_dirname, k_basename = _split_k (k)
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'cd {k_dirname}\n')
f.write (f'dv {k_basename}\n')
f.write ('q\ny\n')
f.close()
chntpw (hivefile, f.name)
os.remove(f.name)
#/**
# ogGetHivePath path_mountpoint [str_hive|str_user]
#@brief Función básica que devuelve el camino del fichero con una sección del registro.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@return str_path - camino del fichero de registro
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { DEFAULT, SAM, SECURITY, SOFTWARE, SYSTEM, COMPONENTS, NombreDeUsuario }
#@warning El sistema de archivos de Windows debe estar montada previamente.
#*/ ##
#ogGetHivePath ('/mnt/sda1', 'user1') => /mnt/sda1/Users/user1/NTUSER.DAT
#ogGetHivePath ('/mnt/sda1', 'SYSTEM') => //mnt/sda1/Windows/System32/config/SYSTEM
#ogGetHivePath ('/mnt/sda1', 'IEUser') => //mnt/sda1/Users/IEUser/NTUSER.DAT
def ogGetHivePath(mntpt, hive):
# Camino del fichero de registro de usuario o de sistema (de menor a mayor prioridad).
FILE = FileLib.ogGetPath(file=f"/{mntpt}/Windows/System32/config/{hive}")
if not FILE: FILE = FileLib.ogGetPath(file=f"/{mntpt}/Users/{hive}/NTUSER.DAT")
if not FILE: FILE = FileLib.ogGetPath(file=f"/{mntpt}/winnt/system32/config/{hive}")
if not FILE: FILE = FileLib.ogGetPath(file=f"/{mntpt}/Documents and Settings/{hive}/NTUSER.DAT")
if FILE and os.path.isfile(FILE):
return FILE
else:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{mntpt} {hive}')
return None
## simulate 'grep --after-context 1'
def _grep_A1 (strings, search_term):
results = []
for i in range (len (strings)):
if search_term in strings[i]:
results.append (strings[i])
if i + 1 < len(strings):
results.append (strings[i + 1])
return results
#/**
# ogGetRegistryValue path_mountpoint str_hive str_valuename
#@brief Devuelve el dato de un valor del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor
#@return str_valuedata - datos del valor.
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw, awk
#@warning El sistema de archivos de Windows debe estar montado previamente.
#*/ ##
def ogGetRegistryValue (mntpt, hive, k):
hivefile = ogGetHivePath(mntpt, hive)
if not hivefile: return
k_dirname, k_basename = _split_k (k)
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'cd {k_dirname}\n')
f.write (f'cat {k_basename}\n')
f.write ('q\n')
f.close()
chntpw_out = chntpw (hivefile, f.name)
os.remove (f.name)
lines = chntpw_out.splitlines()
lines = _grep_A1 (lines, '> Value')
if 2 != len (lines):
return None
ret = None
if 'REG_BINARY' in lines[0]:
if re.search ('^:[0-9A-F]+ ', lines[1]):
ret = lines[1][8:56]
else:
ret = lines[1]
return ret
#/**
# ogListRegistryKeys path_mountpoint str_hive str_key
#@brief Lista los nombres de subclaves de una determinada clave del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_key clave de registro
#@return str_subkey ... - lista de subclaves
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw, awk
#@warning El sistema de archivos de Windows debe estar montado previamente.
#*/ ##
#ogListRegistryKeys ('/mnt/sda1', 'SOFTWARE', '\Microsoft\Windows\CurrentVersion')
def ogListRegistryKeys (mntpt, hive, k):
hivefile = ogGetHivePath(mntpt, hive)
if not hivefile: return
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'ls {k}\n')
f.write ('q\n')
f.close()
chntpw_out = chntpw (hivefile, f.name)
os.remove (f.name)
lines = chntpw_out.splitlines()
ret = []
for l in lines:
elems = re.split ('[<>]', l)
if len(elems) < 2: continue
if ' ' == elems[0]:
ret.append (elems[1])
return ret
#/**
# ogListRegistryValues path_mountpoint str_hive str_key
#@brief Lista los nombres de valores de una determinada clave del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_key clave de registro
#@return str_value ... - lista de valores
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw, awk
#@warning El sistema de archivos de Windows debe estar montado previamente.
#*/ ##
#ogListRegistryValues ('/mnt/sda1', 'SOFTWARE', '\Microsoft\Windows\CurrentVersion')
def ogListRegistryValues (mntpt, hive, k):
hivefile = ogGetHivePath(mntpt, hive)
if not hivefile: return
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'ls {k}\n')
f.write ('q\n')
f.close()
chntpw_out = chntpw (hivefile, f.name)
os.remove (f.name)
lines = chntpw_out.splitlines()
ret = []
for l in lines:
elems = re.split ('[<>]', l)
if len(elems) < 2: continue
if 'REG_' in elems[0]:
ret.append (elems[1])
return ret
def _format_hex (hex_string):
result = []
offset = 0
hex_values = hex_string.strip().split()
result.append (str (len (hex_values)))
while hex_values:
chunk = hex_values[:16]
hex_values = hex_values[16:]
offset_str = f':{offset:05x} '
hex_line = ' '.join (chunk)
result.append (offset_str + hex_line)
offset += 16
return '\n'.join (result)
#/**
# ogSetRegistryValue path_mountpoint str_hive str_valuename str_valuedata
#@brief Establece el dato asociado a un valor del registro de Windows.
#@param path_mountpoint directorio donde está montado el sistema Windows
#@param str_hive sección del registro
#@param str_valuename nombre del valor de registro
#@param str_valuedata dato del valor de registro
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado.
#@note hive = { default, sam, security, software, system, components }
#@warning Requisitos: chntpw
#@warning El sistema de archivos de Windows debe estar montado previamente.
#*/ ##
#ogSetRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Key\SubKey\StringValue', 'Abcde Fghij')
#ogSetRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Key\SubKey\DwordValue', 1)
#ogSetRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Key\SubKey\BinaryValue', '04 08 0C 10')
def ogSetRegistryValue (mntpt, hive, k, v):
hivefile = ogGetHivePath (mntpt, hive)
if not hivefile: return
k_dirname, k_basename = _split_k (k)
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f"ls {k_dirname}\n")
f.write ('q\n')
f.close()
chntpw_out = chntpw (hivefile, f.name)
os.remove(f.name)
if re.search (f"BINARY.*<{k_basename}>", chntpw_out):
## the entry in the registry is binary. Our input should be a sequence of bytes
if ' ' != v[-1]: v += ' ' ## the regex below requires a trailing space
if not re.match (r'^([0-9A-F]{2} )*$', v.upper()):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'"{v}"')
return
formatted = _format_hex (v.upper())
formatted += '\ns'
else:
formatted = v
with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f:
f.write (f'cd {k_dirname}\n')
f.write (f'ed {k_basename}\n')
f.write (f'{formatted}\n')
f.write ('q\ny\n')
f.close()
chntpw (hivefile, f.name)
os.remove(f.name)

View File

@ -0,0 +1,122 @@
#!/bin/bash
#/**
# ogCheckStringInGroup
#@brief Función para determinar si el elemento pertenece a un conjunto
#@param 1 elemento a comprobar
#@param 2 grupo de elementos para comprobar tipo "valor1 valor2 valor3"
#@return 0 si pertenece al grupo
#@return 1 si NO pertenece al grupo
#@exception OG_ERR_FORMAT formato incorrecto.
#@note
#@todo
#@version 0.91 - Definición de
#@author Antonio Doblas Viso, Universidad de Málaga
#@date 2010/05/09
#*/ ##
function ogCheckStringInGroup ()
{
local i
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME str_elemento str_grupo" \
"$FUNCNAME full-duplex \"full-duplex half-duplex broadcast\" "
return
fi
# Error si no se recibe 2 parámetro.
[ $# == 2 ] || ogRaiseError $OG_ERR_FORMAT || return $?
for i in `echo $2`
do
if [ "$1" == "$i" ]
then
return 0
fi
done
return 1
}
#/**
# ogCheckStringInReg
#@brief Función para determinar si el elemento contiene una "expresión regular"
#@param 1 elemento a comprobar
#@param 2 expresión regular"
#@return 0 si coincide con la expresión
#@return 1 si NO coincide con la expresión
#@exception OG_ERR_FORMAT formato incorrecto.
#@note
#@todo
#@version 0.91 - Definición de
#@author Antonio Doblas Viso, Universidad de Málaga
#@date 2010/05/09
#*/ ##
function ogCheckStringInReg()
{
local REG
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME str_elemento str_expresión_regular" \
"$FUNCNAME 50M \"^[0-9]{1,2}\M$\" "
return
fi
# Error si no se recibe 2 parámetro.
[ $# == 2 ] || ogRaiseError $OG_ERR_FORMAT || return $?
REG=$2
[[ $1 =~ $REG ]] && return 0 || return 1
}
#/**
# ogCheckIpAddress
#@brief Función para determinar si una cadena es una dirección ipv4 válida
#@param 1 string de la ip a comprobar
#@return 0 si es una dirección válida
#@return 1 si NO es una dirección válida
#@exception OG_ERR_FORMAT formato incorrecto.
#@note
#@todo
#@version 0.91 - Definición de
#@author Antonio Doblas Viso, Universidad de Málaga
#@date 2010/05/09
#*/ ##
function ogCheckIpAddress()
{
local REG IP arrIP
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME str_IpAddressToCheck" \
"$FUNCNAME 192.18.35.3"
return
fi
# Error si no se recibe 1 parámetro.
[ $# == 1 ] || ogRaiseError $OG_ERR_FORMAT || return $?
IP=$1
REG="^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$"
if [[ "$IP" =~ $REG ]]
then
OIFS=$IFS;
IFS='.' ;
arrIP=($IP)
IFS=$OIFS
if [[ ${arrIP[0]} -le 255 && ${arrIP[1]} -le 255 && ${arrIP[2]} -le 255 && ${arrIP[3]} -le 255 ]]
then
return 0
fi
fi
return 1
}

View File

@ -1,31 +0,0 @@
import re
#/**
# ogCheckIpAddress
#@brief Función para determinar si una cadena es una dirección ipv4 válida
#@param 1 string de la ip a comprobar
#@return 0 si es una dirección válida
#@return 1 si NO es una dirección válida
#@exception OG_ERR_FORMAT formato incorrecto.
#@note
#@todo
#*/ ##
def ogCheckIpAddress(ip):
"""
Función para determinar si una cadena es una dirección ipv4 válida.
:param ip: string de la ip a comprobar
:return: True si es una dirección válida, False si NO es una dirección válida
"""
if not isinstance(ip, str):
raise ValueError("Formato incorrecto, el parámetro debe ser una cadena.")
regex = r"^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$"
if re.match(regex, ip):
parts = ip.split('.')
if all(0 <= int(part) <= 255 for part in parts):
return True
return False

View File

@ -0,0 +1,339 @@
#!/bin/bash
#/**
#@file System.lib
#@brief Librería o clase System
#@class System
#@brief Funciones básicas del sistema.
#@version 1.1.0
#@warning License: GNU GPLv3+
#*/
#/**
# ogEcho [str_logtype ...] [str_loglevel] "str_message" ...
#@brief Muestra mensajes en consola y lo registra en fichero de incidencias.
#@param str_logtype tipo de registro de incidencias.
#@param str_loglevel nivel de registro de incidencias.
#@param str_message mensaje (puede recibir más de 1 parámetro.
#@return Mensaje mostrado.
#@warning Si no se indica nivel de registro, solo muestra mensaje en pantalla.
#@warning Si DEBUG="no", no se registran mensajes de error.
#@note logfile = { log, command, session }; usa "log" si se indica nivel de registro.
#@note loglevel = { help, info, warning, error }
#@note El nivel de ayuda \c (help) no se registra en el fichero de incidencias.
#@version 0.9 - Primera versión para OpenGnSys
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-07-23
#@version 1.0.5 - Elegir fichero de log.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2014-03-17
#@version 1.1.0 - Posibilidad de no registrar mensajes en ficheros.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2015-11-10
#*/
function ogEcho () {
# Variables locales
local CONT=1 LOGS LOGLEVEL DATETIME
# Selección de ficheros de rgistro de incidencias.
while [ $CONT ]; do
case "${1,,}" in
log) LOGS="$LOGS $OGLOGFILE"; shift ;;
command) LOGS="$LOGS $OGLOGCOMMAND"; shift ;;
session) LOGS="$LOGS $OGLOGSESSION"; shift ;;
*) CONT= ;;
esac
done
# Selección del nivel de registro (opcional).
case "${1,,}" in
help) shift ;;
info) LOGLEVEL="$1"; shift ;;
warning) LOGLEVEL="$1"; shift ;;
error) LOGLEVEL="$1"; shift ;;
*) ;;
esac
if [ -n "$LOGLEVEL" ]; then
DATETIME=$(date +"%F %T")
# Registrar mensajes en fichero de log si la depuración no está desactivada.
[ "${DEBUG,,}" != "no" ] && LOGS="$OGLOGFILE $LOGS"
echo "OpenGnsys $LOGLEVEL" "$DATETIME $*" 2>&1 | tee -a $LOGS
else
echo "$*" | tee -a $LOGS
fi
}
#/**
# ogExecAndLog str_logfile ... str_command ...
#@brief Ejecuta un comando y guarda su salida en fichero de registro.
#@param str_logfile fichero de registro (pueden ser varios).
#@param str_command comando y comandos a ejecutar.
#@return Salida de ejecución del comando.
#@note str_logfile = { LOG, SESSION, COMMAND }
#@version 1.0.6 - Primera versión para OpenGnSys
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2013-07-02
#*/
function ogExecAndLog () {
# Variables locales
local ISCOMMAND ISLOG ISSESSION COMMAND CONTINUE=1 FILES REDIREC
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME str_logfile ... str_command ..." \
"$FUNCNAME COMMAND ls -al /"
return
fi
# Procesar parámetros.
while [ $CONTINUE ]; do
case "${1,,}" in
command) ISCOMMAND=1; shift ;;
log) ISLOG=1; shift ;;
session) ISSESSION=1; shift ;;
*) COMMAND="$@"
CONTINUE= ;;
esac
done
# Error si no se recibe un comando que ejecutar.
[ -n "$COMMAND" ] || ogRaiseError $OG_ERR_FORMAT || return $?
# Componer lista de ficheros de registro.
if [ $ISCOMMAND ]; then
FILES="$OGLOGCOMMAND"
> $FILES
REDIREC="2>&1"
fi
[ $ISLOG ] && FILES="$FILES $OGLOGFILE"
[ $ISSESSION ] && FILES="$FILES $OGLOGSESSION"
# Ejecutar comando.
eval $COMMAND $REDIREC | tee -a $FILES
# Salida de error del comando ejecutado.
return ${PIPESTATUS[0]}
}
#/**
# ogGetCaller
#@brief Devuelve nombre del programa o script ejecutor (padre).
#@param No.
#@return str_name - Nombre del programa ejecutor.
#@version 0.10 - Primera versión para OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-01-17
#*/
function ogGetCaller () {
# Obtener el nombre del programa o del script que ha llamado al proceso actual.
basename "$(COLUMNS=200 ps hp $PPID -o args | \
awk '{if ($1~/bash/ && $2!="") { print $2; }
else { sub(/^-/,"",$1); print $1; } }')"
}
#/**
# ogHelp ["str_function" ["str_format" ["str_example" ... ]]]
#@brief Muestra mensaje de ayuda para una función determinda.
#@param str_function Nombre de la función.
#@param str_format Formato de ejecución de la función.
#@param str_example Ejemplo de ejecución de la función.
#@return str_help - Salida de ayuda.
#@note Si no se indican parámetros, la función se toma de la variable \c $FUNCNAME
#@note La descripción de la función se toma de la variable compuesta por \c MSG_FUNC_$función incluida en el fichero de idiomas.
#@note Pueden especificarse varios mensajes con ejemplos.
#@version 0.9 - Primera versión para OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-07-27
#*/
function ogHelp () {
# Variables locales.
local FUNC MSG
# Mostrar función, descripción y formato.
FUNC="${1:-${FUNCNAME[${#FUNCNAME[*]}-1]}}"
MSG="MSG_HELP_$FUNC"
ogEcho help "$MSG_FUNCTION $FUNC: ${!MSG}"
[ -n "$2" ] && ogEcho help " $MSG_FORMAT: $2"
# Mostrar ejemplos (si existen).
shift 2
while [ $# -gt 0 ]; do
ogEcho help " $MSG_EXAMPLE: $1"
shift
done
}
#/**
# ogRaiseError [str_logtype ...] int_errcode ["str_errmessage" ...]
#@brief Devuelve el mensaje y el código de error correspondiente.
#@param str_logtype tipo de registro de incidencias.
#@param int_errcode código de error.
#@param str_errmessage mensajes complementarios de error.
#@return str_message - Mensaje de error, incluyendo las funciones relacionadas.
#@warning No definidas
#@note Mensajes internacionales del fichero de idiomas.
#@version 0.9 - Primera versión para OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2009-07-21
#@version 1.0.5 - Muestra en el mensaje todas las funciones relacionadas (separadas por <-).
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2014-03-17
#*/
function ogRaiseError () {
# Variables locales
local CONT=1 LOGS MSG CODE FUNCS
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [str_logfile ...] int_errorcode str_errormessage"
return
fi
# Selección de rgistros de incidencias.
while [ $CONT ]; do
case "${1,,}" in
log|command|session) LOGS="$LOGS $1"; shift ;;
*) CONT= ;;
esac
done
# Obtener código y mensaje de error.
CODE="$1"
case "$CODE" in
$OG_ERR_FORMAT) MSG="$MSG_ERR_FORMAT \"$2\"" ;;
$OG_ERR_NOTFOUND) MSG="$MSG_ERR_NOTFOUND \"$2\"" ;;
$OG_ERR_OUTOFLIMIT) MSG="$MSG_ERR_OUTOFLIMIT \"$2\"" ;;
$OG_ERR_PARTITION) MSG="$MSG_ERR_PARTITION \"$2\"" ;;
$OG_ERR_LOCKED) MSG="$MSG_ERR_LOCKED \"$2\"" ;;
$OG_ERR_CACHE) MSG="$MSG_ERR_CACHE \"$2\"" ;;
$OG_ERR_NOGPT) MSG="$MSG_ERR_NOGPT \"$2\"" ;;
$OG_ERR_REPO) MSG="$MSG_ERR_REPO \"$2\"" ;;
$OG_ERR_FILESYS) MSG="$MSG_ERR_FILESYS \"$2\"" ;;
$OG_ERR_IMAGE) MSG="$MSG_ERR_IMAGE \"$2\"" ;;
$OG_ERR_NOTOS) MSG="$MSG_ERR_NOTOS \"$2\"" ;;
$OG_ERR_NOTEXEC) MSG="$MSG_ERR_NOTEXEC \"$2\"" ;;
$OG_ERR_NOTWRITE) MSG="$MSG_ERR_NOTWRITE \"$2\"" ;;
$OG_ERR_NOTCACHE) MSG="$MSG_ERR_NOTCACHE \"$2\"" ;;
$OG_ERR_CACHESIZE) MSG="$MSG_ERR_CACHESIZE \"$2\"" ;;
$OG_ERR_REDUCEFS) MSG="$MSG_ERR_REDUCEFS \"$2\"" ;;
$OG_ERR_EXTENDFS) MSG="$MSG_ERR_EXTENDFS \"$2\"" ;;
$OG_ERR_IMGSIZEPARTITION) MSG="$MSG_ERR_IMGSIZEPARTITION \"$2\"" ;;
$OG_ERR_UPDATECACHE) MSG="$MSG_ERR_UPDATECACHE \"$2\"" ;;
$OG_ERR_DONTFORMAT) MSG="$MSG_ERR_DONTFORMAT \"$2\"" ;;
$OG_ERR_IMAGEFILE) MSG="$MSG_ERR_IMAGEFILE \"$2\"" ;;
$OG_ERR_UCASTSYNTAXT) MSG="$MSG_ERR_UCASTSYNTAXT \"$2\"" ;;
$OG_ERR_UCASTSENDPARTITION) MSG="$MSG_ERR_UCASTSENDPARTITION \"$2\"" ;;
$OG_ERR_UCASTSENDFILE) MSG="$MSG_ERR_UCASTSENDFILE \"$2\"" ;;
$OG_ERR_UCASTRECEIVERPARTITION) MSG="$MSG_ERR_UCASTRECEIVERPARTITION \"$2\"" ;;
$OG_ERR_UCASTRECEIVERFILE) MSG="$MSG_ERR_UCASTRECEIVERFILE \"$2\"" ;;
$OG_ERR_MCASTSYNTAXT) MSG="$MSG_ERR_MCASTSYNTAXT \"$2\"" ;;
$OG_ERR_MCASTSENDFILE) MSG="$MSG_ERR_MCASTSENDFILE \"$2\"" ;;
$OG_ERR_MCASTRECEIVERFILE) MSG="$MSG_ERR_MCASTRECEIVERFILE \"$2\"" ;;
$OG_ERR_MCASTSENDPARTITION) MSG="$MSG_ERR_MCASTSENDPARTITION \"$2\"" ;;
$OG_ERR_MCASTRECEIVERPARTITION) MSG="$MSG_ERR_MCASTRECEIVERPARTITION \"$2\"" ;;
$OG_ERR_PROTOCOLJOINMASTER) MSG="$MSG_ERR_PROTOCOLJOINMASTER \"$2\"" ;;
$OG_ERR_DONTMOUNT_IMAGE) MSG="$MSG_ERR_DONTMOUNT_IMAGE \"$2\"" ;;
$OG_ERR_DONTUNMOUNT_IMAGE) MSG="$MSG_ERR_DONTUNMOUNT_IMAGE \"$2\"" ;;
$OG_ERR_DONTSYNC_IMAGE) MSG="$MSG_ERR_DONTSYNC_IMAGE \"$2\"" ;;
$OG_ERR_NOTDIFFERENT) MSG="$MSG_ERR_NOTDIFFERENT \"$2\"" ;;
$OG_ERR_SYNCHRONIZING) MSG="$MSG_ERR_SYNCHRONIZING \"$2\"" ;;
$OG_ERR_NOTUEFI) MSG="$MSG_ERR_NOTUEFI \"$2\"" ;;
$OG_ERR_NOMSDOS) MSG="$MSG_ERR_NOMSDOS \"$2\"" ;;
$OG_ERR_NOTBIOS) MSG="$MSG_ERR_NOTBIOS \"$2\"" ;;
*) MSG="$MSG_ERR_GENERIC"; CODE=$OG_ERR_GENERIC ;;
esac
# Obtener lista de funciones afectadas, incluyendo el script que las llama.
FUNCS="${FUNCNAME[@]:1}"
FUNCS="${FUNCS/main/$(basename $0 2>/dev/null)}"
# Mostrar mensaje de error si es función depurable y salir con el código indicado.
if [ $CODE == $OG_ERR_FORMAT ] || ogCheckStringInGroup "$FUNCS" "$NODEBUGFUNCTIONS" || ! ogCheckStringInGroup "${FUNCS%% *}" "$NODEBUGFUNCTIONS"; then
ogEcho $LOGS error "${FUNCS// /<-}: $MSG" >&2
fi
return $CODE
}
#/**
# ogIsRepoLocked
#@brief Comprueba si el repositorio está siendo usado (tiene ficheros abiertos).
#@param No.
#@return Código de salida: 0 - bloqueado, 1 - sin bloquear o error.
#@version 0.10 - Primera versión para OpenGnSys.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-01-17
#@version 1.0.1 - Devolver falso en caso de error.
#@author Ramon Gomez, ETSII Universidad de Sevilla
#@date 2011-05-18
#*/
function ogIsRepoLocked ()
{
# Variables locales.
local f FILES
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" "if $FUNCNAME; then ...; fi"
return
fi
# No hacer nada, si no está definido el punto de montaje del repositorio.
[ -z "$OGIMG" ] && return 1
# Comprobar si alguno de los ficheros abiertos por los procesos activos está en el
# punto de montaje del repositorio de imágenes.
FILES=$(for f in /proc/[0-9]*/fd/*; do readlink -f "$f"; done | grep "^$OGIMG") # */ (comentario Doxygen)
test -n "$FILES"
}
function ogCheckProgram ()
{
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME \"str_program ...\"" \
"$FUNCNAME \"partimage partclone mbuffer\""
return
fi
# Error si no se recibe 1 parámetro.
[ $# == 1 ] || ogRaiseError $OG_ERR_FORMAT || return $?
local PERROR PLOG i
PERROR=0
PLOG=" "
for i in `echo $1`
do
if [ ! `which $i` ]
then
PERROR=1
PLOG="$PLOG $i"
fi
done
if [ "$PERROR" == "1" ]
then
ogRaiseError $OG_ERR_NOTEXEC "$PLOG" || return $?
else
return 0
fi
}
#### PRUEBA
function ogIsVirtualMachine() {
case "$(dmidecode -s system-product-name)" in
KVM|VirtualBox)
return 1 ;;
*) return 0 ;;
esac
}

View File

@ -1,291 +0,0 @@
import subprocess
import datetime
from zoneinfo import ZoneInfo
import sys
import os
import shutil
import inspect
import glob
## for ogExecAndLog
from io import StringIO
from contextlib import redirect_stdout, redirect_stderr
import ogGlobals
import StringLib
import SystemLib
#NODEBUGFUNCTIONS, OGIMG, OG_ERR_CACHESIZE, OG_ERR_NOTCACHE, OG_ERR_NOTWRITE, OG_ERR_FILESYS
#OG_ERR_REPO, OG_ERR_NOTOS, OG_ERR_NOGPT, OG_ERR_OUTOFLIMIT, OG_ERR_IMAGE, OG_ERR_CACHE
#OGLOGSESSION, OGLOGCOMMAND, OGLOGFILE, OG_ERR_LOCKED, OG_ERR_PARTITION, OG_ERR_FORMAT, OG_ERR_NOTEXEC, OG_ERR_NOTFOUND
def _logtype2logfile (t):
if 'log' == t.lower(): return ogGlobals.OGLOGFILE
elif 'command' == t.lower(): return ogGlobals.OGLOGCOMMAND
elif 'session' == t.lower(): return ogGlobals.OGLOGSESSION
else: raise Exception (f'unknown log type ({t})')
#/**
# ogEcho [str_logtype ...] [str_loglevel] "str_message" ...
#@brief Muestra mensajes en consola y lo registra en fichero de incidencias.
#@param str_logtype tipo de registro de incidencias ("log", "command", "session")
#@param str_loglevel nivel de registro de incidencias ("info", "warning", "error")
#@param str_message mensaje (puede recibir más de 1 parámetro.
#@return Mensaje mostrado.
#*/
def ogEcho (logtypes, loglevel, msg):
logfiles = ['/dev/stdout']
if type (logtypes) is list:
for l in logtypes:
logfiles.append (_logtype2logfile (l))
else: ## string
logfiles.append (_logtype2logfile (logtypes))
if loglevel is None or 'help' == loglevel:
if ogGlobals.DEBUG.lower() != "no":
logfiles.append (ogGlobals.OGLOGFILE)
for f in logfiles:
with open (f, 'a') as fd:
fd.write (msg + '\n')
return
if 'info' == loglevel or 'warning' == loglevel or 'error' == loglevel:
DATETIME = datetime.datetime.now(ZoneInfo(ogGlobals.TZ)).strftime("%F %T %Z")
for f in logfiles:
with open (f, 'a') as fd:
fd.write (f"OpenGnsys {loglevel} {DATETIME} {msg}\n")
else:
raise Exception (f'unknown loglevel ({loglevel})')
#/**
# ogExecAndLog str_logfile ... str_command ...
#@brief Ejecuta un comando y guarda su salida en fichero de registro.
#@param str_logfile fichero de registro (pueden ser varios).
#@param str_command comando y comandos a ejecutar.
#@return Salida de ejecución del comando.
#@note str_logfile = { LOG, SESSION, COMMAND }
#*/
#ogHelp (str_logfile ... str_command ...",
#ogHelp ([], ogMyLib.ogSomeMethod, *args, **kwargs)
#ogHelp ('command', ogMyLib.ogSomeMethod, *args, **kwargs)
#ogHelp (['command'], ogMyLib.ogSomeMethod, *args, **kwargs)
#ogHelp (['log', 'command'], ogMyLib.ogSomeMethod, *args, **kwargs)
def ogExecAndLog (logtypes, fun, *args, **kwargs):
logfiles = ['/dev/stdout']
if type (logtypes) is list:
for l in logtypes:
logtypes = list (map (lambda x: x.lower(), logtypes))
logfiles.append (_logtype2logfile (l))
else: ## string
logtypes = logtypes.lower()
logfiles.append (_logtype2logfile (logtypes))
if not fun:
ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'no function provided')
return
## the original bash code does something like this:
#if [ $ISCOMMAND ]; then
# > $OGLOGCOMMAND
# REDIREC="2>&1"
#fi
#eval $COMMAND $REDIREC | tee -a $FILES
## a hybrid bash/python pseudocode would end up being like the following:
#if 'command' in logtypes:
# rm $OGLOGCOMMAND
# touch $OGLOGCOMMAND
#
#if 'command' in logtypes:
# ## redirect both stdout and stderr
# eval $COMMAND 2>&1 | tee -a $FILES
#else:
# ## redirect stdout only
# eval $COMMAND | tee -a $FILES
sout = serr = ''
if 'command' in logtypes:
os.unlink (ogGlobals.OGLOGCOMMAND)
open (ogGlobals.OGLOGCOMMAND, 'w').close()
with redirect_stdout (StringIO()) as r_stdout, redirect_stderr (StringIO()) as r_stderr:
rc = fun (*args, **kwargs)
sout = r_stdout.getvalue()
serr = r_stderr.getvalue()
else:
with redirect_stdout (StringIO()) as r_stdout:
rc = fun (*args, **kwargs)
sout = r_stdout.getvalue()
rc_str = str (rc)
if sout or serr or ('True' != rc_str and 'False' != rc_str and 'None' != rc_str):
for f in logfiles:
with open (f, 'a') as fd:
if sout: fd.write (f'{sout}\n')
if serr: fd.write (f'{serr}\n')
if rc_str: fd.write (f'{rc_str}\n')
return rc
#/**
# ogGetCaller
#@brief Devuelve nombre del programa o script ejecutor (padre).
#@return str_name - Nombre del programa ejecutor.
#*/
def ogGetCaller():
if 'COLUMNS' in os.environ:
cols = os.environ['COLUMNS']
else:
cols = None
lines = subprocess.run (["ps", "hp", str(os.getppid()), "-o", "args"], capture_output=True, text=True).stdout.splitlines()
if 0 == len (lines):
return ''
line = lines[0]
words = line.split()
if "bash" in line and len(words)>1:
caller = words[1]
else:
caller = words[0].lstrip("-")
if cols is None:
del (os.environ['COLUMNS'])
else:
os.environ['COLUMNS'] = cols
return os.path.basename(caller)
#/**
# ogHelp ["str_function" ["str_format" ["str_example" ... ]]]
#@brief Muestra mensaje de ayuda para una función determinda.
#@param str_function Nombre de la función.
#@param str_format Formato de ejecución de la función.
#@param str_example Ejemplo de ejecución de la función.
#@return str_help - Salida de ayuda.
#@note Si no se indican parámetros, la función se toma de la variable \c $FUNCNAME
#@note La descripción de la función se toma de la variable compuesta por \c MSG_FUNC_$función incluida en el fichero de idiomas.
#@note Pueden especificarse varios mensajes con ejemplos.
#*/
def ogHelp (fname, fmt=None, examples=[]):
FUNC = fname or inspect.stack()[1][3]
MSG = f'ogGlobals.lang.MSG_HELP_{FUNC}'
try:
MSG = eval (MSG)
except:
MSG = ''
ogEcho ([], "help", f"{ogGlobals.lang.MSG_FUNCTION} {FUNC}: {MSG}")
if fmt:
ogEcho([], "help", f" {ogGlobals.lang.MSG_FORMAT}: {fmt}")
if type (examples) is list:
for example in examples:
ogEcho([], "help", f" {ogGlobals.lang.MSG_EXAMPLE}: {example}")
else: ## string
ogEcho([], "help", f" {ogGlobals.lang.MSG_EXAMPLE}: {examples}")
#/**
# ogRaiseError [str_logtype ...] int_errcode ["str_errmessage" ...]
#@brief Devuelve el mensaje y el código de error correspondiente.
#@param str_logtype tipo de registro de incidencias.
#@param int_errcode código de error.
#@param str_errmessage mensajes complementarios de error.
#@return str_code - código de error
#*/
def ogRaiseError (logtypes, code, msg):
if code == ogGlobals.OG_ERR_FORMAT: MSG = f'{ogGlobals.lang.MSG_ERR_FORMAT} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTFOUND: MSG = f'{ogGlobals.lang.MSG_ERR_NOTFOUND} "{msg}"'
elif code == ogGlobals.OG_ERR_OUTOFLIMIT: MSG = f'{ogGlobals.lang.MSG_ERR_OUTOFLIMIT} "{msg}"'
elif code == ogGlobals.OG_ERR_PARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_PARTITION} "{msg}"'
elif code == ogGlobals.OG_ERR_LOCKED: MSG = f'{ogGlobals.lang.MSG_ERR_LOCKED} "{msg}"'
elif code == ogGlobals.OG_ERR_CACHE: MSG = f'{ogGlobals.lang.MSG_ERR_CACHE} "{msg}"'
elif code == ogGlobals.OG_ERR_NOGPT: MSG = f'{ogGlobals.lang.MSG_ERR_NOGPT} "{msg}"'
elif code == ogGlobals.OG_ERR_REPO: MSG = f'{ogGlobals.lang.MSG_ERR_REPO} "{msg}"'
elif code == ogGlobals.OG_ERR_FILESYS: MSG = f'{ogGlobals.lang.MSG_ERR_FILESYS} "{msg}"'
elif code == ogGlobals.OG_ERR_IMAGE: MSG = f'{ogGlobals.lang.MSG_ERR_IMAGE} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTOS: MSG = f'{ogGlobals.lang.MSG_ERR_NOTOS} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTEXEC: MSG = f'{ogGlobals.lang.MSG_ERR_NOTEXEC} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTWRITE: MSG = f'{ogGlobals.lang.MSG_ERR_NOTWRITE} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTCACHE: MSG = f'{ogGlobals.lang.MSG_ERR_NOTCACHE} "{msg}"'
elif code == ogGlobals.OG_ERR_CACHESIZE: MSG = f'{ogGlobals.lang.MSG_ERR_CACHESIZE} "{msg}"'
elif code == ogGlobals.OG_ERR_REDUCEFS: MSG = f'{ogGlobals.lang.MSG_ERR_REDUCEFS} "{msg}"'
elif code == ogGlobals.OG_ERR_EXTENDFS: MSG = f'{ogGlobals.lang.MSG_ERR_EXTENDFS} "{msg}"'
elif code == ogGlobals.OG_ERR_IMGSIZEPARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_IMGSIZEPARTITION} "{msg}"'
elif code == ogGlobals.OG_ERR_UPDATECACHE: MSG = f'{ogGlobals.lang.MSG_ERR_UPDATECACHE} "{msg}"'
elif code == ogGlobals.OG_ERR_DONTFORMAT: MSG = f'{ogGlobals.lang.MSG_ERR_DONTFORMAT} "{msg}"'
elif code == ogGlobals.OG_ERR_IMAGEFILE: MSG = f'{ogGlobals.lang.MSG_ERR_IMAGEFILE} "{msg}"'
elif code == ogGlobals.OG_ERR_UCASTSYNTAXT: MSG = f'{ogGlobals.lang.MSG_ERR_UCASTSYNTAXT} "{msg}"'
elif code == ogGlobals.OG_ERR_UCASTSENDPARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_UCASTSENDPARTITION} "{msg}"'
elif code == ogGlobals.OG_ERR_UCASTSENDFILE: MSG = f'{ogGlobals.lang.MSG_ERR_UCASTSENDFILE} "{msg}"'
elif code == ogGlobals.OG_ERR_UCASTRECEIVERPARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_UCASTRECEIVERPARTITION} "{msg}"'
elif code == ogGlobals.OG_ERR_UCASTRECEIVERFILE: MSG = f'{ogGlobals.lang.MSG_ERR_UCASTRECEIVERFILE} "{msg}"'
elif code == ogGlobals.OG_ERR_MCASTSYNTAXT: MSG = f'{ogGlobals.lang.MSG_ERR_MCASTSYNTAXT} "{msg}"'
elif code == ogGlobals.OG_ERR_MCASTSENDFILE: MSG = f'{ogGlobals.lang.MSG_ERR_MCASTSENDFILE} "{msg}"'
elif code == ogGlobals.OG_ERR_MCASTRECEIVERFILE: MSG = f'{ogGlobals.lang.MSG_ERR_MCASTRECEIVERFILE} "{msg}"'
elif code == ogGlobals.OG_ERR_MCASTSENDPARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_MCASTSENDPARTITION} "{msg}"'
elif code == ogGlobals.OG_ERR_MCASTRECEIVERPARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_MCASTRECEIVERPARTITION} "{msg}"'
elif code == ogGlobals.OG_ERR_PROTOCOLJOINMASTER: MSG = f'{ogGlobals.lang.MSG_ERR_PROTOCOLJOINMASTER} "{msg}"'
elif code == ogGlobals.OG_ERR_DONTMOUNT_IMAGE: MSG = f'{ogGlobals.lang.MSG_ERR_DONTMOUNT_IMAGE} "{msg}"'
elif code == ogGlobals.OG_ERR_DONTUNMOUNT_IMAGE: MSG = f'{ogGlobals.lang.MSG_ERR_DONTUNMOUNT_IMAGE} "{msg}"'
elif code == ogGlobals.OG_ERR_DONTSYNC_IMAGE: MSG = f'{ogGlobals.lang.MSG_ERR_DONTSYNC_IMAGE} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTDIFFERENT: MSG = f'{ogGlobals.lang.MSG_ERR_NOTDIFFERENT} "{msg}"'
elif code == ogGlobals.OG_ERR_SYNCHRONIZING: MSG = f'{ogGlobals.lang.MSG_ERR_SYNCHRONIZING} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTUEFI: MSG = f'{ogGlobals.lang.MSG_ERR_NOTUEFI} "{msg}"'
elif code == ogGlobals.OG_ERR_NOMSDOS: MSG = f'{ogGlobals.lang.MSG_ERR_NOMSDOS} "{msg}"'
elif code == ogGlobals.OG_ERR_NOTBIOS: MSG = f'{ogGlobals.lang.MSG_ERR_NOTBIOS} "{msg}"'
else:
MSG = ogGlobals.lang.MSG_ERR_GENERIC
CODE = ogGlobals.OG_ERR_GENERIC
# Obtener lista de funciones afectadas, incluyendo el script que las llama.
call_stack = [i[3] for i in inspect.stack()]
if len (call_stack) < 2: return ## shouldn't happen
call_stack.pop() ## remove '<module>'
call_stack.pop(0) ## remove 'ogRaiseError'
str_call_stack = ' '.join (call_stack)
# Mostrar mensaje de error si es función depurable y salir con el código indicado.
if code == ogGlobals.OG_ERR_FORMAT or \
(str_call_stack in ogGlobals.NODEBUGFUNCTIONS) or \
not (len(call_stack)>0 and (call_stack[0] in ogGlobals.NODEBUGFUNCTIONS)):
ogEcho (logtypes, "error", f"{str_call_stack.replace(' ', '<-')}: {MSG}")
return code
#/**
# ogIsRepoLocked
#@brief Comprueba si el repositorio está siendo usado (tiene ficheros abiertos).
#@param No.
#@return Código de salida: 0 - bloqueado, 1 - sin bloquear o error.
#*/
def ogIsRepoLocked():
# No hacer nada, si no está definido el punto de montaje del repositorio.
if not ogGlobals.OGIMG:
return False
# Comprobar si alguno de los ficheros abiertos por los procesos activos está en el
# punto de montaje del repositorio de imágenes.
proc_entries = glob.glob ('/proc/[0-9]*/fd/*')
for e in proc_entries:
p = os.path.realpath (e)
if ogGlobals.OGIMG in p:
return True
return False
## has no users
#def ogCheckProgram(program):
# FUNCNAME = ogCheckProgram.__name__
#
# if not program or not isinstance(program, str):
# SystemLib.ogRaiseError ("session", ogGlobals.OG_ERR_FORMAT, f"Error: {ogGlobals.lang.MSG_ERR_FORMAT} {FUNCNAME} \"program\"")
# return
#
# if not shutil.which(program):
# SystemLib.ogRaiseError ( "session", ogGlobals.OG_ERR_NOTEXEC, f"Error: The program '{program}' is not available on the system.")
# return
#
# return 0
def ogIsVirtualMachine():
output = subprocess.run (["dmidecode", "-s", "system-product-name"], capture_output=True, text=True).stdout
return "KVM" in output or "VirtualBox" in output

View File

@ -0,0 +1,679 @@
#!/bin/bash
# Libreria provisional para uso de UEFI
# Las funciones se incluirán las librerías ya existentes
#/**
# ogNvramActiveEntry
#@brief Activa entrada de la NVRAM identificada por la etiqueta o el orden
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
function ogNvramActiveEntry () {
local NUMENTRY
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [ Num_order_entry | Label_entry ] " \
"$FUNCNAME 2" \
"$FUNCNAME \"Windows Boot Manager\""
return
fi
# Error si no se recibe 1 parámetro.
[ $# -eq 1 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME [ Num_order_entry | Label_entry ]" || return $?
# Si no es equipo UEFI salir con error
ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
# Distingo si es número de orden o etiqueta
if [[ $1 =~ ^([0-9a-fA-F]+)$ ]]; then
NUMENTRY=$( efibootmgr |awk -v NUM="$(printf %04x 0x$1|tr '[:lower:]' '[:upper:]')" '{ if($1~NUM) print substr($1,5,4)}')
else
NUMENTRY=$(efibootmgr |awk -v LABEL="$1" '{ if(substr($0, index($0,$2))==LABEL) print substr($1,5,4)}')
fi
[ "$NUMENTRY" == "" ] && return $(ogRaiseError $OG_ERR_NOTFOUND "NVRAM entry '$1'")
efibootmgr -a -b $NUMENTRY &>/dev/null
}
#/**
# ogNvramAddEntry
#@brief Crea nueva entrada en el gestor de arranque (NVRAM), opcionalmente la incluye al final del orden de arranque.
#@param Str_Label_entry Número de disco o etiqueta de la entrada a crear.
#@param Str_BootLoader Número de partición o cargador de arranque.
#@param Bool_Incluir_Arranque Incluir en el orden de arranque (por defecto FALSE) (opcional)
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
function ogNvramAddEntry () {
local EFIDISK EFIPART BOOTLABEL BOOTLOADER ADDORDER
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME Str_label_entry Str_boot_loader [ Bool_add_bootorder ]" \
"$FUNCNAME 1 2 TRUE" \
"$FUNCNAME grub /EFI/grub/grubx64.efi TRUE" \
"$FUNCNAME Windows /EFI/Microsoft/Boot/bootmgfw.efi"
return
fi
# Error si no se recibe 1 parámetro.
[ $# -ge 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME Str_label_entry Str_boot_locader" || return $?
# Si no es equipo UEFI salir con error
ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
read -e EFIDISK EFIPART <<<"$(ogGetEsp)"
[ -n "$EFIPART" ] || ogRaiseError $OG_ERR_NOTFOUND "ESP" || return $?
# Recogemos parámetros
# Distinguimos si es disco/partición o etiqueta/cargador
if [[ "$1$2" =~ ^([0-9]+)$ ]]; then
BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2)
BOOTLOADER="/EFI/$BOOTLABEL/Boot/ogloader.efi"
else
BOOTLABEL="$1"
BOOTLOADER="$2"
fi
# Si existe entrada con la misma etiqueta la borramos
ogNvramDeleteEntry "$BOOTLABEL" 2>/dev/null
efibootmgr -C -d $(ogDiskToDev $EFIDISK) -p $EFIPART -L "$BOOTLABEL" -l "$BOOTLOADER" &>/dev/null
# Incluimos la entrada en el orden de arranque (opcional)
if [ "${3^^}" == "TRUE" ]; then
NUMENTRY=$(efibootmgr |awk -v LABEL="$BOOTLABEL" '{ if(substr($0, index($0,$2))==LABEL) print substr($1,5,4)}')
ogNvramSetOrder $(ogNvramGetOrder |tr , " ") $NUMENTRY
fi
}
#/**
# ogCopyEfiBootLoader int_ndisk str_repo path_image
#@brief Copia el cargador de arranque desde la partición EFI a la de sistema.
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@note Si existe el cargador en la partición de sistema no es válido
#*/ ##
function ogCopyEfiBootLoader () {
# Variables locales
local MNTDIR EFIDIR BOOTLABEL OSVERSION LOADER f
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part" \
"$FUNCNAME 1 2"
return
fi
# Error si no se reciben 2 arámetros.
[ $# == 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part" || return $?
# Comprobamos que exista partición de sistema y la ESP
MNTDIR=$(ogMount $1 $2) || ogRaiseError $OG_ERR_PARTITION "$DISK $PART" || return $?
EFIDIR=$(ogMount $(ogGetEsp)) || ogRaiseError $OG_ERR_PARTITION "ESP" || return $?
# Comprobamos que exista el cargador
BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2)
OSVERSION=$(ogGetOsVersion $1 $2)
case $OSVERSION in
*Windows\ 10*)
for f in $EFIDIR/EFI/{Microsoft,$BOOTLABEL}/Boot/bootmgfw.efi; do
[ -r $f ] && LOADER=$f
done
[ -n "$LOADER" ] || ogRaiseError $OG_ERR_NOTOS "$1 $2 ($OSVERSION, EFI)" || return $?
# Si existe el directorio Boot lo borramos
[ -d $MNTDIR/ogBoot ] && rm -rf $MNTDIR/ogBoot
DIRLOADER=$(realpath "${LOADER%/*}/..")
cp -r ${DIRLOADER}/Boot $MNTDIR/ogBoot
;;
esac
}
#/**
# ogNvramDeleteEntry
#@brief Borra entrada de la NVRAM identificada por la etiqueta o el orden
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado (entrada en NVRAM).
#*/ ##
function ogNvramDeleteEntry () {
local NUMENTRY n
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [ Num_order_entry | Label_entry ] " \
"$FUNCNAME 2" \
"$FUNCNAME \"Windows Boot Manager\""
return
fi
# Error si no se recibe 1 parámetro.
[ $# -eq 1 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME [ Num_order_entry | Label_entry ]" || return $?
# Si no es equipo UEFI salir con error
ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
# Distingo si es número de orden o etiqueta
if [[ $1 =~ ^([0-9a-fA-F]+)$ ]]; then
NUMENTRY=$( efibootmgr |awk -v NUM="$(printf %04x 0x$1|tr '[:lower:]' '[:upper:]')" '{ if($1~NUM) print substr($1,5,4)}')
else
NUMENTRY=$(efibootmgr |awk -v LABEL="$1" '{ if(substr($0, index($0,$2))==LABEL) print substr($1,5,4)}')
fi
[ "$NUMENTRY" == "" ] && return $(ogRaiseError $OG_ERR_NOTFOUND "NVRAM entry '$1'")
for n in $NUMENTRY; do
efibootmgr -B -b $n &>/dev/null
done
}
#/**
# ogNvramGetCurrent
#@brief Muestra la entrada del gestor de arranque (NVRAM) que ha iniciado el equipo.
#@return Entrada con la que se ha iniciado el equipo
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
function ogNvramGetCurrent () {
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" \
"$FUNCNAME"
return
fi
# Si no es equipo UEFI salir con error
ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
efibootmgr| awk -v bootentry=99999 '{if ($1~/BootCurrent/) bootentry=$2; if ($1~bootentry) printf "%s %s %s\n", gensub(/^0{1,3}/,"",1,substr($1,5,4))," ", substr($0, index($0,$2))}'
}
# ogNvramGetNext
#@brief Muestra la entrada del gestor de arranque (NVRAM) que se utilizará en el próximo arranque.
#@return Entrada que se utilizará en el próximo arranque
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
function ogNvramGetNext () {
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" \
"$FUNCNAME"
return
fi
# Si no es equipo UEFI salir con error
ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
efibootmgr|awk '{ if ($1 == "BootNext:") print $2}'
}
# ogNvramGetOrder
#@brief Muestra el orden de las entradas del gestor de arranque (NVRAM)
#@return Orden de las entradas
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
function ogNvramGetOrder () {
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" \
"$FUNCNAME"
return
fi
# Si no es equipo UEFI salir con error
ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
efibootmgr|awk '{ if ($1 == "BootOrder:") print $2}'
}
#/**
# ogNvramGetTimeout
#@brief Muestra el tiempo de espera del gestor de arranque (NVRAM)
#@return Timeout de la NVRAM
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
function ogNvramGetTimeout () {
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" \
"$FUNCNAME"
return
fi
# Si no es equipo UEFI salir con error
ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
efibootmgr|awk '{ if ($1 == "Timeout:") print substr($0, index($0,$2))}'
}
#/**
# ogGrubUefiConf int_ndisk int_part str_dir_grub
#@brief Genera el fichero grub.cfg de la ESP
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@param str_dir_grub prefijo del directorio de grub en la partición de sistema. ej: /boot/grubPARTITION
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@TODO Confirmar si el fichero "$EFIDIR/EFI/$BOOTLABEL/grub.cfg" es necesario.
#*/ ##
function ogGrubUefiConf () {
local EFIDIR BOOTLABEL GRUBEFI UUID DEVICE PREFIXSECONDSTAGE EFIGRUBDIR
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part [ str_dir_grub ]" \
"$FUNCNAME 1 2" \
"$FUNCNAME 1 3 /boot/grubPARTITION"
return
fi
# Error si no se reciben al menos 2 parámetros.
[ $# -ge 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part [ str_dir_grub ]" || return $?
# Directorio del grub en la partición de sistema
PREFIXSECONDSTAGE="$3"
EFIDIR=$(ogMount $(ogGetEsp)) || ogRaiseError $OG_ERR_PARTITION "ESP" || return $?
BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2)
EFIGRUBDIR="$EFIDIR/EFI/$BOOTLABEL/boot/grub"
# Comprobamos que existe directorio
[ -d "$EFIGRUBDIR" ] || mkdir -p "$EFIGRUBDIR"
# Parcheamos uuid y particion en grub.cfg
UUID=$(blkid -o value -s UUID $(ogDiskToDev $1 $2))
DEVICE="hd$(expr $1 - 1 ),gpt$2"
cat << EOT > $EFIGRUBDIR/grub.cfg
set root='$DEVICE'
set prefix=(\$root)'${PREFIXSECONDSTAGE}/boot/grub'
configfile \$prefix/grub.cfg
EOT
# Provisional: confirmar si el segundo archivo se utiliza
cp $EFIGRUBDIR/grub.cfg "$EFIDIR/EFI/$BOOTLABEL/grub.cfg"
}
#/**
# ogNvramInactiveEntry
#@brief Inactiva entrada de la NVRAM identificada por la etiqueta o el orden
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
function ogNvramInactiveEntry () {
local NUMENTRY
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [ Num_order_entry | Label_entry ] " \
"$FUNCNAME 2" \
"$FUNCNAME \"Windows Boot Manager\""
return
fi
# Error si no se recibe 1 parámetro.
[ $# -eq 1 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME [ Num_order_entry | Label_entry ]" || return $?
# Si no es equipo UEFI salir con error
ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
# Distingo si es número de orden o etiqueta
if [[ $1 =~ ^([0-9a-fA-F]+)$ ]]; then
NUMENTRY=$( efibootmgr |awk -v NUM="$(printf %04x 0x$1|tr '[:lower:]' '[:upper:]')" '{ if($1~NUM) print substr($1,5,4)}')
else
NUMENTRY=$(efibootmgr |awk -v LABEL="$1" '{ if(substr($0, index($0,$2))==LABEL) print substr($1,5,4)}')
fi
[ "$NUMENTRY" == "" ] && return $(ogRaiseError $OG_ERR_NOTFOUND "NVRAM entry '$1'")
efibootmgr -A -b $NUMENTRY &>/dev/null
}
#/**
# ogNvramList
#@brief Lista las entradas de la NVRAN (sólo equipos UEFI)
#@return Entradas de la NVRAM con el formato: orden etiqueta [* (si está activa) ]
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
function ogNvramList () {
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" \
"$FUNCNAME"
return
fi
# Si no es equipo UEFI salir con error
ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
efibootmgr |awk '{if($1~/Boot[[:digit:]]/) ; active="" ;if ($1~/*/) active="*"; if($1~/Boot[[:digit:]]/) printf "%4s %s %s %s\n", gensub(/^0{1,3}/,"",1,substr($1,5,4))," ", substr($0, index($0,$2)), active}'
}
#/**
# ogNvramPxeFirstEntry
#@brief Sitúa la entrada de la tarjeta de red en el primer lugar en la NVRAM.
#@return (nada)
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
function ogNvramPxeFirstEntry (){
local NUMENTRY ORDER
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME" \
"$FUNCNAME"
return
fi
# Si no es equipo UEFI salir con error
ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
NUMENTRY=$(printf %04X 0x$(efibootmgr|awk '/IP[vV]{0,1}4/ {print gensub(/^0{1,3}/,"",1,substr($1,5,4))}'))
# Si la entrada es la primera nos salimos.
[[ $(ogNvramGetOrder) =~ ^$NUMENTRY ]] && return
# Si la entrada ya existe la borramos.
ORDER="$NUMENTRY $(ogNvramGetOrder| sed -e s/$NUMENTRY//g -e s/,/' '/g)"
ogNvramSetOrder $ORDER
}
#/**
# ogRestoreEfiBootLoader int_ndisk str_repo
#@brief Copia el cargador de arranque de la partición de sistema a la partición EFI.
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado (partición de sistema o EFI).
#@exception OG_ERR_NOTOS sin sistema operativo.
#*/ ##
function ogRestoreEfiBootLoader () {
# Variables locales
local MNTDIR EFIDIR BOOTLABEL OSVERSION LOADER f UUID DEVICE
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part" \
"$FUNCNAME 1 2"
return
fi
# Error si no se reciben 2 arámetros.
[ $# == 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part" || return $?
# Comprobamos que exista partición de sistema y la ESP
MNTDIR=$(ogMount $1 $2) || ogRaiseError $OG_ERR_PARTITION "$DISK $PART" || return $?
EFIDIR=$(ogMount $(ogGetEsp))
if [ "$EFIDIR" == "" ]; then
ogFormat $(ogGetEsp) FAT32
EFIDIR=$(ogMount $(ogGetEsp)) || ogRaiseError $OG_ERR_PARTITION "ESP" || return $?
fi
# Comprobamos que exista el cargador
#BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2)
OSVERSION=$(ogGetOsVersion $1 $2)
case $OSVERSION in
*Windows\ 10*)
BOOTLABEL=$(printf "Part-%02d-%02d" $1 $2)
LOADER=$(ogGetPath $MNTDIR/ogBoot/bootmgfw.efi)
[ -n "$LOADER" ] || ogRaiseError $OG_ERR_NOTOS "$1 $2 ($OSVERSION, EFI)" || return $?
[ -r $EFIDIR/EFI/$BOOTLABEL ] && rm -rf $EFIDIR/EFI/$BOOTLABEL
mkdir -p $EFIDIR/EFI/$BOOTLABEL
cp -r "${LOADER%/*}" $EFIDIR/EFI/$BOOTLABEL/Boot
# Nombre OpenGnsys para cargador
cp $LOADER $EFIDIR/EFI/$BOOTLABEL/Boot/ogloader.efi
# Si existe subcarpeta Microsoft en la partición EFI la renombramos
[ "$(ogGetPath $EFIDIR/EFI/Microsoft)" == "" ] || mv $EFIDIR/EFI/{Microsoft,Microsoft.backup.og}
;;
esac
}
#/**
# ogRestoreUuidPartitions
#@brief Restaura los uuid de las particiones y la tabla de particiones
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@param REPO|CACHE repositorio
#@param str_imgname nombre de la imagen
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND No encontrado fichero de información de la imagen (con uuid)
#*/ ##
function ogRestoreUuidPartitions () {
local DISK PART IMGNAME INFOFILE DEVICE DATA GUID UUID IMGGUID
local EFIDEVICE EFIDATA EFIGUID EFIUUID EFIUUID IMGEFIGUID
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME REPO|CACHE str_imgname int_ndisk int_npart" \
"$FUNCNAME REPO Windows 1 2"
return
fi
# Error si no se reciben 4 parámetros.
[ $# -eq 4 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME REPO|CACHE str_imgname int_ndisk int_npart" || return $?
# Sólo se ejecuta si es UEFI
ogIsEfiActive || return
# Parámetros de entrada
IMGNAME="$2"
INFOFILE="$OGIMG/.$IMGNAME.img.json"
[ "${1^^}" == "CACHE" ] && INFOFILE="$OGCAC$INFOFILE"
# TODO: que la función getPath soporte archivos ocultos
ls $INFOFILE &>/dev/null || ogRaiseError $OG_ERR_NOTFOUND "$INFOFILE" || return $?
DISK=$3
PART=$4
DEVICE=$(ogDiskToDev $DISK)
read -e EFIDISK EFIPART <<<"$(ogGetEsp)"
# Datos de la imagen
IMGGUID=$(jq .guid $INFOFILE|tr -d \")
IMGEFIGUID=$(jq .espguid $INFOFILE|tr -d \")
# Datos actuales
DATA=$(sfdisk -J $DEVICE)
GUID=$(echo $DATA|jq ".partitiontable|.id"|tr -d \")
if [ "$IMGGUID" != "$GUID" ]; then
echo sgdisk -U "$IMGGUID" "$DEVICE"
sgdisk -U "$IMGGUID" "$DEVICE"
partprobe
fi
if [ $DISK -eq $EFIDISK ]; then
EFIDATA=$DATA
EFIDEVICE=$DEVICE
else
EFIDEVICE=$(ogDiskToDev $EFIDISK) || return $?
EFIDATA=$(sfdisk -J $EFIDEVICE)
EFIGUID=$(echo $EFIDATA|jq ".partitiontable|.id"|tr -d \")
if [ "$IMGEFIGUID" != "$EFIGUID" ]; then
echo sgdisk -U "$IMGEFIGUID" "$EFIDEVICE"
sgdisk -U "$IMGEFIGUID" "$EFIDEVICE"
partprobe
fi
fi
}
#/**
# ogNvramSetNext
#@brief Configura el próximo arranque con la entrada del gestor de arranque (NVRAM) identificada por la etiqueta o el orden.
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
function ogNvramSetNext () {
local NUMENTRY
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME [ Num_order_entry | Label_entry ] " \
"$FUNCNAME 2" \
"$FUNCNAME \"Windows Boot Manager\""
return
fi
# Error si no se recibe 1 parámetro.
[ $# -eq 1 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME [ Num_order_entry | Label_entry ]" || return $?
# Si no es equipo UEFI salir con error
ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
# Distingo si es número de orden o etiqueta
if [[ $1 =~ ^([0-9a-fA-F]+)$ ]]; then
NUMENTRY=$( efibootmgr |awk -v NUM="$(printf %04x 0x$1|tr '[:lower:]' '[:upper:]')" '{ if($1~NUM) print substr($1,5,4)}')
else
NUMENTRY=$(efibootmgr | awk -v LABEL="$1" '$0 ~ LABEL { print substr($1,5,4) }')
fi
[ "$NUMENTRY" == "" ] && return $(ogRaiseError $OG_ERR_NOTFOUND "NVRAM entry '$1'")
efibootmgr -n $NUMENTRY &>/dev/null
}
#/**
# ogNvramSetOrder
#@brief Configura el orden de las entradas de la NVRAM
#@param Orden de las entradas separadas por espacios
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado (entrada NVRAM).
#*/ ##
function ogNvramSetOrder () {
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME Num_order1 [ Num_order2 ] ... " \
"$FUNCNAME 1 3"
return
fi
#
# Error si no se recibe al menos 1 parámetro.
[ $# -ge 1 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME Num_order1 [ Num_order2 ] ..." || return $?
# Si no es equipo UEFI salir con error
ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
# Comprobamos que sean números
[[ "$@" =~ ^([0-9a-fA-F ]+)$ ]] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME Num_order1 [ Num_order2 ] ..." || return $?
# Entradas de la NVRAM actuales
NUMENTRYS=$(efibootmgr|awk '{ if ($1~/Boot[0-9a-fA-F]{4}/) printf "0%s ", substr($1,5,4)}')
ORDER=""
for ARG in $@; do
# Si no existe la entrada me salgo
ARG=$(printf %04X 0x$ARG)
echo $NUMENTRYS | grep "$ARG" &>/dev/null || ogRaiseError $OG_ERR_NOTFOUND "NVRAM entry order \"$ARG\"" || return $?
ORDER=${ORDER},$ARG
done
# Cambiamos el orden
efibootmgr -o ${ORDER#,} &>/dev/null
}
#/**
# ogNvramSetTimeout
#@brief Configura el tiempo de espera de la NVRAM
#@param Orden de las entradas separadas por espacios
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
function ogNvramSetTimeout () {
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_Timeout (seg)" \
"$FUNCNAME 2"
return
fi
#
# Si no es equipo UEFI salir con error
ogIsEfiActive || ogRaiseError $OG_ERR_NOTUEFI || return $?
# Error si no se recibe 1 parámetro.
[ $# -eq 1 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_Timeout (seg)" || return $?
# Comprobamos que sea un número
[[ "$1" =~ ^([0-9 ]+)*$ ]] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_Timeout (seg)" || return $?
# Cambiamos el orden
efibootmgr -t $1 &>/dev/null
}
#/**
# ogUuidChange int_ndisk str_repo
#@brief Reemplaza el UUID de un sistema de ficheros.
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
function ogUuidChange () {
local MNTDIR DEVICE UUID NEWUUID f
# Si se solicita, mostrar ayuda.
if [ "$*" == "help" ]; then
ogHelp "$FUNCNAME" "$FUNCNAME int_ndisk int_part" \
"$FUNCNAME 1 2"
return
fi
# Error si no se reciben al menos 2 parámetros.
[ $# -eq 2 ] || ogRaiseError $OG_ERR_FORMAT "$FUNCNAME int_ndisk int_part" || return $?
# Comprobamos que exista la partición
MNTDIR=$(ogMount $1 $2) || ogRaiseError $OG_ERR_NOTFOUND "Device $1 $2" || return $?
DEVICE=$(ogDiskToDev $1 $2)
UUID=$(blkid -o value -s UUID $DEVICE)
NEWUUID=$(cat /proc/sys/kernel/random/uuid)
# Cambiamos UUID a la partición
ogUnmount $1 $2
tune2fs $DEVICE -U $NEWUUID
# Cambiamos UUID en la configuración (fstab y grub)
ogMount $1 $2
for f in $MNTDIR/etc/fstab $MNTDIR/{,boot/}{{grubMBR,grubPARTITION}/boot/,}{grub{,2},{,efi/}EFI/*}/{menu.lst,grub.cfg}; do
[ -r $f ] && sed -i s/$UUID/$NEWUUID/g $f
done
}

View File

@ -1,579 +0,0 @@
import os.path
import re
import subprocess
import shutil
import ogGlobals
import SystemLib
import FileSystemLib
import DiskLib
import FileLib
import InventoryLib
#!/bin/bash
# Libreria provisional para uso de UEFI
# Las funciones se incluirán las librerías ya existentes
#/**
# ogNvramActiveEntry
#@brief Activa entrada de la NVRAM identificada por la etiqueta o el orden
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
#ogNvramActiveEntry ('2')
#ogNvramActiveEntry ('Windows Boot Manager')
def ogNvramActiveEntry (entry):
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
numentries = []
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
try:
foo = int (entry, 16) ## raises ValueError if entry doesn't look like hexadecimal
num = f'{foo:04x}'.upper()
for l in efibootmgr_out.splitlines():
words = l.split()
if len(words) < 2: continue
if num in words[0]:
numentries.append (words[0][4:8])
except ValueError:
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if words[1] == entry:
numentries.append (words[0][4:8])
if not numentries:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'NVRAM entry "{entry}"')
return
if 1 != len(numentries):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, f'more than one entry found')
return
subprocess.run (['efibootmgr', '-a', '-b', numentries[0]], capture_output=True, text=True)
#/**
# ogNvramAddEntry
#@brief Crea nueva entrada en el gestor de arranque (NVRAM), opcionalmente la incluye al final del orden de arranque.
#@param Str_Label_entry Número de disco o etiqueta de la entrada a crear.
#@param Str_BootLoader Número de partición o cargador de arranque.
#@param Bool_Incluir_Arranque Incluir en el orden de arranque (por defecto FALSE) (opcional)
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
#ogNvramAddEntry ('1', '2', True)
#ogNvramAddEntry ('grub', '/EFI/grub/grubx64.efi', True)
#ogNvramAddEntry ('Windows', '/EFI/Microsoft/Boot/bootmgfw.efi')
def ogNvramAddEntry (bootlbl, bootldr, nvram_set=False):
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
esp = DiskLib.ogGetEsp()
if not esp:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'ESP')
return
efidisk, efipar = esp.split()
try:
foo = int(bootlbl) + int(bootldr) ## raises ValueError if bootlbl/bootldr don't look like numbers
bootlabel = f'Part-{int(bootlbl):02d}-{int(bootldr):02d}'
bootloader = f'/EFI/{bootlabel}/Boot/ogloader.efi'
except ValueError:
bootlabel = bootlbl
bootloader = bootldr
ogNvramDeleteEntry (bootlabel)
dev = DiskLib.ogDiskToDev (efidisk)
subprocess.run (['efibootmgr', '-C', '-d', dev, '-p', efipar, '-L', bootlabel, '-l', bootloader])
if nvram_set:
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if words[1] == bootlabel:
numentry = words[0][4:8]
order = ogNvramGetOrder()
ogNvramSetOrder (order + [numentry])
#/**
# ogCopyEfiBootLoader int_ndisk str_repo path_image
#@brief Copia el cargador de arranque desde la partición EFI a la de sistema.
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@note Si existe el cargador en la partición de sistema no es válido
#*/ ##
def ogCopyEfiBootLoader (disk, par):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}')
return None
esp = DiskLib.ogGetEsp()
if not esp:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'EFI partition')
return
esp_disk, esp_par = esp.split()
efidir = FileSystemLib.ogMount (esp_disk, esp_par)
if not efidir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'ESP')
return
bootlabel = f'Part-{int(disk):02d}-{int(par):02d}'
osversion = InventoryLib.ogGetOsVersion (disk, par)
print (f'bootlabel ({bootlabel})')
print (f'osversion ({osversion})')
if 'Windows 1' in osversion:
loader = None
for i in f'{efidir}/EFI/Microsoft/Boot/bootmgfw.efi', f'{efidir}/EFI/{bootlabel}/Boot/bootmgfw.efi':
if os.path.exists (i):
loader = i
if not loader:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk} {par} ({osversion}, EFI)')
return None
if (os.path.isdir (f'{mntdir}/ogBoot')):
shutil.rmtree (f'{mntdir}/ogBoot')
dirloader = os.path.realpath (os.path.dirname (loader) + '/..')
shutil.copytree (f'{dirloader}/Boot', f'{mntdir}/ogBoot')
#/**
# ogNvramDeleteEntry
#@brief Borra entrada de la NVRAM identificada por la etiqueta o el orden
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado (entrada en NVRAM).
#*/ ##
#ogNvramDeleteEntry ('2')
#ogNvramDeleteEntry ('Windows Boot Manager')
def ogNvramDeleteEntry (entry):
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
numentries = []
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
try:
foo = int (entry, 16) ## raises ValueError if entry doesn't look like hexadecimal
num = f'{foo:04x}'.upper()
for l in efibootmgr_out.splitlines():
words = l.split()
if len(words) < 2: continue
if num in words[0]:
numentries.append (words[0][4:8])
except ValueError:
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if words[1] == entry:
numentries.append (words[0][4:8])
if not numentries:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'NVRAM entry "{entry}"')
return
if 1 != len(numentries):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, f'more than one entry found')
return
subprocess.run (['efibootmgr', '-B', '-b', numentries[0]], capture_output=True, text=True)
#/**
# ogNvramGetCurrent
#@brief Muestra la entrada del gestor de arranque (NVRAM) que ha iniciado el equipo.
#@return Entrada con la que se ha iniciado el equipo
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
def ogNvramGetCurrent():
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
bootentry = '9999'
ret = None
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if 'BootCurrent' in words[0]:
bootentry = words[1]
continue
if bootentry in words[0]:
num = words[0][4:8].strip ('0') or '0'
ret = f'{num} {words[1]}'
return ret
# ogNvramGetNext
#@brief Muestra la entrada del gestor de arranque (NVRAM) que se utilizará en el próximo arranque.
#@return Entrada que se utilizará en el próximo arranque
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
def ogNvramGetNext():
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
ret = None
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if 'BootNext' in words[0]:
ret = words[1]
return ret
# ogNvramGetOrder
#@brief Muestra el orden de las entradas del gestor de arranque (NVRAM)
#@return Array, orden de las entradas
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
def ogNvramGetOrder():
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
ret = []
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
words = l.split()
if len(words) < 2: continue
if 'BootOrder:' == words[0]:
ret = words[1].split (',')
return ret
#/**
# ogNvramGetTimeout
#@brief Muestra el tiempo de espera del gestor de arranque (NVRAM)
#@return Timeout de la NVRAM
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
def ogNvramGetTimeout():
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
ret = None
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if 'Timeout:' == words[0]:
ret = words[1]
return ret
#/**
# ogGrubUefiConf int_ndisk int_part str_dir_grub
#@brief Genera el fichero grub.cfg de la ESP
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@param str_dir_grub prefijo del directorio de grub en la partición de sistema. ej: /boot/grubPARTITION
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@TODO Confirmar si el fichero "$EFIDIR/EFI/$BOOTLABEL/grub.cfg" es necesario.
#*/ ##
#/**
# ogNvramInactiveEntry
#@brief Inactiva entrada de la NVRAM identificada por la etiqueta o el orden
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
#ogNvramInactiveEntry ('2')
#ogNvramInactiveEntry ('Windows Boot Manager')
def ogNvramInactiveEntry (entry):
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
numentries = []
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
try:
foo = int (entry, 16) ## raises ValueError if entry doesn't look like hexadecimal
num = f'{foo:04x}'.upper()
for l in efibootmgr_out.splitlines():
words = l.split()
if len(words) < 2: continue
if num in words[0]:
numentries.append (words[0][4:8])
except ValueError:
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if words[1] == entry:
numentries.append (words[0][4:8])
if not numentries:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'NVRAM entry "{entry}"')
return
if 1 != len(numentries):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, f'more than one entry found')
return
subprocess.run (['efibootmgr', '-A', '-b', numentries[0]], capture_output=True, text=True)
#/**
# ogNvramList
#@brief Lista las entradas de la NVRAN (sólo equipos UEFI)
#@return Multiline string: entradas de la NVRAM con el formato: orden etiqueta [* (si está activa) ]
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
def ogNvramList():
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
ret = ''
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if re.search ('Boot[0-9]', words[0]):
active = '*' if '*' in words[0] else ''
num = words[0][4:8].strip ('0') or '0'
ret += '{:>4s} {} {}\n'.format (num, words[1], active)
return ret
#/**
# ogNvramPxeFirstEntry
#@brief Sitúa la entrada de la tarjeta de red en el primer lugar en la NVRAM.
#@return (nada)
#@exception OG_ERR_NOTUEFI UEFI no activa.
#*/ ##
def ogNvramPxeFirstEntry():
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
num = ''
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
if re.search ('IP[vV]{0,1}4', l):
num = l[4:8].strip ('0') or '0'
numentry = f'{int(num):04x}'.upper()
o = ogNvramGetOrder()
if not o:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, f'ogNvramGetOrder returned an empty list')
return
# Si la entrada es la primera nos salimos.
if numentry == o[0]:
return True
# Si la entrada ya existe la borramos.
order = [numentry] + list (filter (lambda x: x if x!=numentry else [], o))
ogNvramSetOrder (order)
return True
#/**
# ogRestoreEfiBootLoader int_ndisk str_repo
#@brief Copia el cargador de arranque de la partición de sistema a la partición EFI.
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado (partición de sistema o EFI).
#@exception OG_ERR_NOTOS sin sistema operativo.
#*/ ##
def ogRestoreEfiBootLoader (disk, par):
mntdir = FileSystemLib.ogMount (disk, par)
if not mntdir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}')
return
esp = DiskLib.ogGetEsp()
if not esp:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'EFI partition')
return
esp_disk, esp_par = esp.split()
efidir = FileSystemLib.ogMount (esp_disk, esp_par)
if not efidir:
FileSystemLib.ogFormat (esp_disk, esp_par, 'FAT32')
efidir = FileSystemLib.ogMount (esp_disk, esp_par)
if not efidir:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'ESP')
return
osversion = InventoryLib.ogGetOsVersion (disk, par)
if 'Windows 1' in osversion:
bootlabel = f'Part-{int(disk):02d}-{int(par):02d}'
loader = FileLib.ogGetPath (file=f'{mntdir}/ogBoot/bootmgfw.efi')
if not loader:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk} {par} ({osversion}, EFI)')
return
efi_bl = f'{efidir}/EFI/{bootlabel}'
if os.path.exists (efi_bl):
shutil.rmtree (efi_bl)
os.makedirs (efi_bl, exist_ok=True)
shutil.copytree (os.path.dirname (loader), f'{efi_bl}/Boot', symlinks=True)
shutil.copy (loader, f'{efi_bl}/Boot/ogloader.efi')
if '' != FileLib.ogGetPath (file=f'{efidir}/EFI/Microsoft'):
os.rename (f'{efidir}/EFI/Microsoft', f'{efidir}/EFI/Microsoft.backup.og')
return
#/**
# ogRestoreUuidPartitions
#@brief Restaura los uuid de las particiones y la tabla de particiones
#@param int_ndisk nº de orden del disco
#@param int_nfilesys nº de orden del sistema de archivos
#@param REPO|CACHE repositorio
#@param str_imgname nombre de la imagen
#@return (nada)
#@exception OG_ERR_FORMAT Formato incorrecto.
#@exception OG_ERR_NOTFOUND No encontrado fichero de información de la imagen (con uuid)
#*/ ##
#/**
# ogNvramSetNext
#@brief Configura el próximo arranque con la entrada del gestor de arranque (NVRAM) identificada por la etiqueta o el orden.
#@param Num_order_entry | Label_entry Número de orden o la etiqueta de la entrada a borrar.
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
#ogNvramSetNext ('2')
#ogNvramSetNext ('Windows Boot Manager')
def ogNvramSetNext (entry):
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
numentries = []
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
try:
foo = int (entry, 16) ## raises ValueError if entry doesn't look like hexadecimal
num = f'{foo:04x}'.upper()
for l in efibootmgr_out.splitlines():
words = l.split()
if len(words) < 2: continue
if num in words[0]:
numentries.append (words[0][4:8])
except ValueError:
for l in efibootmgr_out.splitlines():
words = l.split (maxsplit=1)
if len(words) < 2: continue
if words[1] == entry:
numentries.append (words[0][4:8])
if not numentries:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'NVRAM entry "{entry}"')
return
if 1 != len(numentries):
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, f'more than one entry found')
return
subprocess.run (['efibootmgr', '-n', numentries[0]], capture_output=True, text=True)
#/**
# ogNvramSetOrder
#@brief Configura el orden de las entradas de la NVRAM
#@param Orden de las entradas separadas por espacios
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTUEFI UEFI no activa.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado (entrada NVRAM).
#*/ ##
#ogNvramSetOrder (['1', '3'])
def ogNvramSetOrder (order):
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
try:
for i in order:
foo = int (i, 16)
except ValueError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'ogNvramSetOrder ([array or hex values])')
return
# Entradas de la NVRAM actuales
numentries = []
efibootmgr_out = subprocess.run (['efibootmgr'], capture_output=True, text=True).stdout
for l in efibootmgr_out.splitlines():
words = l.split()
if len(words) < 2: continue
if re.search ('Boot[0-9a-fA-F]{4}', words[0]):
numentries.append ('0' + words[0][4:8])
new_order = []
for o in order:
h = f'{int(o,16):05x}'.upper()
if h not in numentries:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'NVRAM entry order "{h}"')
return
new_order.append (h)
subprocess.run (['efibootmgr', '-o', ','.join (new_order)])
#/**
# ogNvramSetTimeout
#@brief Configura el tiempo de espera de la NVRAM
#@param Orden de las entradas separadas por espacios
#@return (nada)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##
#ogNvramSetTimeout ('2')
def ogNvramSetTimeout (t):
if not InventoryLib.ogIsEfiActive():
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTUEFI, '')
return
try:
num = int (t) ## raises ValueError if t doesn't look like a number
except ValueError:
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'ogNvramSetTimeout (timeout)')
return
subprocess.run (['efibootmgr', '-t', t])
#/**
# ogUuidChange int_ndisk str_repo
#@brief Reemplaza el UUID de un sistema de ficheros.
#@param int_ndisk nº de orden del disco
#@param int_part nº de partición
#@return (nada, por determinar)
#@exception OG_ERR_FORMAT formato incorrecto.
#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado.
#*/ ##

View File

@ -1,400 +0,0 @@
#!/usr/bin/python3
# Fichero de idioma: catalá.
#@version 1.1.1
#@author
# Mensajes de error.
MSG_ERR_GENERIC="Error imprevisto no definido"
MSG_ERR_FORMAT="Formato de ejecución incorrecto"
MSG_ERR_OUTOFLIMIT="Valor fuera de rango o no válido"
MSG_ERR_NOTFOUND="Fichero o dispositivo no encontrado"
MSG_ERR_PARTITION="Partición errónea o desconocida"
MSG_ERR_LOCKED="Recurso bloqueado por operación de uso exclusivo"
MSG_ERR_CACHE="Error en partición de caché local"
MSG_ERR_NOGPT="El disco indicado no contiene una particion GPT"
MSG_ERR_REPO="Error al montar el repositorio de imágenes"
MSG_ERR_NOMSDOS="El disco indicado no contiene una partición MSDOS"
MSG_ERR_FILESYS="Sistema de archivos desconocido o no se puede montar"
MSG_ERR_NOTOS="Sistema operativo no detectado o no se puede iniciar"
MSG_ERR_IMAGE="No se puede crear o restaurar una image de sistema"
MSG_ERR_IMAGEFILE="Archivo de imagen corrupto o de otra versión de partclone"
MSG_ERR_NOTEXEC="Programa o función no ejecutable"
MSG_ERR_NOTWRITE="No hay acceso de escritura"
MSG_ERR_NOTCACHE="No existe particion Cache en el cliente"
MSG_ERR_NOTUEFI="La interfaz UEFI no está activa"
MSG_ERR_NOTBIOS="La interfaz BIOS Legacy no está activa"
MSG_ERR_CACHESIZE="El espacio de la cache local o remota no es suficiente"
MSG_ERR_REDUCEFS="Error al reducir el sistema de archivos"
MSG_ERR_EXTENDFS="Error al expandir el sistema de archivos"
MSG_ERR_IMGSIZEPARTITION="Error al restaurar: Particion mas pequeña que la imagen"
MSG_ERR_UPDATECACHE="Error al realizar el comando updateCache"
MSG_ERR_UCASTSYNTAXT="Error en la generación de sintaxis de transferenica unicast"
MSG_ERR_UCASTSENDPARTITION="Error en envio UNICAST de una particion"
MSG_ERR_UCASTSENDFILE="Error en envio UNICAST de un fichero"
MSG_ERR_UCASTRECEIVERPARTITION="Error en la recepcion UNICAST de una particion"
MSG_ERR_UCASTRECEIVERFILE="Error en la recepcion UNICAST de un fichero"
MSG_ERR_MCASTSYNTAXT="Error en la generación de sintaxis de transferenica multicast"
MSG_ERR_MCASTSENDFILE="Error en envio MULTICAST de un fichero"
MSG_ERR_MCASTRECEIVERFILE="Error en la recepcion MULTICAST de un fichero"
MSG_ERR_MCASTSENDPARTITION="Error en envio MULTICAST de una particion"
MSG_ERR_MCASTRECEIVERPARTITION="Error en la recepcion MULTICAST de un fichero"
MSG_ERR_PROTOCOLJOINMASTER="Error en la conexion de una sesion UNICAST|MULTICAST con el MASTER"
MSG_ERR_DONTFORMAT="Error al formatear"
MSG_ERR_DONTMOUNT_IMAGE="Error al montar/reducir la imagen"
MSG_ERR_DONTUNMOUNT_IMAGE="Error al desmontar la imagen"
MSG_ERR_DONTSYNC_IMAGE="Imagen no sincronizable"
MSG_ERR_NOTDIFFERENT="No se detectan diferencias entre la imagen basica y la particion."
MSG_ERR_SYNCHRONIZING="Error al sincronizar, puede afectar la creacion|restauracion de la imagen"
# Mensajes de avisos.
MSG_DONTUSE="NO USAR"
MSG_DONTMOUNT="Sistema de archivos no montado"
MSG_DONTUNMOUNT="El sistema de archivos no se puede desmontar o no está montado"
MSG_MOUNT="Sistema de archivos montado"
MSG_MOUNTREADONLY="Sistema de archivos montado solo de lectura"
MSG_OBSOLETE="EN DESUSO"
# Mensajes complementarios para las ayudas.
MSG_64BIT="64 bits"
MSG_DISK="disc"
MSG_ERROR="Error"
MSG_EXAMPLE="Exemple"
MSG_FORMAT="Format"
MSG_FUNCTION="Funció"
MSG_HARDWAREINVENTORY="Inventario de maquinari de la màquina"
MSG_IMAGE="imatge"
MSG_INSTALLED="instal-lat"
MSG_NOCACHE="sense caché local"
MSG_NOEXTENDED="sense partició estensa"
MSG_PARTITION="partició"
MSG_PROTOCOL="protocol"
MSG_RESERVEDVALUE="Valor reservat"
MSG_SEE="Veure"
MSG_UNKNOWN="Desconegut"
MSG_WARNING="Avís"
# Mensajes del proceso de arranque.
MSG_DETECTLVMRAID="Detectar metadispositivos LVM y RAID."
MSG_ERRBOOTMODE=f"{MSG_ERROR}: Modo de arranque desconocido."
MSG_LAUNCHCLIENT="Ejecutar cliente."
MSG_LOADAPI="Cargar funciones del motor de clonación."
MSG_LOADMODULES="Cargar módulos del kernel."
MSG_MAKELINKS="Crear enlaces simbólicos."
MSG_MOUNTREPO="Montar repositorio por %s en modo %s."
MSG_OFFLINEMODE="Modo de arranque sin conexión."
MSG_OTHERSERVICES="Iniciar servicios complementarios del cliente."
MSG_POWEROFFCONF="Definir parámetros de ahorro de energía."
# Mensajes del menú por defecto.
MSG_BOOT="Iniciar"
MSG_DUPLEX="D&uacute;plex"
MSG_HOSTNAME="Equipo"
MSG_IPADDR="Direcci&oacute;n IP"
MSG_MACADDR="Direcci&oacute;n MAC"
MSG_MENUTITLE="Men&uacute; de opciones"
MSG_POWEROFF="Apagar el equipo"
MSG_SPEED="Velocidad"
# Mensajes de descripción breve de las funciones de la API.
MSG_HELP_ogAclFilter="Extrae las acl de los ficheros de la diferencial"
MSG_HELP_ogAddCmd="Añade comandos al fichero creado por la función ogInstalMiniSetup."
MSG_HELP_ogAddRegistryKey="Añade una nueva clave al registro de Windows."
MSG_HELP_ogAddRegistryValue="Añade un nuevo valor al registro de Windows."
MSG_HELP_ogAddToLaunchDaemon=""
MSG_HELP_ogBoot="Arranca un sistema operativo instalado."
MSG_HELP_ogBootLoaderDeleteEntry=MSG_DONTUSE
MSG_HELP_ogBootLoaderHidePartitions=MSG_DONTUSE
MSG_HELP_ogBootMbrGeneric=""
MSG_HELP_ogBootMbrXP=""
MSG_HELP_ogBurgDefaultEntry="Configura la entrada por defecto de Burg."
MSG_HELP_ogBurgDeleteEntry="Borra en el Burg del MBR las entradas para el inicio en una particion."
MSG_HELP_ogBurgHidePartitions="Configura el Burg del MBR para que oculte las particiones de windows que no se esten iniciando. Permite definir una partición que no se ocultará (ej: para datos)."
MSG_HELP_ogBurgInstallMbr="Instal·la el carregador d'arrencada BURG al MBR del primer disc dur"
MSG_HELP_ogBurgOgliveDefaultEntry="Configura la entrada de ogLive como la entrada por defecto de Burg."
MSG_HELP_ogCalculateChecksum="Calcula la suma de comprobación (checksum) de un fichero."
MSG_HELP_ogCalculateFullChecksum=""
MSG_HELP_ogChangeRepo="Cambia el repositorio para el recurso remoto images."
MSG_HELP_ogCheckFs="Comprueba la consistencia de un sistema de archivos."
MSG_HELP_ogCheckIpAddress=""
MSG_HELP_ogCheckProgram=""
MSG_HELP_ogCheckStringInGroup=""
MSG_HELP_ogCheckStringInReg=""
MSG_HELP_ogCheckSyncImage="Muestra el contenido de la imagen para comprobarla."
MSG_HELP_ogCleanLinuxDevices=""
MSG_HELP_ogCleanOs="Elimina los archivos que no son necesarios en el sistema operativo."
MSG_HELP_ogCompareChecksumFiles="Compara si coinciden las sumas de comprobación almacenadas de 2 ficheros."
MSG_HELP_ogConfigureFstab=""
MSG_HELP_ogConfigureOgagent="Configura el nuevo agente OGAgent para sistemas ooperativos."
MSG_HELP_ogCopyFile="Copia un fichero a otro almacenamiento."
MSG_HELP_ogCreateBootLoaderImage=""
MSG_HELP_ogCreateCache="Reserva espacio para la partición de caché al final del disco."
MSG_HELP_ogCreateDiskImage="Genera una imagen exacta de un disco completo."
MSG_HELP_ogCreateFileImage="Crea/Redimensiona el archivo de la imagen sincronizada"
MSG_HELP_ogCreateGptPartitions=""
MSG_HELP_ogCreateImage="Genera una imagen exacta de un sistema operativo instalado localmente."
MSG_HELP_ogCreateImageSyntax=""
MSG_HELP_ogCreateInfoImage="Crea informacion del contenido de la imagen"
MSG_HELP_ogCreateMbrImage="Genera una imagen del sector de arranque (MBR)."
MSG_HELP_ogCreatePartitions="Define la estructura de particiones de un disco."
MSG_HELP_ogCreatePartitionTable="Genera una tabla de particiones en caso de que no sea valida."
MSG_HELP_ogCreateTorrent=""
MSG_HELP_ogCopyEfiBootLoader="Copia el cargador de arranque desde la partición EFI a la de sistema."
MSG_HELP_ogDeleteCache="Elimina la partición de caché local."
MSG_HELP_ogDeleteFile="Borra un fichero de un espacio de almacenamiento."
MSG_HELP_ogDeletePartitionTable="Elimina la tabla de particiones del disco"
MSG_HELP_ogDeleteRegistryKey="Borra una clave vacía del registro de Windows."
MSG_HELP_ogDeleteRegistryValue="Borra un valor del registro de Windows."
MSG_HELP_ogDeleteTree="Borra un árbol de directorios de un espacio de almacenamiento."
MSG_HELP_ogDevToDisk="Devuelve el nº de orden de disco o de partición correspondiente al camino del fichero de dispositivo."
MSG_HELP_ogDiskToDev="Devuelve el camino del fichero de dispositivo correspondiente al nº de orden de disco o de partición."
MSG_HELP_ogDomainScript=""
MSG_HELP_ogEcho=""
MSG_HELP_ogExecAndLog=""
MSG_HELP_ogExtendFs="Extiende el tamaño de un sistema de archivo al máximo de su partición."
MSG_HELP_ogFindCache="Indica la partición reservada para caché local."
MSG_HELP_ogFixBootSector=""
MSG_HELP_ogFormatCache="Formatea (inicia) el sistema de caché local."
MSG_HELP_ogFormat="Formatea o reformatea un sistema de archivos."
MSG_HELP_ogFormatFs=MSG_HELP_ogFormat
MSG_HELP_ogGetArch="Devuelve el tipo de arquitectura del cliente."
MSG_HELP_ogGetCacheSize="Devuelve el tamaño de la partición de caché local."
MSG_HELP_ogGetCacheSpace="Devuelve el espacio máximo disponible que puede ser reservado para la partición de caché local."
MSG_HELP_ogGetCaller=""
MSG_HELP_ogGetDiskSize="Devuelve el tamaño del disco."
MSG_HELP_ogGetDiskType="Devuelve el mnemónico de tipo de disco."
MSG_HELP_ogGetFreeSize=""
MSG_HELP_ogGetFsSize="Devuelve el tamaño de un sistema de archivos."
MSG_HELP_ogGetFsType="Devuelve el mnemónico de tipo de sistema de archivos."
MSG_HELP_ogGetGroupDir="Devuelve el camino del directorio por defecto para el grupo del cliente."
MSG_HELP_ogGetGroupName="Devuelve el nombre del grupo al que pertenece el cliente."
MSG_HELP_ogGetHivePath="Devuelve el camino completo del fichero de una sección del registro de Windows."
MSG_HELP_ogGetHostname="Devuelve el nombre de la máquina local."
MSG_HELP_ogGetImageCompressor="Devuelve la herramienta de compresión de la imagen."
MSG_HELP_ogGetImageInfo="Muestra información sobre la imagen monolitica: clonacion:compresor:sistemaarchivos:tamañoKB."
MSG_HELP_ogGetImageProgram="Devuelve el programa usado para crear la imagen."
MSG_HELP_ogGetImageSize="Devuelve el tamaño de una imagen de sistema."
MSG_HELP_ogGetImageType="Devuelve el sistema de ficheros de la imagen."
MSG_HELP_ogGetIpAddress="Devuelve la dirección IP del cliente."
MSG_HELP_ogGetLastSector="Devuelve el último sector usable del disco o de una partición."
MSG_HELP_ogGetMacAddress="Devuelve la dirección Ethernet del cliente."
MSG_HELP_ogGetMountImageDir="Devuelve el directorio de montaje de una imagen."
MSG_HELP_ogGetMountPoint="Devuelve el directorio donde está montado un sistema de archivos local."
MSG_HELP_ogGetNetInterface=""
MSG_HELP_ogGetOsType="Devuelve el tipo de un sistema operativo instalado."
MSG_HELP_ogGetOsUuid=""
MSG_HELP_ogGetOsVersion="Devuelve el tipo y la versión de un sistema operativo instalado."
MSG_HELP_ogGetParentPath="Devuelve el camino completo del directorio padre de un fichero de sistema OpenGnsys."
MSG_HELP_ogGetPartitionActive="Indica cual es la partición marcada como activa en un disco."
MSG_HELP_ogGetPartitionId="Devuelve el identificador de tipo de una partición."
MSG_HELP_ogGetPartitionSize="Devuelve el tamaño de una partición."
MSG_HELP_ogGetPartitionsNumber=""
MSG_HELP_ogGetPartitionTableType="Devuelve el tipo de tabla de particiones del disco"
MSG_HELP_ogGetPartitionType="Devuelve el mnemónico de tipo de una partición."
MSG_HELP_ogGetPath="Devuelve el camino completo de un fichero de sistema OpenGnsys."
MSG_HELP_ogGetRegistryValue="Devuelve el dato de un valor del registro de Windows."
MSG_HELP_ogGetRepoIp="Devuelve la dirección IP del repositorio de datos."
MSG_HELP_ogGetSerialNumber="Devuelve el número de serie del cliente."
MSG_HELP_ogGetServerIp="Devuelve la dirección IP del servidor principal."
MSG_HELP_ogGetSizeParameters="Devuelve el tamaño de los datos de un sistema de ficheros, el espacio necesario para la imagen y si cabe en el repositorio elegido."
MSG_HELP_ogGetWindowsName="Devuelve el nombre del cliente guardado en el registro de Windows."
MSG_HELP_ogGrubAddOgLive="Incluye en el grub del MBR una entrada llamando al cliente de opengnsys."
MSG_HELP_ogGrubDefaultEntry="Configura la entrada por defecto de GRUB."
MSG_HELP_ogGrubDeleteEntry="Borra en el grub del MBR las entradas para el inicio en una particion."
MSG_HELP_ogGrubHidePartitions="Configura el grub del MBR para que oculte las particiones de windows que no se esten iniciando. Permite definir una partición que no se ocultará (ej: para datos)."
MSG_HELP_ogGrubInstallMbr="Instal·la el carregador d'arrencada GRUB al MBR del primer disc dur"
MSG_HELP_ogGrubInstallPartition="Instal·la el carregador d'arrencada BURG al BootSector"
MSG_HELP_ogGrubOgliveDefaultEntry="Configura la entrada de ogLive como la entrada por defecto de GRUB."
MSG_HELP_ogGrubSecurity="Configura usuario y clave para modificar las entradas del menu del Grub."
MSG_HELP_ogGrubUefiConf="Genera el fichero grub.cfg de la partición EFI."
MSG_HELP_ogHelp="Muestra mensajes de ayudas para las funciones."
MSG_HELP_ogHidePartition="Oculta una partición de Windows."
MSG_HELP_ogIdToType="Devuelve el mnemónico asociado al identificador de tipo de partición."
MSG_HELP_ogNvramActiveEntry="Configura a activa entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramAddEntry="Crea nueva entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramDeleteEntry="Borra entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramGetCurrent="Muestra la entrada del gestor de arranque (NVRAM) que ha iniciado el equipo."
MSG_HELP_ogNvramGetNext="Muestra la entrada del gestor de arranque (NVRAM) que se utilizará en el próximo arranque."
MSG_HELP_ogNvramGetOrder="Muestra el orden de las entradas del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramGetTimeout="Muestra el tiempo de espera del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramInactiveEntry="Configura a inactiva entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramList="Lista las entradas del gestor de arranque (NVRAN) marcando con un asterisco las activas"
MSG_HELP_ogNvramSetNext="Configura el próximo arranque con la entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramSetOrder="Configura el orden de las entradas del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramSetTimeout="Configura el tiempo de espera del gestor de arranque (NVRAM)."
MSG_HELP_ogGetOsType="Devuelve el tipo de un sistema operativo instalado."
MSG_HELP_ogInstallFirstBoot="Crea un archivo que se ejecutará en el primer arranque de Windows."
MSG_HELP_ogInstallLaunchDaemon="Instala un archivo que se ejecutará en el arranque de macOS."
MSG_HELP_ogInstallLinuxClient=MSG_OBSOLETE
MSG_HELP_ogInstallMiniSetup="Instala un archivo que se ejecutará en el arranque de Windows."
MSG_HELP_ogInstallRunonce="Crea un archivo que se ejecutará en el inicio de un usuario administrador de Windows."
MSG_HELP_ogInstallWindowsClient=MSG_OBSOLETE
MSG_HELP_ogIsFormated="Comprueba si un sistema de archivos está formateado."
MSG_HELP_ogIsImageLocked="Comprueba si una imagen está bloqueada por una operación de uso exclusivo."
MSG_HELP_ogIsLocked="Comprueba si una partición o su disco están bloqueados por una operación de uso exclusivo."
MSG_HELP_ogIsDiskLocked="Comprueba si un disco está bloqueado por una operación de uso exclusivo."
MSG_HELP_ogIsMounted="Comprueba si un sistema de archivos está montado."
MSG_HELP_ogIsNewerFile="Comprueba si un fichero es más nuevo (se ha modificado después) que otro."
MSG_HELP_ogIsPartitionLocked=MSG_HELP_ogIsLocked
MSG_HELP_ogIsRepoLocked=""
MSG_HELP_ogIsSyncImage="Comprueba si la imagen es sincronizable."
MSG_HELP_ogIsVirtualMachine=""
MSG_HELP_ogIsWritable="Comprueba si un sistema de archivos está montado con permiso de escritura."
MSG_HELP_ogLinuxBootParameters="Devuelve los parámetros de arranque de un sistema operativo Linux instalado."
MSG_HELP_ogListHardwareInfo="Lista el inventario de dispositivos del cliente."
MSG_HELP_ogListLogicalPartitions=""
MSG_HELP_ogListPartitions="Lista la estructura de particiones de un disco."
MSG_HELP_ogListPrimaryPartitions=""
MSG_HELP_ogListRegistryKeys="Lista los nombres de las subclaves incluidas en una clave del registro de Windows."
MSG_HELP_ogListRegistryValues="Lista los nombres de los valores incluidos en una clave del registro de Windows."
MSG_HELP_ogListSoftware="Lista el inventario de programas instalados en un sistema operativo."
MSG_HELP_ogLock="Bloquea una partición para operación de uso exclusivo."
MSG_HELP_ogLockDisk="Bloquea un disco para operación de uso exclusivo."
MSG_HELP_ogLockImage="Bloquea una imagen para operación de uso exclusivo."
MSG_HELP_ogLockPartition=MSG_HELP_ogLock
MSG_HELP_ogMakeChecksumFile="Almacena la suma de comprobación de un fichero."
MSG_HELP_ogMakeDir="Crea un directorio para OpenGnsys."
MSG_HELP_ogMakeGroupDir="Crea el directorio de grupo (aula) en un repositorio."
MSG_HELP_ogMcastReceiverFile=""
MSG_HELP_ogMcastReceiverPartition=""
MSG_HELP_ogMcastRequest=""
MSG_HELP_ogMcastSendFile=""
MSG_HELP_ogMcastSendPartition=""
MSG_HELP_ogMcastSyntax=""
MSG_HELP_ogMountCache="Monta el sistema de archivos dedicado a caché local."
MSG_HELP_ogMountCdrom="Monta dispositivo óptico por defecto."
MSG_HELP_ogMountImage="Monta una imagen sincronizable"
MSG_HELP_ogMount="Monta un sistema de archivos y devuelve el punto de montaje."
MSG_HELP_ogMountFs=MSG_HELP_ogMount
MSG_HELP_ogNvramActiveEntry="Configura a activa entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramAddEntry="Crea nueva entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramDeleteEntry="Borra entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramGetCurrent="Muestra la entrada del gestor de arranque (NVRAM) que ha iniciado el equipo."
MSG_HELP_ogNvramGetNext="Muestra la entrada del gestor de arranque (NVRAM) que se utilizará en el próximo arranque."
MSG_HELP_ogNvramGetOrder="Muestra el orden de las entradas del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramGetTimeout="Muestra el tiempo de espera del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramInactiveEntry="Configura a inactiva entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramList="Lista las entradas del gestor de arranque (NVRAN) marcando con un asterisco las activas"
MSG_HELP_ogNvramPxeFirstEntry="Configura la tarjeta de red como primer arranque en la NVRAM."
MSG_HELP_ogNvramSetNext="Configura el próximo arranque con la entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramSetOrder="Configura el orden de las entradas del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramSetTimeout="Configura el tiempo de espera del gestor de arranque (NVRAM)."
MSG_HELP_ogRaiseError="Muestra y registra mensajes de error y devuelve el código correspondiente."
MSG_HELP_ogReduceFs="Reduce el tamaño del sistema de archivos al mínimo ocupado por sus datos."
MSG_HELP_ogReduceImage="Reduce el tamaño de la imagen"
MSG_HELP_ogRefindDeleteEntry="Borra en rEFInd las entradas para el inicio en una particion."
MSG_HELP_ogRefindDefaultEntry="Configura la entrada por defecto de rEFInd."
MSG_HELP_ogRefindOgliveDefaultEntry="Configura la entrada de ogLive como la entrada por defecto de rEFInd."
MSG_HELP_ogRefindSetTheme="Asigna un tema al rEFInd."
MSG_HELP_ogRefindSetTimeOut="Define el tiempo (segundos) que se muestran las opciones de inicio de rEFInd."
MSG_HELP_ogRefindSetResolution="Define la resolución que usuará el thema del gestor de arranque rEFInd."
MSG_HELP_ogRefindInstall="Instala y configura el gestor rEFInd en la particion EFI"
MSG_HELP_ogRestoreAclImage=""
MSG_HELP_ogRestoreBootLoaderImage=""
MSG_HELP_ogRestoreDiskImage="Restaura una imagen de un disco completo."
MSG_HELP_ogRestoreEfiBootLoader="Copia el cargador de arranque de la partición de sistema a la partición EFI."
MSG_HELP_ogRestoreImage="Restaura una imagen de sistema operativo."
MSG_HELP_ogRestoreInfoImage="Restablece informacion del sistema: acl y enlaces simbolicos"
MSG_HELP_ogRestoreMbrImage="Restaura una imagen del sector de arranque (MBR)."
MSG_HELP_ogRestoreUuidPartitions="Restaura los uuid de las particiones y la tabla de particiones."
MSG_HELP_ogSaveImageInfo="Crea un fichero con la información de la imagen."
MSG_HELP_ogSetLinuxName=""
MSG_HELP_ogSetPartitionActive="Establece el número de partición activa de un disco."
MSG_HELP_ogSetPartitionId="Modifica el tipo de una partición física usando el mnemónico del tipo."
MSG_HELP_ogSetPartitionSize="Establece el tamaño de una partición."
MSG_HELP_ogSetPartitionType="Modifica el identificador de tipo de una partición física."
MSG_HELP_ogSetRegistryValue="Asigna un dato a un valor del registro de Windows."
MSG_HELP_ogSetWindowsName="Asigna el nombre del cliente en el registro de Windows."
MSG_HELP_ogSetWinlogonUser="Asigna el nombre de usuario por defecto para el gestor de entrada de Windows."
MSG_HELP_ogSyncCreate="Sincroniza los datos de la particion a la imagen"
MSG_HELP_ogSyncRestore="Sincroniza los datos de la imagen a la particion"
MSG_HELP_ogTorrentStart=""
MSG_HELP_ogTypeToId="Devuelve el identificador asociado al mnemónico de tipo de partición."
MSG_HELP_ogUcastReceiverPartition=""
MSG_HELP_ogUcastSendFile=""
MSG_HELP_ogUcastSendPartition=""
MSG_HELP_ogUcastSyntax=""
MSG_HELP_ogUnhidePartition="Hace visible una partición de Windows."
MSG_HELP_ogUninstallLinuxClient="Desinstala el cliente OpenGnSys en un sistema operativo Linux."
MSG_HELP_ogUninstallWindowsClient="Desinstala el cliente OpenGnSys en un sistema operativo Windows."
MSG_HELP_ogUnlock="Desbloquea una partición tras finalizar una operación de uso exclusivo."
MSG_HELP_ogUnlockDisk="Desbloquea un disco tras finalizar una operación de uso exclusivo."
MSG_HELP_ogUnlockImage="Desbloquea una imagen tras finalizar una operación de uso exclusivo."
MSG_HELP_ogUnlockPartition=MSG_HELP_ogUnlock
MSG_HELP_ogUnmountAll="Desmonta todos los sistemas de archivos."
MSG_HELP_ogUnmountCache="Desmonta el sistema de archivos de caché local."
MSG_HELP_ogUnmount="Desmonta un sistema de archivos."
MSG_HELP_ogUnmountImage="Desmonta la imagen"
MSG_HELP_ogUnmountFs=MSG_HELP_ogUnmount
MSG_HELP_ogUnsetDirtyBit=""
MSG_HELP_ogUpdateCacheIsNecesary="Comprueba si es necesario actualizar una archivo en la cache local."
MSG_HELP_ogUpdatePartitionTable="Actualiza informacion tabla particiones del disco"
MSG_HELP_ogUuidChange="Reemplaza el UUID de un sistema de ficheros."
MSG_HELP_ogWaitSyncImage=""
MSG_HELP_ogWindowsBootParameters=""
MSG_HELP_ogWindowsRegisterPartition=""
# Scripts
MSG_HELP_configureOs="Post-configura de arranque del sistema"
MSG_HELP_createBaseImage="Genera imagen basica de la particion"
MSG_HELP_createDiffImage="Genera imagen diferencial de la particion respecto a la imagen basica"
MSG_HELP_installOfflineMode="Prepara el equipo cliente para el modo offline."
MSG_HELP_partclone2sync="Convierte imagen de partclone en imagen sincronizable."
MSG_HELP_restoreBaseImage="Restaura una imagen basica en una particion"
MSG_HELP_restoreDiffImage="Restaura una imagen diferencial en una particion"
MSG_HELP_updateCache="Realiza la actualizacion de la cache"
# Mensajes de descripción breve de la interfaz.
MSG_INTERFACE_START="[START Interface] Ejecutar comando: "
MSG_INTERFACE_END="[END Interface] Comando terminado con este código: "
# Mensajes de scripts.
MSG_SCRIPTS_START=" INICIO scripts : "
MSG_SCRIPTS_END=" FIN scripts: "
MSG_SCRIPTS_TASK_END="Fin de la tarea"
MSG_SCRIPTS_TASK_SLEEP="Esperando para iniciar"
MSG_SCRIPTS_TASK_START="Iniciando"
MSG_SCRIPTS_TASK_ERR="Error"
# Script createImage.
MSG_SCRIPTS_FILE_RENAME=" Renombrar fichero-imagen previo: "
MSG_SCRIPTS_CREATE_SIZE=" Calcular espacio (KB) requerido para almacenarlo y el disponible: "
# Script updateCache.
MSG_SCRIPTS_UPDATECACHE_DOUPDATE="comprovar si es necessari actualitzar el fitxer imatge"
MSG_SCRIPTS_UPDATECACHE_CHECKSIZECACHE="Comprobar que el tamaño de la cache es mayor que el fichero a descargar."
# Script updateCache: para las imágenes sincronizadas tipo dir.
MSG_SCRIPTS_UPDATECACHE_CHECKSIZEDIR="Calculamos el tamaño de la imagen."
MSG_SCRIPTS_UPDATECACHE_CHECKSIZEIMG="Comprobamos si hay que la imagen del repositorio es mayor que la de la cache."
MSG_SCRIPTS_UPDATECACHE_IFNOTCACHEDO="Comprobar el espacio libre de la cache y actuar según engine.cfg"
MSG_SCRIPTS_UPDATECACHE_CHECKMCASTSESSION="Comprobando sesion multicast: ServidorMcast:PuertoDatos"
# interface sustituye temporalmente al scritp restore
MSG_SCRIPTS_CHECK_ENGINE="Analizar proceso a realizar según engine.cfg"
MSG_SCRIPTS_MULTICAST_PRECHECK_PORT="Determinar puerto principal y auxiliar multicast."
MSG_SCRIPTS_MULTICAST_CHECK_PORT="Comprobar puertos de sesion y datos"
MSG_SCRIPTS_MULTICAST_REQUEST_PORT="Solicitar la apertura: "
MSG_SCRIPTS_OS_CONFIGURE="Iniciar la configuracion del sistema restaurado"
# TIME MESSAGES
MSG_SCRIPTS_TIME_TOTAL="tiempo total del proceso"
MSG_SCRIPTS_TIME_PARTIAL="tiempo parcial del subproceso"
# HTTPLOG
MSG_HTTPLOG_NOUSE="No apague este ordenador por favor"
# Mensajes sincronizadas
MSG_SYNC_RESIZE="Redimensiona la imagen al tamaño necesario"
MSG_SYNC_RESTORE="Trae el listado ficheros y baja la imagen"
MSG_SYNC_DELETE="Diferencial: Borra archivos antiguos"
MSG_SYNC_SLEEP="Espera que se monte/reduzca la imagen"
# Mensajes sincronizadas complementarios a errores
MSG_SYNC_DIFFERENTFS="El sistema de ficheros de destino no coincide con el de la imagen"
MSG_SYNC_EXTENSION="Las extensiones de la imagenes deben ser img o diff"
MSG_SYNC_NOCHECK="La imagen esta montada por otro proceso, no podemos comprobarla"
MSG_RESTORE="Restaura la imagen en"

View File

@ -1,387 +0,0 @@
#!/usr/bin/python3
# English language file.
#@version 1.1.0
#@author Jose Miguel Hernandez - Universidad de Salamanca
#@date 2018-03-01
# Error messages.
MSG_ERR_GENERIC="Undefined unknown error"
MSG_ERR_FORMAT="Wrong execution format"
MSG_ERR_OUTOFLIMIT="Out of range or invalid value"
MSG_ERR_NOTFOUND="File or device not found"
MSG_ERR_PARTITION="Unknown or wrong partition"
MSG_ERR_LOCKED="Resource locked by exclusive use operation"
MSG_ERR_CACHE="Local cache error"
MSG_ERR_NOGPT="Current disk does not include GPT partition"
MSG_ERR_REPO="Failed when mounting images repository"
MSG_ERR_NOMSDOS="Current disk does not include MSDOS partition"
MSG_ERR_FILESYS="Unknown or unmountable file system"
MSG_ERR_NOTOS="Cannot detect or boot OS"
MSG_ERR_IMAGE="Cannot create or restore a system image"
MSG_ERR_IMAGEFILE="Image file corrupt or of other partclone version"
MSG_ERR_NOTEXEC="Non executable program or function"
MSG_ERR_NOTWRITE="Write access denied"
MSG_ERR_NOTCACHE="No client cache partition"
MSG_ERR_NOTUEFI="UEFI isn't active"
MSG_ERR_NOTBIOS="BIOS legacy isn't active"
MSG_ERR_CACHESIZE="Not enough space in local or remote cache"
MSG_ERR_REDUCEFS="Error when reducing file system"
MSG_ERR_EXTENDFS="Error when expanding file system"
MSG_ERR_IMGSIZEPARTITION="Backup error: Partition smaller than image"
MSG_ERR_UPDATECACHE="Error when running `updateCache´ command"
MSG_ERR_UCASTSYNTAXT="Error when generating Unicast transfer syntax"
MSG_ERR_UCASTSENDPARTITION="Error when sending a Unicast partition"
MSG_ERR_UCASTSENDFILE="Error when sending a Unicast file"
MSG_ERR_UCASTRECEIVERPARTITION="Error when receiving an Unicast partition"
MSG_ERR_UCASTRECEIVERFILE="Error when receiving an Unicast file"
MSG_ERR_MCASTSYNTAXT="Error when generating Multicast transfer syntax"
MSG_ERR_MCASTSENDFILE="Error when sending Multicast file"
MSG_ERR_MCASTRECEIVERFILE="Error when receiving Multicast file"
MSG_ERR_MCASTSENDPARTITION="Error when sending Multicast partition"
MSG_ERR_MCASTRECEIVERPARTITION="Error when receiving Multicast partition "
MSG_ERR_PROTOCOLJOINMASTER="Error when connecting Unicast/Multicast session to Master"
MSG_ERR_DONTFORMAT="Formatting Error"
MSG_ERR_DONTMOUNT_IMAGE="Error when mounting/reducing image"
MSG_ERR_DONTUNMOUNT_IMAGE="Error when unmounting image"
MSG_ERR_DONTSYNC_IMAGE="Unsynchronizable image"
MSG_ERR_NOTDIFFERENT="Basic image identical to partition"
MSG_ERR_SYNCHRONIZING="Synchronizing error, it may affect image creation/restoration process"
# Warning messages.
MSG_DONTUSE="DO NOT USE"
MSG_DONTMOUNT="Unmounted file system"
MSG_DONTUNMOUNT="Cannot unmount file system or it isn't mounted"
MSG_MOUNT="File system already mounted"
MSG_MOUNTREADONLY="Read-only file system mounted"
MSG_OBSOLETE="OBSOLETE"
# Auxiliary help messages.
MSG_64BIT="64-bit"
MSG_DISK="Disk"
MSG_ERROR="Error"
MSG_EXAMPLE="Example"
MSG_FORMAT="Format"
MSG_FUNCTION="Function"
MSG_HARDWAREINVENTORY="Hardware inventory"
MSG_IMAGE="Image"
MSG_INSTALLED="Installed"
MSG_NOCACHE="No local cache"
MSG_NOEXTENDED="No extended partition"
MSG_PARTITION="Partition"
MSG_PROTOCOL="Protocol"
MSG_RESERVEDVALUE="Reserved value"
MSG_SEE="See"
MSG_UNKNOWN="Unknown"
MSG_WARNING="Warning"
# Boot process messages.
MSG_DETECTLVMRAID="Detecting LVM and RAID meta-devices."
MSG_ERRBOOTMODE=f"{MSG_ERROR}: Unknown boot mode."
MSG_LAUNCHCLIENT="Launching client browser."
MSG_LOADAPI="Loading cloning-engine functions."
MSG_LOADMODULES="Loading kernel modules."
MSG_MAKELINKS="Creating symbolic links."
MSG_MOUNTREPO="Mounting repository using %s by %s mode."
MSG_OFFLINEMODE="Off-line boot mode."
MSG_OTHERSERVICES="Starting client complementary services."
MSG_POWEROFFCONF="Defining power-saving parameters."
# Default menu messages.
MSG_BOOT="Boot"
MSG_DUPLEX="Duplex"
MSG_HOSTNAME="Hostname"
MSG_IPADDR="IP Address"
MSG_MACADDR="MAC Address"
MSG_MENUTITLE="Options menu"
MSG_POWEROFF="Shutdown computer"
MSG_SPEED="Speed"
# API functions messages.
MSG_HELP_ogAclFilter="Draws ACL files from differential image."
MSG_HELP_ogAddCmd="Adds commands to file created by ogInstalMiniSetup."
MSG_HELP_ogAddRegistryKey="Adds new Windows registry key."
MSG_HELP_ogAddRegistryValue="Adds new Windows registry value."
MSG_HELP_ogAddToLaunchDaemon=""
MSG_HELP_ogBoot="Boots installed OS."
MSG_HELP_ogBootLoaderDeleteEntry=MSG_DONTUSE
MSG_HELP_ogBootLoaderHidePartitions=MSG_DONTUSE
MSG_HELP_ogBootMbrGeneric=""
MSG_HELP_ogBootMbrXP=""
MSG_HELP_ogBurgDefaultEntry="Sets default Burg entry."
MSG_HELP_ogBurgDeleteEntry="Deletes partition start-entries from MBR BURG."
MSG_HELP_ogBurgHidePartitions="Sets MBR Burg to hide non starting windows partitions. Allows you to select a partition that will not be hidden (e.g. for data)."
MSG_HELP_ogBurgInstallMbr="Installs BURG boot-loader on 1st HD MBR."
MSG_HELP_ogBurgOgliveDefaultEntry="Sets ogLive input as default Burg input."
MSG_HELP_ogCalculateChecksum="Calculates file checksum."
MSG_HELP_ogCalculateFullChecksum="Calculates file full checksum"
MSG_HELP_ogChangeRepo="Changes repository for remote resource: images."
MSG_HELP_ogCheckFs="Checks file system consistence."
MSG_HELP_ogCheckIpAddress=""
MSG_HELP_ogCheckProgram=""
MSG_HELP_ogCheckStringInGroup=""
MSG_HELP_ogCheckStringInReg=""
MSG_HELP_ogCheckSyncImage="Displays image contents to check it."
MSG_HELP_ogCleanLinuxDevices=""
MSG_HELP_ogCleanOs="Deletes OS unnecessary files."
MSG_HELP_ogCompareChecksumFiles="Compares if the checksums match."
MSG_HELP_ogConfigureFstab=""
MSG_HELP_ogConfigureOgagent="Sets OS new agent: OGAgent."
MSG_HELP_ogCopyFile="Copies file to another storage unit ."
MSG_HELP_ogCreateBootLoaderImage=""
MSG_HELP_ogCreateCache="Saves space for cache partition at the end of disk."
MSG_HELP_ogCreateDiskImage="Creates exact image from local disk."
MSG_HELP_ogCreateFileImage="Creates/Resizes synchronized image file."
MSG_HELP_ogCreateGptPartitions=""
MSG_HELP_ogCreateImage="Creates exact image from local installed OS."
MSG_HELP_ogCreateImageSyntax=""
MSG_HELP_ogCreateInfoImage="Creates image content information."
MSG_HELP_ogCreateMbrImage="Creates MBR image."
MSG_HELP_ogCreatePartitions="Creates disk partition table."
MSG_HELP_ogCreatePartitionTable="Creates partition table, if necessary."
MSG_HELP_ogCreateTorrent=""
MSG_HELP_ogCopyEfiBootLoader="Copy the boot loader from the EFI partition to system partition."
MSG_HELP_ogDeleteCache="Deletes local cache partition."
MSG_HELP_ogDeleteFile="Deletes file from storage."
MSG_HELP_ogDeletePartitionTable="Deletes disk table partition"
MSG_HELP_ogDeleteRegistryKey="Deletes empty Windows registry key."
MSG_HELP_ogDeleteRegistryValue="Deletes Windows registry value."
MSG_HELP_ogDeleteTree="Deletes directory tree."
MSG_HELP_ogDevToDisk="Returns disk or partition ordinal number for device file path."
MSG_HELP_ogDiskToDev="Returns device file path for disk or partition ordinal number."
MSG_HELP_ogDomainScript=""
MSG_HELP_ogEcho="Displays and log messages."
MSG_HELP_ogExecAndLog="Runs and logs command"
MSG_HELP_ogExtendFs="Expands file system size to partition maximum."
MSG_HELP_ogFindCache="Shows local cache reserved partition."
MSG_HELP_ogFixBootSector=""
MSG_HELP_ogFormatCache="Formats (clears) local cache."
MSG_HELP_ogFormat="Formats file system."
MSG_HELP_ogFormatFs=MSG_HELP_ogFormat
MSG_HELP_ogGetArch="Returns client architecture."
MSG_HELP_ogGetCacheSize="Returns local cache partition size."
MSG_HELP_ogGetCacheSpace="Returns maximum available space that can be reserved for local cache partition."
MSG_HELP_ogGetCaller="Returns program or function which is calling to current one"
MSG_HELP_ogGetDiskSize="Returns disk size."
MSG_HELP_ogGetDiskType="Returns disk type."
MSG_HELP_ogGetFreeSize=""
MSG_HELP_ogGetFsSize="Returns file system size."
MSG_HELP_ogGetFsType="Returns file system type."
MSG_HELP_ogGetGroupDir="Returns default directory path for client group."
MSG_HELP_ogGetGroupName="Returns client group name."
MSG_HELP_ogGetHivePath="Returns full path of file from Windows registry section."
MSG_HELP_ogGetHostname="Returns local hostname."
MSG_HELP_ogGetImageCompressor="Returns image compression tool."
MSG_HELP_ogGetImageInfo="Displays monolithic image information: cloning; compressor; file system; size(KB)."
MSG_HELP_ogGetImageProgram="Returns used program to create image."
MSG_HELP_ogGetImageSize="Returns system image size."
MSG_HELP_ogGetImageType="Returns image file system."
MSG_HELP_ogGetIpAddress="Returns client IP."
MSG_HELP_ogGetLastSector="Returns last available sector from disk or partition."
MSG_HELP_ogGetMacAddress="Returns client Ethernet address."
MSG_HELP_ogGetMountImageDir="Returns mounting directory of image."
MSG_HELP_ogGetMountPoint="Returns directory of local file system mount point."
MSG_HELP_ogGetNetInterface=""
MSG_HELP_ogGetOsType="Returns installed OS type."
MSG_HELP_ogGetOsUuid="Returns OS UUID"
MSG_HELP_ogGetOsVersion="Returns OS version."
MSG_HELP_ogGetParentPath="Returns full path of OpenGnsys system file parent directory."
MSG_HELP_ogGetPartitionActive="Returns disk active partition."
MSG_HELP_ogGetPartitionId="Returns partition type ID."
MSG_HELP_ogGetPartitionSize="Returns partition size."
MSG_HELP_ogGetPartitionsNumber="Returns disk partitions number."
MSG_HELP_ogGetPartitionTableType="Returns disk partition table type."
MSG_HELP_ogGetPartitionType="Returns partition type."
MSG_HELP_ogGetPath="Returns full path of OpenGnsys system file."
MSG_HELP_ogGetRegistryValue="Returns data from Windows registry value."
MSG_HELP_ogGetRepoIp="Returns OpenGnsys Repository IP address ."
MSG_HELP_ogGetSerialNumber="Returns host serial number."
MSG_HELP_ogGetServerIp="Returns main OpenGnsys Server IP address."
MSG_HELP_ogGetSizeParameters="Returns file system data size, required space for image and if it fits in the chosen repository."
MSG_HELP_ogGetWindowsName="Returns saved client name on Windows registry."
MSG_HELP_ogGrubAddOgLive="Adds MBR grub an entry calling Opengnsys client."
MSG_HELP_ogGrubDefaultEntry="Sets GRUB default entry."
MSG_HELP_ogGrubDeleteEntry="Deletes partition start entries on MBR grub."
MSG_HELP_ogGrubHidePartitions="Sets MBR grub to hide non starting Windows partitions. Allows you to select a partition that will not be hidden (e.g. for data)."
MSG_HELP_ogGrubInstallMbr="Installs GRUB boot loader on 1st HD MBR"
MSG_HELP_ogGrubInstallPartition="Installs GRUB boot loader on BootSector"
MSG_HELP_ogGrubOgliveDefaultEntry="Sets ogLive entry as default GRUB entry."
MSG_HELP_ogGrubSecurity="Configures user and password for change the menu entries of grub."
MSG_HELP_ogGrubUefiConf="Generates the grub.cfg file of the EFI partition."
MSG_HELP_ogHelp="Shows functions help messages."
MSG_HELP_ogHidePartition="Hides Windows partition."
MSG_HELP_ogIdToType="Returns partition type identifier."
MSG_HELP_ogInstallFirstBoot="Creates file to run on first Windows boot."
MSG_HELP_ogInstallLaunchDaemon="Installs file to run on MACos boot."
MSG_HELP_ogInstallLinuxClient=MSG_OBSOLETE
MSG_HELP_ogInstallMiniSetup="Installs file to run on Windows boot."
MSG_HELP_ogInstallRunonce="Creates file to run on admin-user Windows boot."
MSG_HELP_ogInstallWindowsClient=MSG_OBSOLETE
MSG_HELP_ogIsFormated="Checks file system if formatted."
MSG_HELP_ogIsImageLocked="Checks image if blocked by exclusive use operation."
MSG_HELP_ogIsLocked="Checks partition or disk if blocked by exclusive use operation."
MSG_HELP_ogIsDiskLocked="Checks disk if blocked by exclusive use operation."
MSG_HELP_ogIsMounted="Checks file system if mounted."
MSG_HELP_ogIsNewerFile="Checks if one file is newer (or has been modified later) than another one."
MSG_HELP_ogIsPartitionLocked=MSG_HELP_ogIsLocked
MSG_HELP_ogIsRepoLocked=""
MSG_HELP_ogIsSyncImage="Checks image if synchronizable."
MSG_HELP_ogIsVirtualMachine="Checks if client is a virtual machine"
MSG_HELP_ogIsWritable="Checks if mounted file system has write permissions."
MSG_HELP_ogLinuxBootParameters="Returns installed Linux boot parameters."
MSG_HELP_ogListHardwareInfo="Lists the client hardware inventory."
MSG_HELP_ogListLogicalPartitions="Lists disk logic partitions."
MSG_HELP_ogListPartitions="Lists disk partitions table."
MSG_HELP_ogListPrimaryPartitions="Lists disk primary partitions"
MSG_HELP_ogListRegistryKeys="Lists sub-keys names included on a Windows registry key."
MSG_HELP_ogListRegistryValues="Lists value names included on a Windows registry key."
MSG_HELP_ogListSoftware="Lists OS installed programs inventory."
MSG_HELP_ogLock="Blocks partition for exclusive use operation."
MSG_HELP_ogLockDisk="Blocks disk for exclusive use operation."
MSG_HELP_ogLockImage="Blocks image for exclusive use operation."
MSG_HELP_ogLockPartition=MSG_HELP_ogLock
MSG_HELP_ogMakeChecksumFile="Stores file checksum."
MSG_HELP_ogMakeDir="Makes OpenGnsys directory."
MSG_HELP_ogMakeGroupDir="Makes group (lab) directory on repository."
MSG_HELP_ogMcastReceiverFile=""
MSG_HELP_ogMcastReceiverPartition=""
MSG_HELP_ogMcastRequest=""
MSG_HELP_ogMcastSendFile=""
MSG_HELP_ogMcastSendPartition=""
MSG_HELP_ogMcastSyntax=""
MSG_HELP_ogMountCache="Mounts cache file system."
MSG_HELP_ogMountCdrom="Mounts default optical drive."
MSG_HELP_ogMountImage="Mounts synchronizable image"
MSG_HELP_ogMount="Mounts file system and returns mount point."
MSG_HELP_ogMountFs=MSG_HELP_ogMount
MSG_HELP_ogNvramActiveEntry="Sets active a bootloader (NVRAM) entry."
MSG_HELP_ogNvramAddEntry="Creates new entry in bootloader (NVRAM)."
MSG_HELP_ogNvramDeleteEntry="Deletes a bootloader (NVRAM) entry."
MSG_HELP_ogNvramGetCurrent="Displays the bootloader (NVRAM) entry that was started by the computer."
MSG_HELP_ogNvramGetNext="Displays the bootloader (NVRAM) entry for the boot next."
MSG_HELP_ogNvramGetOrder="Displays the bootloader (NVRAM) entries order."
MSG_HELP_ogNvramGetTimeout="Displays the bootloader (NVRAM) timeout."
MSG_HELP_ogNvramInactiveEntry="Sets inactive bootloader (NVRAM) entry."
MSG_HELP_ogNvramList="Lists bootloader (NVRAM) entries, by staring actives ones."
MSG_HELP_ogNvramPxeFirstEntry="Set the network as the NVRAM first boot."
MSG_HELP_ogNvramSetNext="Set the bootloader (NVRAM) entry for the boot next."
MSG_HELP_ogNvramSetOrder="Sets the bootloader (NVRAM) entries order."
MSG_HELP_ogNvramSetTimeout="Sets the bootloader (NVRAM) timeout."
MSG_HELP_ogRaiseError="Displays and registers error messages and returns code."
MSG_HELP_ogReduceFs="Reduces file system size to minimum."
MSG_HELP_ogReduceImage="Reduces image size."
MSG_HELP_ogRefindDeleteEntry="Deletes the menu entry of a partition in rEFInd."
MSG_HELP_ogRefindDefaultEntry="Configures default menu entry in rEFInd."
MSG_HELP_ogRefindOgliveDefaultEntry="Configures ogLive menu entry as default menu entry in rEFInd."
MSG_HELP_ogRefindSetTheme="Configures rEFInd's theme."
MSG_HELP_ogRefindSetTimeOut="Defines the time that rEFInd shows the menu."
MSG_HELP_ogRefindSetResolution="Defines the resolucion of rEFInd's theme."
MSG_HELP_ogRefindInstall="Installs and configures rEFInd boot loader in ESP."
MSG_HELP_ogRestoreAclImage="Restores Windows ACL (Inf. must be on /tmp)."
MSG_HELP_ogRestoreBootLoaderImage=""
MSG_HELP_ogRestoreDiskImage="Restores disk image."
MSG_HELP_ogRestoreEfiBootLoader="Copy the boot loader from the system partition to the EFI partition."
MSG_HELP_ogRestoreImage="Restore OS image."
MSG_HELP_ogRestoreInfoImage="Restores system information: ACL and symbolic links"
MSG_HELP_ogRestoreMbrImage="Restores boot sector image (MBR)."
MSG_HELP_ogRestoreUuidPartitions="Restores UUID of partitions and partition table."
MSG_HELP_ogSaveImageInfo="Creates the image information file."
MSG_HELP_ogSetLinuxName=""
MSG_HELP_ogSetPartitionActive="Sets active partition number of disk."
MSG_HELP_ogSetPartitionId="Changes partition ID using mnemonic."
MSG_HELP_ogSetPartitionSize="Sets partition size."
MSG_HELP_ogSetPartitionType="Changes partition type ID."
MSG_HELP_ogSetRegistryValue="Assigns data to a Windows registry values."
MSG_HELP_ogSetWindowsName="Assigns client name to Windows registry."
MSG_HELP_ogSetWinlogonUser="Assigns Windows default user name to Windows input manager."
MSG_HELP_ogSyncCreate="Synchronizes partition data to image"
MSG_HELP_ogSyncRestore="Synchronize image data to partition"
MSG_HELP_ogTorrentStart=""
MSG_HELP_ogTypeToId="Returns the ID of partition type mnemonic."
MSG_HELP_ogUcastReceiverPartition=""
MSG_HELP_ogUcastSendFile=""
MSG_HELP_ogUcastSendPartition=""
MSG_HELP_ogUcastSyntax=""
MSG_HELP_ogUnhidePartition="Unhides Windows partition."
MSG_HELP_ogUninstallLinuxClient="Uninstalls old OpenGnSys agent from Linux OS."
MSG_HELP_ogUninstallWindowsClient="Uninstalls oldOpenGnSys agent from Windows OS."
MSG_HELP_ogUnlock="Unlocks partition after exclusive use operation."
MSG_HELP_ogUnlockDisk="Unlocks disk after exclusive use operation."
MSG_HELP_ogUnlockImage="Unlocks image after exclusive use operation."
MSG_HELP_ogUnlockPartition=MSG_HELP_ogUnlock
MSG_HELP_ogUnmountAll="Unmounts all file systems."
MSG_HELP_ogUnmountCache="Unmounts cache file system."
MSG_HELP_ogUnmountImage="Unmounts image"
MSG_HELP_ogUnmount="Unmounts file system."
MSG_HELP_ogUnmountFs=MSG_HELP_ogUnmount
MSG_HELP_ogUnsetDirtyBit=""
MSG_HELP_ogUpdateCacheIsNecesary="Checks if necessary file update in local cache."
MSG_HELP_ogUpdatePartitionTable="Updates disk partition table info "
MSG_HELP_ogUuidChange="Replaces the filesystem UUID"
MSG_HELP_ogWaitSyncImage=""
MSG_HELP_ogWindowsBootParameters=""
MSG_HELP_ogWindowsRegisterPartition=""
# Scripts
MSG_HELP_configureOs="Post-configure system boot"
MSG_HELP_createBaseImage="Create partition basic image"
MSG_HELP_createDiffImage="Create partition differential image from basic image"
MSG_HELP_installOfflineMode="Prepare client for off-line mode."
MSG_HELP_partclone2sync="Turn part-clone image into synchronizable image."
MSG_HELP_restoreBaseImage="Restore basic image into partition"
MSG_HELP_restoreDiffImage="Restore differential image into partition"
MSG_HELP_updateCache="Update cache"
# INTERFACE functions messages.
MSG_INTERFACE_START="[START Interface] Run command: "
MSG_INTERFACE_END="[END Interface] Command finished with this code: "
# SCRIPTS messages.
MSG_SCRIPTS_START=" START scripts: "
MSG_SCRIPTS_END=" END scripts: "
MSG_SCRIPTS_TASK_END="End of task"
MSG_SCRIPTS_TASK_SLEEP="Waiting to start"
MSG_SCRIPTS_TASK_START="Starting"
MSG_SCRIPTS_TASK_ERR="Error"
# createImage script
MSG_SCRIPTS_FILE_RENAME="Rename previous image-file: "
MSG_SCRIPTS_CREATE_SIZE="Check required and available storing space(KB): "
# updateCache script
MSG_SCRIPTS_UPDATECACHE_DOUPDATE="Check if it is necessary to update image file"
MSG_SCRIPTS_UPDATECACHE_CHECKSIZECACHE="Check if Cache size is bigger than image file size."
# Script updateCache: for dir synchronized images .
MSG_SCRIPTS_UPDATECACHE_CHECKSIZEDIR="Calculate image size."
MSG_SCRIPTS_UPDATECACHE_CHECKSIZEIMG="Check if repository image file size is bigger than Cache size."
MSG_SCRIPTS_UPDATECACHE_IFNOTCACHEDO="Check free Cache and apply engine.cfg"
MSG_SCRIPTS_UPDATECACHE_CHECKMCASTSESSION="Checking Multicast Session McastServer:DataPort"
# interface temporarily replaces restore script
MSG_SCRIPTS_CHECK_ENGINE="Analyze process to carry out according to engine.cfg"
MSG_SCRIPTS_MULTICAST_PRECHECK_PORT="Check main and auxiliary Multicast port."
MSG_SCRIPTS_MULTICAST_CHECK_PORT="Check session and data ports"
MSG_SCRIPTS_MULTICAST_REQUEST_PORT="Request Multicast port opening: "
MSG_SCRIPTS_OS_CONFIGURE="Start restored system setting"
# TIME MESSAGES
MSG_SCRIPTS_TIME_TOTAL="Total process time"
MSG_SCRIPTS_TIME_PARTIAL="Partial sub-process time"
# HTTPLOG
MSG_HTTPLOG_NOUSE="PLEASE DO NOT TURN OFF THIS COMPUTER"
# Messages for synchronized images (complementary to errors)
MSG_SYNC_RESIZE="Resize image to necessary size"
MSG_SYNC_RESTORE="Get files list and download image"
MSG_SYNC_DELETE="Differential: Delete old files"
MSG_SYNC_SLEEP="Wait for mounting/reducing image"
# Messages for synchronized images (complementary to errors)
MSG_SYNC_DIFFERENTFS="Destination file system does not match image"
MSG_SYNC_EXTENSION="Image extension must be img or diff"
MSG_SYNC_NOCHECK="Image mounted by another process. Cannot verify it"
MSG_RESTORE="Restore image on "

View File

@ -1,387 +0,0 @@
#!/usr/bin/python3
# Fichero de idioma: español.
#@version 1.1.1
#@author
# Mensajes de error.
MSG_ERR_GENERIC="Error imprevisto no definido"
MSG_ERR_FORMAT="Formato de ejecución incorrecto"
MSG_ERR_OUTOFLIMIT="Valor fuera de rango o no válido"
MSG_ERR_NOTFOUND="Fichero o dispositivo no encontrado"
MSG_ERR_PARTITION="Partición errónea o desconocida"
MSG_ERR_LOCKED="Recurso bloqueado por operación de uso exclusivo"
MSG_ERR_CACHE="Error en partición de caché local"
MSG_ERR_NOGPT="El disco indicado no contiene una partición GPT"
MSG_ERR_REPO="Error al montar el repositorio de imágenes"
MSG_ERR_NOMSDOS="El disco indicado no contiene una partición MSDOS"
MSG_ERR_FILESYS="Sistema de archivos desconocido o no se puede montar"
MSG_ERR_NOTOS="Sistema operativo no detectado o no se puede iniciar"
MSG_ERR_IMAGE="No se puede crear o restaurar una image de sistema"
MSG_ERR_IMAGEFILE="Archivo de imagen corrupto o de otra versión de partclone"
MSG_ERR_NOTEXEC="Programa o función no ejecutable"
MSG_ERR_NOTWRITE="No hay acceso de escritura"
MSG_ERR_NOTCACHE="No existe partición caché en el cliente"
MSG_ERR_NOTUEFI="La interfaz UEFI no está activa"
MSG_ERR_NOTBIOS="La interfaz BIOS Legacy no está activa"
MSG_ERR_CACHESIZE="El espacio de la caché local o remota no es suficiente"
MSG_ERR_REDUCEFS="Error al reducir el sistema de archivos"
MSG_ERR_EXTENDFS="Error al expandir el sistema de archivos"
MSG_ERR_IMGSIZEPARTITION="Error al restaurar: Partición mas pequeña que la imagen"
MSG_ERR_UPDATECACHE="Error al realizar el comando updateCache"
MSG_ERR_UCASTSYNTAXT="Error en la generación de sintaxis de transferenica Unicast"
MSG_ERR_UCASTSENDPARTITION="Error en envío Unicast de una partición"
MSG_ERR_UCASTSENDFILE="Error en envío Unicast de un fichero"
MSG_ERR_UCASTRECEIVERPARTITION="Error en la recepción Unicast de una partición"
MSG_ERR_UCASTRECEIVERFILE="Error en la recepción Unicast de un fichero"
MSG_ERR_MCASTSYNTAXT="Error en la generación de sintaxis de transferenica Multicast"
MSG_ERR_MCASTSENDFILE="Error en envío Multicast de un fichero"
MSG_ERR_MCASTRECEIVERFILE="Error en la recepción Multicast de un fichero"
MSG_ERR_MCASTSENDPARTITION="Error en envío Multicast de una partición"
MSG_ERR_MCASTRECEIVERPARTITION="Error en la recepción Multicast de un fichero"
MSG_ERR_PROTOCOLJOINMASTER="Error en la conexión de una sesión Unicast|Multicast con el Master"
MSG_ERR_DONTFORMAT="Error al formatear"
MSG_ERR_DONTMOUNT_IMAGE="Error al montar/reducir la imagen"
MSG_ERR_DONTUNMOUNT_IMAGE="Error al desmontar la imagen"
MSG_ERR_DONTSYNC_IMAGE="Imagen no sincronizable"
MSG_ERR_NOTDIFFERENT="No se detectan diferencias entre la imagen básica y la partición"
MSG_ERR_SYNCHRONIZING="Error al sincronizar, puede afectar la creacion|restauracion de la imagen"
# Mensajes de avisos.
MSG_DONTMOUNT="Sistema de archivos no montado"
MSG_DONTUSE="NO USAR"
MSG_DONTUNMOUNT="El sistema de archivos no se puede desmontar o no está montado"
MSG_MOUNT="Sistema de archivos montado"
MSG_MOUNTREADONLY="Sistema de archivos montado solo de lectura"
MSG_OBSOLETE="EN DESUSO"
# Mensajes complementarios para las ayudas.
MSG_64BIT="64 bits"
MSG_DISK="disco"
MSG_ERROR="Error"
MSG_EXAMPLE="Ejemplo"
MSG_FORMAT="Formato"
MSG_FUNCTION="Función"
MSG_HARDWAREINVENTORY="Inventario de hardware de la máquina"
MSG_IMAGE="imagen"
MSG_INSTALLED="instalado"
MSG_NOCACHE="sin caché local"
MSG_NOEXTENDED="sin partición extendida"
MSG_PARTITION="partición"
MSG_PROTOCOL="protocolo"
MSG_RESERVEDVALUE="Valor reservado"
MSG_SEE="Ver"
MSG_UNKNOWN="Desconocido"
MSG_WARNING="Aviso"
# Mensajes del proceso de arranque.
MSG_DETECTLVMRAID="Detectar metadispositivos LVM y RAID."
MSG_ERRBOOTMODE=f"{MSG_ERROR}: Modo de arranque desconocido."
MSG_LAUNCHCLIENT="Ejecutar cliente."
MSG_LOADAPI="Cargar funciones del motor de clonación."
MSG_LOADMODULES="Cargar módulos del kernel."
MSG_MAKELINKS="Crear enlaces simbólicos."
MSG_MOUNTREPO="Montar repositorio por %s en modo %s."
MSG_OFFLINEMODE="Modo de arranque sin conexión."
MSG_OTHERSERVICES="Iniciar servicios complementarios del cliente."
MSG_POWEROFFCONF="Definir parámetros de ahorro de energía."
# Mensajes del menú por defecto.
MSG_BOOT="Iniciar"
MSG_DUPLEX="D&uacute;plex"
MSG_HOSTNAME="Equipo"
MSG_IPADDR="Direcci&oacute;n IP"
MSG_MACADDR="Direcci&oacute;n MAC"
MSG_MENUTITLE="Men&uacute; de opciones"
MSG_POWEROFF="Apagar el equipo"
MSG_SPEED="Velocidad"
# Mensajes de descripción breve de las funciones de la API.
MSG_HELP_ogAclFilter="Extrae las acl de los ficheros de la diferencial"
MSG_HELP_ogAddCmd="Añade comandos al fichero creado por la función ogInstalMiniSetup."
MSG_HELP_ogAddRegistryKey="Añade una nueva clave al registro de Windows."
MSG_HELP_ogAddRegistryValue="Añade un nuevo valor al registro de Windows."
MSG_HELP_ogAddToLaunchDaemon=""
MSG_HELP_ogBoot="Arranca un sistema operativo instalado."
MSG_HELP_ogBootLoaderDeleteEntry=MSG_DONTUSE
MSG_HELP_ogBootLoaderHidePartitions=MSG_DONTUSE
MSG_HELP_ogBootMbrGeneric=""
MSG_HELP_ogBootMbrXP=""
MSG_HELP_ogBurgDefaultEntry="Configura la entrada por defecto de Burg."
MSG_HELP_ogBurgDeleteEntry="Borra en el Burg del MBR las entradas para el inicio en una particion."
MSG_HELP_ogBurgHidePartitions="Configura el Burg del MBR para que oculte las particiones de windows que no se esten iniciando. Permite definir una partición que no se ocultará (ej: para datos)."
MSG_HELP_ogBurgInstallMbr="Instala el gestor de arranque BURG en el MBR del primer disco duro"
MSG_HELP_ogBurgOgliveDefaultEntry="Configura la entrada de ogLive como la entrada por defecto de Burg."
MSG_HELP_ogCalculateChecksum="Calcula la suma de comprobación (checksum) de un fichero."
MSG_HELP_ogCalculateFullChecksum="Calcula la suma de comprobación completa de un fichero."
MSG_HELP_ogChangeRepo="Cambia el repositorio para el recurso remoto images."
MSG_HELP_ogCheckFs="Comprueba la consistencia de un sistema de archivos."
MSG_HELP_ogCheckIpAddress=""
MSG_HELP_ogCheckProgram=""
MSG_HELP_ogCheckStringInGroup=""
MSG_HELP_ogCheckStringInReg=""
MSG_HELP_ogCheckSyncImage="Muestra el contenido de la imagen para comprobarla."
MSG_HELP_ogCleanLinuxDevices=""
MSG_HELP_ogCleanOs="Elimina los archivos que no son necesarios en el sistema operativo."
MSG_HELP_ogCompareChecksumFiles="Compara si coinciden las sumas de comprobación almacenadas de 2 ficheros."
MSG_HELP_ogConfigureFstab=""
MSG_HELP_ogConfigureOgagent="Configura el nuevo agente OGAgent para sistemas operativos."
MSG_HELP_ogCopyFile="Copia un fichero a otro almacenamiento."
MSG_HELP_ogCreateBootLoaderImage=""
MSG_HELP_ogCreateCache="Reserva espacio para la partición de caché al final del disco."
MSG_HELP_ogCreateDiskImage="Genera una imagen exacta de un disco completo."
MSG_HELP_ogCreateFileImage="Crea/redimensiona el archivo de la imagen sincronizada"
MSG_HELP_ogCreateGptPartitions=""
MSG_HELP_ogCreateImage="Genera una imagen exacta de un sistema operativo instalado localmente."
MSG_HELP_ogCreateImageSyntax=""
MSG_HELP_ogCreateInfoImage="Crea información del contenido de la imagen"
MSG_HELP_ogCreateMbrImage="Genera una imagen del sector de arranque (MBR)."
MSG_HELP_ogCreatePartitions="Define la estructura de particiones de un disco."
MSG_HELP_ogCreatePartitionTable="Genera una tabla de particiones en caso de que no sea valida."
MSG_HELP_ogCreateTorrent=""
MSG_HELP_ogCopyEfiBootLoader="Copia el cargador de arranque desde la partición EFI a la de sistema."
MSG_HELP_ogDeleteCache="Elimina la partición de caché local."
MSG_HELP_ogDeleteFile="Borra un fichero de un espacio de almacenamiento."
MSG_HELP_ogDeletePartitionTable="Elimina la tabla de particiones del disco"
MSG_HELP_ogDeleteRegistryKey="Borra una clave vacía del registro de Windows."
MSG_HELP_ogDeleteRegistryValue="Borra un valor del registro de Windows."
MSG_HELP_ogDeleteTree="Borra un árbol de directorios de un espacio de almacenamiento."
MSG_HELP_ogDevToDisk="Devuelve el nº de orden de disco o de partición correspondiente al camino del fichero de dispositivo."
MSG_HELP_ogDiskToDev="Devuelve el camino del fichero de dispositivo correspondiente al nº de orden de disco o de partición."
MSG_HELP_ogDomainScript=""
MSG_HELP_ogEcho="Muestra un mensaje en pantalla y permite registrarlo en fichero de log"
MSG_HELP_ogExecAndLog="Ejecuta un comando y registra su salida en fichero de log"
MSG_HELP_ogExtendFs="Extiende el tamaño de un sistema de archivo al máximo de su partición."
MSG_HELP_ogFindCache="Indica la partición reservada para caché local."
MSG_HELP_ogFixBootSector=""
MSG_HELP_ogFormatCache="Formatea (inicia) el sistema de caché local."
MSG_HELP_ogFormat="Formatea o reformatea un sistema de archivos."
MSG_HELP_ogFormatFs=MSG_HELP_ogFormat
MSG_HELP_ogGetArch="Devuelve el tipo de arquitectura del cliente."
MSG_HELP_ogGetCacheSize="Devuelve el tamaño de la partición de caché local."
MSG_HELP_ogGetCacheSpace="Devuelve el espacio máximo disponible que puede ser reservado para la partición de caché local."
MSG_HELP_ogGetCaller="Devuelve el programa o función que llama al actual"
MSG_HELP_ogGetDiskSize="Devuelve el tamaño del disco."
MSG_HELP_ogGetDiskType="Devuelve el mnemónico de tipo de disco."
MSG_HELP_ogGetFreeSize=""
MSG_HELP_ogGetFsSize="Devuelve el tamaño de un sistema de archivos."
MSG_HELP_ogGetFsType="Devuelve el mnemónico de tipo de sistema de archivos."
MSG_HELP_ogGetGroupDir="Devuelve el camino del directorio por defecto para el grupo del cliente."
MSG_HELP_ogGetGroupName="Devuelve el nombre del grupo al que pertenece el cliente."
MSG_HELP_ogGetHivePath="Devuelve el camino completo del fichero de una sección del registro de Windows."
MSG_HELP_ogGetHostname="Devuelve el nombre de la máquina local."
MSG_HELP_ogGetImageCompressor="Devuelve la herramienta de compresión de la imagen."
MSG_HELP_ogGetImageInfo="Muestra información sobre la imagen monolitica: clonacion:compresor:sistemaarchivos:tamañoKB."
MSG_HELP_ogGetImageProgram="Devuelve el programa usado para crear la imagen."
MSG_HELP_ogGetImageSize="Devuelve el tamaño de una imagen de sistema."
MSG_HELP_ogGetImageType="Devuelve el sistema de ficheros de la imagen."
MSG_HELP_ogGetIpAddress="Devuelve la dirección IP del cliente."
MSG_HELP_ogGetLastSector="Devuelve el último sector usable del disco o de una partición."
MSG_HELP_ogGetMacAddress="Devuelve la dirección Ethernet del cliente."
MSG_HELP_ogGetMountImageDir="Devuelve el directorio de montaje de una imagen."
MSG_HELP_ogGetMountPoint="Devuelve el directorio donde está montado un sistema de archivos local."
MSG_HELP_ogGetNetInterface=""
MSG_HELP_ogGetOsType="Devuelve el tipo de un sistema operativo instalado."
MSG_HELP_ogGetOsUuid="Devuelve el UUID de un sistema operativo"
MSG_HELP_ogGetOsVersion="Devuelve el tipo y la versión de un sistema operativo instalado."
MSG_HELP_ogGetParentPath="Devuelve el camino completo del directorio padre de un fichero de sistema OpenGnsys."
MSG_HELP_ogGetPartitionActive="Indica cual es la partición marcada como activa en un disco."
MSG_HELP_ogGetPartitionId="Devuelve el identificador de tipo de una partición."
MSG_HELP_ogGetPartitionSize="Devuelve el tamaño de una partición."
MSG_HELP_ogGetPartitionsNumber="Devuelve el número de particiones de un disco"
MSG_HELP_ogGetPartitionTableType="Devuelve el tipo de tabla de particiones del disco"
MSG_HELP_ogGetPartitionType="Devuelve el mnemónico de tipo de una partición."
MSG_HELP_ogGetPath="Devuelve el camino completo de un fichero de sistema OpenGnsys."
MSG_HELP_ogGetRegistryValue="Devuelve el dato de un valor del registro de Windows."
MSG_HELP_ogGetRepoIp="Devuelve la dirección IP del repositorio de datos."
MSG_HELP_ogGetSerialNumber="Devuelve el número de serie del equipo"
MSG_HELP_ogGetServerIp="Devuelve la dirección IP del servidor principal."
MSG_HELP_ogGetSizeParameters="Devuelve el tamaño de los datos de un sistema de ficheros, el espacio necesario para la imagen y si cabe en el repositorio elegido."
MSG_HELP_ogGetWindowsName="Devuelve el nombre del cliente guardado en el registro de Windows."
MSG_HELP_ogGrubAddOgLive="Incluye en el grub del MBR una entrada llamando al cliente de opengnsys."
MSG_HELP_ogGrubDefaultEntry="Configura la entrada por defecto de GRUB."
MSG_HELP_ogGrubDeleteEntry="Borra en el grub del MBR las entradas para el inicio en una particion."
MSG_HELP_ogGrubHidePartitions="Configura el grub del MBR para que oculte las particiones de windows que no se esten iniciando. Permite definir una partición que no se ocultará (ej: para datos)."
MSG_HELP_ogGrubInstallMbr="Instala el gestor de arranque GRUB en el MBR del primer disco duro"
MSG_HELP_ogGrubInstallPartition="Instala el gestor de arranque GRUB en el BootSector"
MSG_HELP_ogGrubOgliveDefaultEntry="Configura la entrada de ogLive como la entrada por defecto de GRUB."
MSG_HELP_ogGrubSecurity="Configura usuario y clave para modificar las entradas del menu del Grub."
MSG_HELP_ogGrubUefiConf="Genera el fichero grub.cfg de la partición EFI."
MSG_HELP_ogHelp="Muestra mensajes de ayudas para las funciones."
MSG_HELP_ogHidePartition="Oculta una partición de Windows."
MSG_HELP_ogIdToType="Devuelve el mnemónico asociado al identificador de tipo de partición."
MSG_HELP_ogInstallFirstBoot="Crea un archivo que se ejecutará en el primer arranque de Windows."
MSG_HELP_ogInstallLaunchDaemon="Instala un archivo que se ejecutará en el arranque de macOS."
MSG_HELP_ogInstallLinuxClient=MSG_OBSOLETE
MSG_HELP_ogInstallMiniSetup="Instala un archivo que se ejecutará en el arranque de Windows."
MSG_HELP_ogInstallRunonce="Crea archivo que se ejecutará en el inicio de un usuario administrador de Windows."
MSG_HELP_ogInstallWindowsClient=MSG_OBSOLETE
MSG_HELP_ogIsFormated="Comprueba si un sistema de archivos está formateado."
MSG_HELP_ogIsImageLocked="Comprueba si una imagen está bloqueada por una operación de uso exclusivo."
MSG_HELP_ogIsLocked="Comprueba si una partición o su disco están bloqueados por una operación de uso exclusivo."
MSG_HELP_ogIsDiskLocked="Comprueba si un disco está bloqueado por una operación de uso exclusivo."
MSG_HELP_ogIsMounted="Comprueba si un sistema de archivos está montado."
MSG_HELP_ogIsNewerFile="Comprueba si un fichero es más nuevo (se ha modificado después) que otro."
MSG_HELP_ogIsPartitionLocked=MSG_HELP_ogIsLocked
MSG_HELP_ogIsRepoLocked=""
MSG_HELP_ogIsSyncImage="Comprueba si la imagen es sincronizable."
MSG_HELP_ogIsVirtualMachine="Comprueba si el cliente es una máquina virtual"
MSG_HELP_ogIsWritable="Comprueba si un sistema de archivos está montado con permiso de escritura."
MSG_HELP_ogLinuxBootParameters="Devuelve los parámetros de arranque de un sistema operativo Linux instalado."
MSG_HELP_ogListHardwareInfo="Lista el inventario de dispositivos del cliente."
MSG_HELP_ogListLogicalPartitions="Lista las particiones lógicas de un disco"
MSG_HELP_ogListPartitions="Lista la estructura de particiones de un disco."
MSG_HELP_ogListPrimaryPartitions="Lista las particiones primarias de un disco"
MSG_HELP_ogListRegistryKeys="Lista los nombres de las subclaves incluidas en una clave del registro de Windows."
MSG_HELP_ogListRegistryValues="Lista los nombres de los valores incluidos en una clave del registro de Windows."
MSG_HELP_ogListSoftware="Lista el inventario de programas instalados en un sistema operativo."
MSG_HELP_ogLock="Bloquea una partición para operación de uso exclusivo."
MSG_HELP_ogLockDisk="Bloquea un disco para operación de uso exclusivo."
MSG_HELP_ogLockImage="Bloquea una imagen para operación de uso exclusivo."
MSG_HELP_ogLockPartition=MSG_HELP_ogLock
MSG_HELP_ogMakeChecksumFile="Almacena la suma de comprobación de un fichero."
MSG_HELP_ogMakeDir="Crea un directorio para OpenGnsys."
MSG_HELP_ogMakeGroupDir="Crea el directorio de grupo (aula) en un repositorio."
MSG_HELP_ogMcastReceiverFile=""
MSG_HELP_ogMcastReceiverPartition=""
MSG_HELP_ogMcastRequest=""
MSG_HELP_ogMcastSendFile=""
MSG_HELP_ogMcastSendPartition=""
MSG_HELP_ogMcastSyntax=""
MSG_HELP_ogMountCache="Monta el sistema de archivos dedicado a caché local."
MSG_HELP_ogMountCdrom="Monta dispositivo óptico por defecto."
MSG_HELP_ogMountImage="Monta una imagen sincronizable"
MSG_HELP_ogMount="Monta un sistema de archivos y devuelve el punto de montaje."
MSG_HELP_ogMountFs=MSG_HELP_ogMount
MSG_HELP_ogNvramActiveEntry="Configura a activa entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramAddEntry="Crea nueva entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramDeleteEntry="Borra entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramGetCurrent="Muestra la entrada del gestor de arranque (NVRAM) que ha iniciado el equipo."
MSG_HELP_ogNvramGetNext="Muestra la entrada del gestor de arranque (NVRAM) que se utilizará en el próximo arranque."
MSG_HELP_ogNvramGetOrder="Muestra el orden de las entradas del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramGetTimeout="Muestra el tiempo de espera del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramInactiveEntry="Configura a inactiva entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramList="Lista las entradas del gestor de arranque (NVRAN) marcando con un asterisco las activas"
MSG_HELP_ogNvramPxeFirstEntry="Configura la tarjeta de red como primer arranque en la NVRAM."
MSG_HELP_ogNvramSetNext="Configura el próximo arranque con la entrada del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramSetOrder="Configura el orden de las entradas del gestor de arranque (NVRAM)."
MSG_HELP_ogNvramSetTimeout="Configura el tiempo de espera del gestor de arranque (NVRAM)."
MSG_HELP_ogRaiseError="Muestra y registra mensajes de error y devuelve el código correspondiente."
MSG_HELP_ogReduceFs="Reduce el tamaño del sistema de archivos al mínimo ocupado por sus datos."
MSG_HELP_ogReduceImage="Reduce el tamaño de la imagen"
MSG_HELP_ogRefindDeleteEntry="Borra en rEFInd las entradas para el inicio en una particion."
MSG_HELP_ogRefindDefaultEntry="Configura la entrada por defecto de rEFInd."
MSG_HELP_ogRefindOgliveDefaultEntry="Configura la entrada de ogLive como la entrada por defecto de rEFInd."
MSG_HELP_ogRefindSetTheme="Asigna un tema al rEFInd."
MSG_HELP_ogRefindSetTimeOut="Define el tiempo (segundos) que se muestran las opciones de inicio de rEFInd."
MSG_HELP_ogRefindSetResolution="Define la resolución que usuará el thema del gestor de arranque rEFInd."
MSG_HELP_ogRefindInstall="Instala y configura el gestor rEFInd en la particion EFI"
MSG_HELP_ogRestoreAclImage="Restaura las ACL de Windows (La informacion debe estar copiada en /tmp)."
MSG_HELP_ogRestoreBootLoaderImage=""
MSG_HELP_ogRestoreDiskImage="Restaura una imagen de un disco completo."
MSG_HELP_ogRestoreEfiBootLoader="Copia el cargador de arranque de la partición de sistema a la partición EFI."
MSG_HELP_ogRestoreImage="Restaura una imagen de sistema operativo."
MSG_HELP_ogRestoreInfoImage="Restablece información del sistema: ACL y enlaces simbolicos"
MSG_HELP_ogRestoreMbrImage="Restaura una imagen del sector de arranque (MBR)."
MSG_HELP_ogRestoreUuidPartitions="Restaura los uuid de las particiones y la tabla de particiones."
MSG_HELP_ogSaveImageInfo="Crea un fichero con la información de la imagen."
MSG_HELP_ogSetLinuxName=""
MSG_HELP_ogSetPartitionActive="Establece el número de partición activa de un disco."
MSG_HELP_ogSetPartitionId="Modifica el tipo de una partición física usando el mnemónico del tipo."
MSG_HELP_ogSetPartitionSize="Establece el tamaño de una partición."
MSG_HELP_ogSetPartitionType="Modifica el identificador de tipo de una partición física."
MSG_HELP_ogSetRegistryValue="Asigna un dato a un valor del registro de Windows."
MSG_HELP_ogSetWindowsName="Asigna el nombre del cliente en el registro de Windows."
MSG_HELP_ogSetWinlogonUser="Asigna el nombre de usuario por defecto para el gestor de entrada de Windows."
MSG_HELP_ogSyncCreate="Sincroniza los datos de la partición a la imagen"
MSG_HELP_ogSyncRestore="Sincroniza los datos de la imagen a la partición"
MSG_HELP_ogTorrentStart=""
MSG_HELP_ogTypeToId="Devuelve el identificador asociado al mnemónico de tipo de partición."
MSG_HELP_ogUcastReceiverPartition=""
MSG_HELP_ogUcastSendFile=""
MSG_HELP_ogUcastSendPartition=""
MSG_HELP_ogUcastSyntax=""
MSG_HELP_ogUnhidePartition="Hace visible una partición de Windows."
MSG_HELP_ogUninstallLinuxClient="Desinstala el antiguo cliente OpenGnSys en un sistema operativo Linux."
MSG_HELP_ogUninstallWindowsClient="Desinstala el antiguo cliente OpenGnSys en un sistema operativo Windows."
MSG_HELP_ogUnlock="Desbloquea una partición tras finalizar una operación de uso exclusivo."
MSG_HELP_ogUnlockDisk="Desbloquea un disco tras finalizar una operación de uso exclusivo."
MSG_HELP_ogUnlockImage="Desbloquea una imagen tras finalizar una operación de uso exclusivo."
MSG_HELP_ogUnlockPartition=MSG_HELP_ogUnlock
MSG_HELP_ogUnmountAll="Desmonta todos los sistemas de archivos."
MSG_HELP_ogUnmountCache="Desmonta el sistema de archivos de caché local."
MSG_HELP_ogUnmount="Desmonta un sistema de archivos."
MSG_HELP_ogUnmountImage="Desmonta la imagen."
MSG_HELP_ogUnmountFs=MSG_HELP_ogUnmount
MSG_HELP_ogUnsetDirtyBit=""
MSG_HELP_ogUpdateCacheIsNecesary="Comprueba si es necesario actualizar una archivo en la cache local."
MSG_HELP_ogUpdatePartitionTable="Actualiza información de la tabla de particiones del disco."
MSG_HELP_ogUuidChange="Reemplaza el UUID de un sistema de ficheros."
MSG_HELP_ogWaitSyncImage=""
MSG_HELP_ogWindowsBootParameters=""
MSG_HELP_ogWindowsRegisterPartition=""
# Scripts
MSG_HELP_configureOs="Post-configura de arranque del sistema"
MSG_HELP_createBaseImage="Genera imagen básica de la partición"
MSG_HELP_createDiffImage="Genera imagen diferencial de la partición respecto a la imagen básica"
MSG_HELP_installOfflineMode="Prepara el equipo cliente para el modo offline."
MSG_HELP_partclone2sync="Convierte imagen de partclone en imagen sincronizable."
MSG_HELP_restoreBaseImage="Restaura una imagen básica en una partición"
MSG_HELP_restoreDiffImage="Restaura una imagen diferencial en una partición"
MSG_HELP_updateCache="Realiza la actualización de la caché"
# Mensajes de descripción breve de la interfaz.
MSG_INTERFACE_START="[START Interface] Ejecutar comando: "
MSG_INTERFACE_END="[END Interface] Comando terminado con este código: "
# Mensajes de scripts.
MSG_SCRIPTS_START=" INICIO scripts: "
MSG_SCRIPTS_END=" FIN scripts: "
MSG_SCRIPTS_TASK_END="Fin de la tarea"
MSG_SCRIPTS_TASK_SLEEP="Esperando para iniciar"
MSG_SCRIPTS_TASK_START="Iniciando"
MSG_SCRIPTS_TASK_ERR="Error"
# Script createImage.
MSG_SCRIPTS_FILE_RENAME=" Renombrar fichero-imagen previo: "
MSG_SCRIPTS_CREATE_SIZE=" Calcular espacio (KB) requerido para almacenarlo y el disponible: "
# Script updateCache.
MSG_SCRIPTS_UPDATECACHE_DOUPDATE="Comprobar si es necesario actualizar el fichero imagen "
MSG_SCRIPTS_UPDATECACHE_CHECKSIZECACHE="Comprobar que el tamaño de la caché es mayor que el fichero a descargar."
# Script updateCache: para las imágenes sincronizadas tipo dir.
MSG_SCRIPTS_UPDATECACHE_CHECKSIZEDIR="Calcular el tamaño de la imagen."
MSG_SCRIPTS_UPDATECACHE_CHECKSIZEIMG="Comprobar si la imagen del repositorio es mayor que la de la caché."
MSG_SCRIPTS_UPDATECACHE_IFNOTCACHEDO="Comprobar el espacio libre de la caché y actuar según engine.cfg"
MSG_SCRIPTS_UPDATECACHE_CHECKMCASTSESSION="Comprobando sesión Multicast: ServidorMcast:PuertoDatos"
# interface sustituye temporalmente al scritp restore
MSG_SCRIPTS_CHECK_ENGINE="Analizar proceso a realizar según engine.cfg"
MSG_SCRIPTS_MULTICAST_PRECHECK_PORT="Determinar puerto principal y auxiliar Multicast."
MSG_SCRIPTS_MULTICAST_CHECK_PORT="Comprobar puertos de sesión y datos"
MSG_SCRIPTS_MULTICAST_REQUEST_PORT="Solicitar la apertura: "
MSG_SCRIPTS_OS_CONFIGURE="Iniciar la configuración del sistema restaurado"
# TIME MESSAGES
MSG_SCRIPTS_TIME_TOTAL="tiempo total del proceso"
MSG_SCRIPTS_TIME_PARTIAL="tiempo parcial del subproceso"
# HTTPLOG
MSG_HTTPLOG_NOUSE="No apague este ordenador por favor"
# Mensajes sincronizadas
MSG_SYNC_RESIZE="Redimensiona la imagen al tamaño necesario"
MSG_SYNC_RESTORE="Trae el listado ficheros y baja la imagen"
MSG_SYNC_DELETE="Diferencial: Borra archivos antiguos"
MSG_SYNC_SLEEP="Espera que se monte/reduzca la imagen"
# Mensajes sincronizadas complementarios a errores
MSG_SYNC_DIFFERENTFS="El sistema de ficheros de destino no coincide con el de la imagen"
MSG_SYNC_EXTENSION="Las extensiones de la imagenes deben ser img o diff"
MSG_SYNC_NOCHECK="La imagen esta montada por otro proceso, no podemos comprobarla"
MSG_RESTORE="Restaura la imagen en"

View File

@ -1,112 +0,0 @@
#!/usr/bin/python3
import sys
import os.path
import locale
import importlib.util
def load_lang (name):
global lang
if name in sys.modules:
return True
elif (spec := importlib.util.find_spec (name)) is not None:
lang = importlib.util.module_from_spec (spec)
sys.modules[name] = lang
spec.loader.exec_module (lang)
return True
else:
#print(f"can't find the {name!r} module")
return False
l = locale.getlocale()[0]
if not l: print (f"couldn't set locale")
if not l or not load_lang (f'lang_{l}'):
if not load_lang ('lang_en_GB'):
raise ModuleNotFoundError (f"can't find the default language module", name=name)
TZ='Europe/Madrid'
## engine.cfg
OGLOGSESSION='/tmp/session.log'
OGLOGCOMMAND='/tmp/command.log'
#OGWINCHKDISK=True #Hacer chkdisk tras la clonacion
ACTIONCACHEFULL='NONE' #Que hacer cuando la cache no tenga espacio libre. [ NONE | FORMAT ] ]
RESTOREPROTOCOLNOTCACHE=None #Que protocolo de restauracion usar en el caso de que no exista cache o no exista espacio sufiente. [NONE | UNICAST | MULTICAST].NONE retorna error
IMGPROG='partclone'
IMGCOMP='lzop'
IMGEXT='img'
IMGREDUCE=True
#OGWINREDUCE=True #Al enviar particion reducir el sistema de archivos previamente.
MCASTERRORSESSION=120 #timeout (segundos) para abortar la sesion de multicast si no contacta con el servidor de multicast. Valor asignado a 0, utiliza los valores por defecto de udp-cast
MCASTWAIT=30 # timeout (segundos) para abortar la la transferencia si se interrumpe. Valor asignado a 0, utiliza los valores por defecto de udp-cast
#CREATESPEED=100000*4 # Factor para calcular el time-out al crear la imagen. 100000k -> 4s
#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
NODEBUGFUNCTIONS=['ogCreateImageSyntax', 'ogGetHivePath', 'ogGetOsType', 'ogRestoreImageSyntax', 'ogUnmountAll', 'ogUnmountCache'] # Funciones que no deben mostrar salida de avisos si son llamadas por otras funciones.
#DEFAULTSPEED=''
## /engine.cfg
## loadenviron.sh
OPENGNSYS = '/opt/opengnsys'
OGBIN = os.path.join (OPENGNSYS, 'bin')
OGETC = os.path.join (OPENGNSYS, 'etc')
OGLIB = os.path.join (OPENGNSYS, 'lib')
OGAPI = os.path.join (OGLIB, 'engine', 'bin')
OGSCRIPTS = os.path.join (OPENGNSYS, 'scripts')
OGIMG = os.path.join (OPENGNSYS, 'images')
OGCAC = os.path.join (OPENGNSYS, 'cache')
OGLOG = os.path.join (OPENGNSYS, 'log')
OGLOGFILE = f'{OGLOG}/192.168.42.42' ## TODO import NetLib; OGLOGFILE = f'$OGLOG/{NetLib.ogGetIpAddress()}.log'
DEBUG = 'yes'
## /loadenviron.sh
# Declaración de códigos de error.
OG_ERR_FORMAT=1 # Formato de ejecución incorrecto.
OG_ERR_NOTFOUND=2 # Fichero o dispositivo no encontrado.
OG_ERR_PARTITION=3 # Error en partición de disco.
OG_ERR_LOCKED=4 # Partición o fichero bloqueado.
OG_ERR_IMAGE=5 # Error al crear o restaurar una imagen.
OG_ERR_NOTOS=6 # Sin sistema operativo.
OG_ERR_NOTEXEC=7 # Programa o función no ejecutable.
# Códigos 8-13 reservados por ogAdmClient.h
OG_ERR_NOTWRITE=14 # No hay acceso de escritura
OG_ERR_NOTCACHE=15 # No hay particion cache en cliente
OG_ERR_CACHESIZE=16 # No hay espacio en la cache para almacenar fichero-imagen
OG_ERR_REDUCEFS=17 # Error al reducir sistema archivos
OG_ERR_EXTENDFS=18 # Error al expandir el sistema de archivos
OG_ERR_OUTOFLIMIT=19 # Valor fuera de rango o no válido.
OG_ERR_FILESYS=20 # Sistema de archivos desconocido o no se puede montar
OG_ERR_CACHE=21 # Error en partición de caché local
OG_ERR_NOGPT=22 # El disco indicado no contiene una particion GPT
OG_ERR_REPO=23 # Error al montar el repositorio de imagenes
OG_ERR_NOMSDOS=24 # El disco indicado no contienen una particion MSDOS
OG_ERR_IMGSIZEPARTITION=30 # Error al restaurar partición más pequeña que la imagen
OG_ERR_UPDATECACHE=31 # Error al realizar el comando updateCache
OG_ERR_DONTFORMAT=32 # Error al formatear
OG_ERR_IMAGEFILE=33 # Archivo de imagen corrupto o de otra versión de $IMGPROG
OG_ERR_GENERIC=40 # Error imprevisto no definido
OG_ERR_UCASTSYNTAXT=50 # Error en la generación de sintaxis de transferenica UNICAST
OG_ERR_UCASTSENDPARTITION=51 # Error en envío UNICAST de partición
OG_ERR_UCASTSENDFILE=52 # Error en envío UNICAST de un fichero
OG_ERR_UCASTRECEIVERPARTITION=53 # Error en la recepcion UNICAST de una particion
OG_ERR_UCASTRECEIVERFILE=54 # Error en la recepcion UNICAST de un fichero
OG_ERR_MCASTSYNTAXT=55 # Error en la generacion de sintaxis de transferenica Multicast.
OG_ERR_MCASTSENDFILE=56 # Error en envio MULTICAST de un fichero
OG_ERR_MCASTRECEIVERFILE=57 # Error en la recepcion MULTICAST de un fichero
OG_ERR_MCASTSENDPARTITION=58 # Error en envio MULTICAST de una particion
OG_ERR_MCASTRECEIVERPARTITION=59 # Error en la recepcion MULTICAST de una particion
OG_ERR_PROTOCOLJOINMASTER=60 # Error en la conexion de una sesion UNICAST|MULTICAST con el MASTER
OG_ERR_DONTMOUNT_IMAGE=70 # Error al montar una imagen sincronizada.
OG_ERR_DONTSYNC_IMAGE=71 # Imagen no sincronizable (es monolitica)
OG_ERR_DONTUNMOUNT_IMAGE=72 # Error al desmontar la imagen
OG_ERR_NOTDIFFERENT=73 # No se detectan diferencias entre la imagen basica y la particion.
OG_ERR_SYNCHRONIZING=74 # Error al sincronizar, puede afectar la creacion/restauracion de la imagen
OG_ERR_NOTUEFI=80 # La interfaz UEFI no está activa
OG_ERR_NOTBIOS=81 # La interfaz BIOS legacy no está activa

2
debian/control vendored
View File

@ -11,6 +11,6 @@ Section: admin
Priority: optional Priority: optional
Architecture: all Architecture: all
Depends: Depends:
samba, python3 (>=3.4) | python (>= 3.4), ${misc:Depends}, ${shlibs:Depends} samba, ucf, python3 (>=3.4) | python (>= 3.4), ${misc:Depends}, ${shlibs:Depends}
Description: OpenGnsys client files Description: OpenGnsys client files
This package provides the basic filesystem for clients. This package provides the basic filesystem for clients.

55
debian/ogclient.postinst vendored 100644
View File

@ -0,0 +1,55 @@
#!/bin/sh
#. /usr/share/debconf/confmodule
set -e
case "$1" in
configure)
# Create a temporary file with the modified configuration
SMB_CONF="/etc/samba/smb-ogclient.conf"
OLD_FILE="/etc/samba/smb.conf"
NEW_FILE=$(mktemp)
# Ensure the template file exists
if [ ! -f "$SMB_CONF" ]; then
echo "Config file missing!"
exit 1
fi
# Check if our share section already exists
if grep -q "include = /etc/samba/smb-ogclient.conf" "$OLD_FILE"; then
# Section already exists, do nothing
rm -f "$NEW_FILE"
else
# Copy the original file
cp -a "$OLD_FILE" "$NEW_FILE"
# Append our configuration
echo "include = /etc/samba/smb-ogclient.conf" >> "$NEW_FILE"
# Use ucf to handle the file update
ucf --debconf-ok "$NEW_FILE" "$OLD_FILE"
# Clean up
rm -f "$NEW_FILE"
# Reload Samba
if command -v systemctl >/dev/null 2>&1; then
systemctl reload smbd.service
else
service smbd reload || true
fi
fi
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
#DEBHELPER#
exit 0

28
debian/ogclient.postrm vendored 100644
View File

@ -0,0 +1,28 @@
#!/bin/sh -e
#. /usr/share/debconf/confmodule
set -e
if [ "$1" = "remove" ] || [ "$1" = "purge" ]; then
# Create a temporary file with the configuration without our share
OLD_FILE="/etc/samba/smb.conf"
NEW_FILE=$(mktemp)
# Remove our share section from the file
grep -v "include = /etc/samba/smb-ogclient.conf" "$OLD_FILE" > "$NEW_FILE"
# Use ucf to update the file
ucf --debconf-ok "$NEW_FILE" "$OLD_FILE"
ucf --purge "$OLD_FILE"
# Clean up
rm -f "$NEW_FILE"
# Reload Samba
if command -v systemctl >/dev/null 2>&1; then
systemctl reload smbd.service
else
service smbd reload || true
fi
fi

4
debian/rules vendored
View File

@ -23,7 +23,7 @@ install: build
mkdir -p debian/ogclient/opt/opengnsys/ogclient_log debian/ogclient/etc/samba mkdir -p debian/ogclient/opt/opengnsys/ogclient_log debian/ogclient/etc/samba
cp -a client debian/ogclient/opt/opengnsys/ogclient cp -a client debian/ogclient/opt/opengnsys/ogclient
mkdir -p debian/ogclient/opt/opengnsys/ogclient/images debian/ogclient/opt/opengnsys/ogclient/cache debian/ogclient/opt/opengnsys/ogclient/log mkdir -p debian/ogclient/opt/opengnsys/ogclient/images debian/ogclient/opt/opengnsys/ogclient/cache debian/ogclient/opt/opengnsys/ogclient/log
install --owner root --group root --mode 0644 etc/samba/smb-client.conf debian/ogclient/etc/samba/ install --owner root --group root --mode 0644 etc/samba/smb-ogclient.conf debian/ogclient/etc/samba/
find debian/ogclient -name '*.swp' -exec rm -f '{}' ';' find debian/ogclient -name '*.swp' -exec rm -f '{}' ';'
binary-arch: build install binary-arch: build install
# emptyness # emptyness
@ -40,7 +40,7 @@ binary-indep: build install
dh_fixperms dh_fixperms
dh_installdeb dh_installdeb
## ignore Qt*.so.4 errors ## ignore Qt*.so.4 errors
dh_shlibdeps --exclude debian/ogclient/opt/opengnsys/ogclient/bin/browser --exclude debian/ogclient/opt/opengnsys/ogclient/bin/grub-probe1.99_i686 #dh_shlibdeps
dh_gencontrol dh_gencontrol
dh_md5sums dh_md5sums
dh_builddeb dh_builddeb