Compare commits
40 Commits
Author | SHA1 | Date |
---|---|---|
|
7624964ba1 | |
|
c3e86b7dc0 | |
|
a18e861bea | |
|
842dbf48c2 | |
|
d79c677f16 | |
|
bd056438a1 | |
|
fb665fa4ca | |
|
c76fd8388a | |
|
fac6e142f6 | |
|
e20bd46edb | |
|
f785143b73 | |
|
bf85cb1fed | |
|
e885302256 | |
|
ad3388d36e | |
|
46238456cb | |
|
0179d106e9 | |
|
697c60f812 | |
|
4353c74768 | |
|
2c18e6981f | |
|
c1f123b489 | |
|
1f92f54994 | |
|
bbaa6578e1 | |
|
e1a1be667b | |
|
44511c79a0 | |
|
a1493a827e | |
|
0352e3a2cc | |
|
e76fe57b1b | |
|
793705953f | |
|
782e5c8978 | |
|
0e979c46fa | |
|
6cbe28272f | |
|
565e3d4091 | |
|
5e9fb86f9f | |
|
df16663594 | |
|
48f6a41838 | |
|
288aa9cf09 | |
|
9847cad6a9 | |
|
1be353aa1d | |
|
78b76bcd6c | |
|
14b0f2db47 |
102
CHANGELOG.md
102
CHANGELOG.md
|
@ -5,6 +5,108 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [0.8.0] - 2025-04-23
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Have the oglive agent send /stopped on poweroff or restart
|
||||||
|
|
||||||
|
## [0.7.2] - 2025-04-21
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Have the partitioning functions return a meaningful rc
|
||||||
|
|
||||||
|
## [0.7.1] - 2025-04-15
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- getConfiguration.py: don't fail if NTFS filesystems are mounted ro
|
||||||
|
|
||||||
|
## [0.7.0] - 2025-04-15
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Removed references to ogGlobals.OGLOG in python code
|
||||||
|
|
||||||
|
## [0.6.1] - 2025-04-15
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed capturing of partclone output and management of return value
|
||||||
|
|
||||||
|
## [0.6.0] - 2025-04-15
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- ogGetIpAddress() is no longer required in ogGlobals--move it back into NetLib
|
||||||
|
|
||||||
|
## [0.5.0] - 2025-04-15
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Log to /var/log/clone-engine.log and clone-engine.json.log
|
||||||
|
|
||||||
|
## [0.4.1] - 2025-04-10
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- restoreImage.py: return negated rc to the shell
|
||||||
|
|
||||||
|
## [0.4.0] - 2025-04-10
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Make /opt/opengnsys writable in clients, just like it used to be
|
||||||
|
|
||||||
|
## [0.3.6] - 2025-04-09
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed ogReduceFs
|
||||||
|
|
||||||
|
## [0.3.5] - 2025-04-09
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed syntax
|
||||||
|
|
||||||
|
## [0.3.4] - 2025-04-09
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed usage of ogEcho in FileSystemLib
|
||||||
|
|
||||||
|
## [0.3.3] - 2025-04-09
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Kill coproc'ed browser in all execution branches in Configurar.py
|
||||||
|
|
||||||
|
## [0.3.2] - 2025-04-07
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Handle invalid number of arguments pass to functions/ogCopyFile
|
||||||
|
|
||||||
|
## [0.3.1] - 2025-04-03
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed invocation to ogCheckIpAddress in interfaceAdm/CrearImagen.py
|
||||||
|
|
||||||
|
## [0.3.0] - 2025-04-03
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Removed burg and rsync 3.1
|
||||||
|
|
||||||
|
## [0.2.6] - 2025-03-31
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Restore qt4 browser
|
||||||
|
|
||||||
## [0.2.5] - 2025-03-31
|
## [0.2.5] - 2025-03-31
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -48,7 +48,18 @@ pipeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stage('Generate Changelog (Nightly)'){
|
||||||
|
when {
|
||||||
|
branch 'main'
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
def devName = params.DEV_NAME ? params.DEV_NAME : env.DEFAULT_DEV_NAME
|
||||||
|
def devEmail = params.DEV_EMAIL ? params.DEV_EMAIL : env.DEFAULT_DEV_EMAIL
|
||||||
|
generateDebianChangelog(env.BUILD_DIR, devName, devEmail,"nightly")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
stage('Build') {
|
stage('Build') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
|
@ -71,6 +82,19 @@ pipeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stage ('Publish to Debian Repository (Nightly)') {
|
||||||
|
when {
|
||||||
|
branch 'main'
|
||||||
|
}
|
||||||
|
agent { label 'debian-repo' }
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
// Construir el patrón de versión esperado en el nombre del paquete
|
||||||
|
def versionPattern = "-${env.BUILD_NUMBER}~nightly"
|
||||||
|
publicarEnAptly('/var/tmp/opengnsys/debian-repo/ogclient', 'nightly', versionPattern)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
post {
|
post {
|
||||||
always {
|
always {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[ogclient]
|
[ogclient]
|
||||||
comment = OpenGnsys Client
|
comment = OpenGnsys Client
|
||||||
browseable = no
|
browseable = no
|
||||||
writeable = no
|
writeable = yes
|
||||||
locking = no
|
locking = no
|
||||||
path = /opt/opengnsys/ogclient
|
path = /opt/opengnsys/ogclient
|
||||||
guest ok = no
|
guest ok = no
|
||||||
|
|
Binary file not shown.
|
@ -55,6 +55,9 @@ elif 6 == len (sys.argv):
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
src = { 'container': args.src_container, 'file': args.src_file }
|
src = { 'container': args.src_container, 'file': args.src_file }
|
||||||
dst = { 'disk': args.dst_disk, 'par': args.dst_par, 'file': args.dst_file }
|
dst = { 'disk': args.dst_disk, 'par': args.dst_par, 'file': args.dst_file }
|
||||||
|
else:
|
||||||
|
ogHelp ('ogCopyFile', 'ogCopyFile [ str_repo | int_ndisk int_npartition ] path_source [ str_repo | int_ndisk int_npartition ] path_target', ['ogCopyFile REPO newfile.txt 1 2 /tmp/newfile.txt'])
|
||||||
|
sys.exit (1)
|
||||||
|
|
||||||
ret = ogCopyFile (src, dst)
|
ret = ogCopyFile (src, dst)
|
||||||
if ret is not None:
|
if ret is not None:
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
os.system ('pkill -f OGAgent')
|
||||||
|
time.sleep (3)
|
||||||
os.system ('poweroff')
|
os.system ('poweroff')
|
||||||
sys.exit (0)
|
sys.exit (0)
|
||||||
|
|
|
@ -75,8 +75,11 @@ for item in tbprm:
|
||||||
elif 'tch' == k: tch = v
|
elif 'tch' == k: tch = v
|
||||||
|
|
||||||
# Error si no se define el parámetro de disco (dis).
|
# Error si no se define el parámetro de disco (dis).
|
||||||
if dis is None: sys.exit (ogGlobals.OG_ERR_FORMAT)
|
if dis is None:
|
||||||
if tch is None: tch = '0'
|
coproc.kill()
|
||||||
|
sys.exit (ogGlobals.OG_ERR_FORMAT)
|
||||||
|
if tch is None:
|
||||||
|
tch = '0'
|
||||||
|
|
||||||
# Toma valores de distribución de particiones, separados por "%".
|
# Toma valores de distribución de particiones, separados por "%".
|
||||||
tbp = [] # Valores de configuración (parámetros para ogCreatePartitions)
|
tbp = [] # Valores de configuración (parámetros para ogCreatePartitions)
|
||||||
|
@ -111,6 +114,7 @@ for item in tbprm:
|
||||||
if tam is None: missing_params.append ('tam')
|
if tam is None: missing_params.append ('tam')
|
||||||
if missing_params:
|
if missing_params:
|
||||||
print (f'partition data ({item}) missing required parameters ({' '.join (missing_params)})')
|
print (f'partition data ({item}) missing required parameters ({' '.join (missing_params)})')
|
||||||
|
coproc.kill()
|
||||||
sys.exit (1)
|
sys.exit (1)
|
||||||
|
|
||||||
# Componer datos de particionado.
|
# Componer datos de particionado.
|
||||||
|
@ -150,6 +154,7 @@ if 'CACHE' in sparam:
|
||||||
rc = SystemLib.ogExecAndLog ('command', CacheLib.initCache, tch)
|
rc = SystemLib.ogExecAndLog ('command', CacheLib.initCache, tch)
|
||||||
if rc:
|
if rc:
|
||||||
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_CACHE, f'initCache failed')
|
SystemLib.ogRaiseError (['log', 'session'], ogGlobals.OG_ERR_CACHE, f'initCache failed')
|
||||||
|
coproc.kill()
|
||||||
sys.exit (1)
|
sys.exit (1)
|
||||||
|
|
||||||
# Definir particionado.
|
# Definir particionado.
|
||||||
|
|
|
@ -66,7 +66,7 @@ repo = arg_repo
|
||||||
if not repo: repo = 'REPO'
|
if not repo: repo = 'REPO'
|
||||||
if repo == ogGetIpAddress(): repo = 'CACHE'
|
if repo == ogGetIpAddress(): repo = 'CACHE'
|
||||||
# Si es una ip y es distinta a la del recurso samba cambiamos de REPO.
|
# Si es una ip y es distinta a la del recurso samba cambiamos de REPO.
|
||||||
if 'REPO' == repo or StringLib.ogCheckIpAddress (repo):
|
if 'REPO' == repo or ogCheckIpAddress (repo):
|
||||||
# Si falla el cambio -> salimos con error repositorio no valido
|
# Si falla el cambio -> salimos con error repositorio no valido
|
||||||
if not ogChangeRepo (repo):
|
if not ogChangeRepo (repo):
|
||||||
ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, repo)
|
ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, repo)
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
os.system ('pkill -f OGAgent')
|
||||||
|
time.sleep (3)
|
||||||
os.system ('reboot')
|
os.system ('reboot')
|
||||||
sys.exit (0)
|
sys.exit (0)
|
||||||
|
|
|
@ -74,4 +74,5 @@ else:
|
||||||
|
|
||||||
# Borramos marcas de arranque de Windows
|
# Borramos marcas de arranque de Windows
|
||||||
for f in glob.glob ('/mnt/*/ogboot.*') + glob.glob ('/mnt/*/*/ogboot.*'):
|
for f in glob.glob ('/mnt/*/ogboot.*') + glob.glob ('/mnt/*/*/ogboot.*'):
|
||||||
os.unlink (f)
|
try: os.unlink (f)
|
||||||
|
except: pass
|
||||||
|
|
|
@ -179,7 +179,7 @@ def ogCreatePartitions (disk, parts):
|
||||||
p = subprocess.run (['sfdisk', DISK], input=sfdisk_input, capture_output=True, text=True)
|
p = subprocess.run (['sfdisk', DISK], input=sfdisk_input, capture_output=True, text=True)
|
||||||
subprocess.run (['partprobe', DISK])
|
subprocess.run (['partprobe', DISK])
|
||||||
if CACHESIZE: CacheLib.ogMountCache()
|
if CACHESIZE: CacheLib.ogMountCache()
|
||||||
return True
|
return not p.returncode
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
|
@ -285,7 +285,7 @@ def ogCreateGptPartitions (disk, parts):
|
||||||
p = subprocess.run (['sgdisk'] + DELOPTIONS + OPTIONS + [DISK], capture_output=True, text=True)
|
p = subprocess.run (['sgdisk'] + DELOPTIONS + OPTIONS + [DISK], capture_output=True, text=True)
|
||||||
subprocess.run (['partprobe', DISK])
|
subprocess.run (['partprobe', DISK])
|
||||||
if CACHESIZE: CacheLib.ogMountCache()
|
if CACHESIZE: CacheLib.ogMountCache()
|
||||||
return True
|
return not p.returncode
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
|
|
|
@ -286,11 +286,7 @@ def ogGetFsSize (disk, par, unit='KB'):
|
||||||
elif unit.upper() == "TB":
|
elif unit.upper() == "TB":
|
||||||
factor = 1024 * 1024 * 1024
|
factor = 1024 * 1024 * 1024
|
||||||
elif unit.upper() != "KB":
|
elif unit.upper() != "KB":
|
||||||
SystemLib.ogRaiseError (
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f"{unit} != {{ KB, MB, GB, TB }}")
|
||||||
[],
|
|
||||||
ogGlobals.OG_ERR_FORMAT,
|
|
||||||
f"{unit} != {{ KB, MB, GB, TB }}"
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Obtener el tamaño del sistema de archivo (si no está formateado; tamaño = 0).
|
# Obtener el tamaño del sistema de archivo (si no está formateado; tamaño = 0).
|
||||||
|
@ -331,11 +327,7 @@ def ogGetFsType(disk, part):
|
||||||
try:
|
try:
|
||||||
subprocess.run(["zfs", "mount", PART])
|
subprocess.run(["zfs", "mount", PART])
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
SystemLib.ogRaiseError (
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTEXEC, 'zfs')
|
||||||
[],
|
|
||||||
ogGlobals.OG_ERR_NOTEXEC,
|
|
||||||
'zfs'
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
out = subprocess.run(["mount"], capture_output=True, text=True).stdout.splitlines()
|
out = subprocess.run(["mount"], capture_output=True, text=True).stdout.splitlines()
|
||||||
for line in out:
|
for line in out:
|
||||||
|
@ -344,11 +336,7 @@ def ogGetFsType(disk, part):
|
||||||
break
|
break
|
||||||
|
|
||||||
if not TYPE:
|
if not TYPE:
|
||||||
SystemLib.ogRaiseError (
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{disk} {part}')
|
||||||
[],
|
|
||||||
ogGlobals.OG_ERR_NOTFOUND,
|
|
||||||
f'{disk} {part}'
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Componer valores correctos.
|
# Componer valores correctos.
|
||||||
|
@ -592,11 +580,7 @@ def ogMountFs (disk, par):
|
||||||
try:
|
try:
|
||||||
rc = subprocess.run(['mount', dev, mntdir, '-o', 'force,remove_hiberfile'], check=True).returncode
|
rc = subprocess.run(['mount', dev, mntdir, '-o', 'force,remove_hiberfile'], check=True).returncode
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
SystemLib.ogRaiseError (
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk}, {par}")
|
||||||
[],
|
|
||||||
ogGlobals.OG_ERR_PARTITION,
|
|
||||||
f"{disk}, {par}"
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if 0 == rc:
|
if 0 == rc:
|
||||||
|
@ -605,26 +589,18 @@ def ogMountFs (disk, par):
|
||||||
try:
|
try:
|
||||||
subprocess.run (['ntfsfix', '-d', par], check=True)
|
subprocess.run (['ntfsfix', '-d', par], check=True)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
SystemLib.ogRaiseError (
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk, par}")
|
||||||
[],
|
|
||||||
ogGlobals.OG_ERR_PARTITION,
|
|
||||||
f"{disk, par}"
|
|
||||||
)
|
|
||||||
#return
|
#return
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
subprocess.run (['mount', par, mntdir, '-o', 'ro'], check=True)
|
subprocess.run (['mount', par, mntdir, '-o', 'ro'], check=True)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
SystemLib.ogRaiseError (
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk, par}")
|
||||||
[],
|
|
||||||
ogGlobals.OG_ERR_PARTITION,
|
|
||||||
f"{disk, par}"
|
|
||||||
)
|
|
||||||
#return
|
#return
|
||||||
|
|
||||||
# Aviso de montaje de solo lectura.
|
# Aviso de montaje de solo lectura.
|
||||||
if ogIsReadonly(disk, par):
|
if ogIsReadonly(disk, par):
|
||||||
SystemLib.ogEcho("warning", f'ogMountFs: {ogGlobals.lang.MSG_MOUNTREADONLY}: "{disk}, {par}"')
|
SystemLib.ogEcho ([], "warning", f'ogMountFs: {ogGlobals.lang.MSG_MOUNTREADONLY}: "{disk}, {par}"')
|
||||||
else:
|
else:
|
||||||
# Montar sistema de archivos ZFS (un ZPOOL no comienza por "/").
|
# Montar sistema de archivos ZFS (un ZPOOL no comienza por "/").
|
||||||
subprocess.run(['zfs', 'mount', dev])
|
subprocess.run(['zfs', 'mount', dev])
|
||||||
|
@ -716,7 +692,8 @@ def ogReduceFs (disk, par):
|
||||||
break
|
break
|
||||||
elif type == 'NTFS':
|
elif type == 'NTFS':
|
||||||
ogUnmount (disk, par)
|
ogUnmount (disk, par)
|
||||||
nr_lines = subprocess.run (['ntfsresize', '-fi', PART], capture_output=True, text=True).stdout.splitlines()
|
ntfsresize_out = subprocess.run (['ntfsresize', '-fi', PART], capture_output=True, text=True).stdout
|
||||||
|
nr_lines = ntfsresize_out.splitlines()
|
||||||
maxsize = None
|
maxsize = None
|
||||||
size = None
|
size = None
|
||||||
for l in nr_lines:
|
for l in nr_lines:
|
||||||
|
@ -726,12 +703,10 @@ def ogReduceFs (disk, par):
|
||||||
size = l.split()[4]
|
size = l.split()[4]
|
||||||
size = int ((int (size) * 1.1 / 1024 + 1) * 1024)
|
size = int ((int (size) * 1.1 / 1024 + 1) * 1024)
|
||||||
|
|
||||||
if not maxsize and not size:
|
if not maxsize or not size:
|
||||||
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk},{par}')
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk},{par} ({ntfsresize_out})')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
import time
|
|
||||||
|
|
||||||
extrasize = 0
|
extrasize = 0
|
||||||
retval = 1
|
retval = 1
|
||||||
while retval != 0 and size+extrasize < maxsize:
|
while retval != 0 and size+extrasize < maxsize:
|
||||||
|
@ -809,18 +784,14 @@ def ogUnmountFs(disk, par):
|
||||||
if MNTDIR:
|
if MNTDIR:
|
||||||
# Error si la particion está bloqueada.
|
# Error si la particion está bloqueada.
|
||||||
if ogIsLocked (disk, par):
|
if ogIsLocked (disk, par):
|
||||||
SystemLib.ogRaiseError (
|
SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f"{ogGlobals.lang.MSG_PARTITION}, {disk} {par}")
|
||||||
[],
|
|
||||||
ogGlobals.OG_ERR_LOCKED,
|
|
||||||
f"{ogGlobals.lang.MSG_PARTITION}, {disk} {par}"
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Desmontar y borrar punto de montaje.
|
# Desmontar y borrar punto de montaje.
|
||||||
try:
|
try:
|
||||||
subprocess.run(["umount", PART], check=True)
|
subprocess.run(["umount", PART], check=True)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
SystemLib.ogEcho("warning", f'ogUnmountFs: {ogGlobals.lang.MSG_DONTUNMOUNT}: "{disk}, {par}"')
|
SystemLib.ogEcho ([], "warning", f'ogUnmountFs: {ogGlobals.lang.MSG_DONTUNMOUNT}: "{disk}, {par}"')
|
||||||
try:
|
try:
|
||||||
os.rmdir(MNTDIR)
|
os.rmdir(MNTDIR)
|
||||||
except:
|
except:
|
||||||
|
|
|
@ -512,6 +512,8 @@ def ogRestoreImage (repo, imgpath, disk, par):
|
||||||
rc = None
|
rc = None
|
||||||
try:
|
try:
|
||||||
p = subprocess.run (program, shell=True, capture_output=True, text=True)
|
p = subprocess.run (program, shell=True, capture_output=True, text=True)
|
||||||
|
print (p.stdout)
|
||||||
|
print (p.stderr)
|
||||||
rc = p.returncode
|
rc = p.returncode
|
||||||
if not rc:
|
if not rc:
|
||||||
SystemLib.ogRaiseError ([], ogGlobalsOG_ERR_IMAGE, f'{imgfile}, {disk}, {par}')
|
SystemLib.ogRaiseError ([], ogGlobalsOG_ERR_IMAGE, f'{imgfile}, {disk}, {par}')
|
||||||
|
|
|
@ -142,7 +142,29 @@ def ogGetHostname():
|
||||||
#@note Usa las variables utilizadas por el initrd "/etc/net-ethX.conf
|
#@note Usa las variables utilizadas por el initrd "/etc/net-ethX.conf
|
||||||
#*/ ##
|
#*/ ##
|
||||||
def ogGetIpAddress():
|
def ogGetIpAddress():
|
||||||
return ogGlobals.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]
|
||||||
|
|
||||||
|
|
||||||
#/**
|
#/**
|
||||||
|
|
|
@ -3,6 +3,7 @@ import datetime
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import json
|
||||||
import shutil
|
import shutil
|
||||||
import inspect
|
import inspect
|
||||||
import glob
|
import glob
|
||||||
|
@ -20,6 +21,7 @@ import StringLib
|
||||||
|
|
||||||
def _logtype2logfile (t):
|
def _logtype2logfile (t):
|
||||||
if 'log' == t.lower(): return ogGlobals.OGLOGFILE
|
if 'log' == t.lower(): return ogGlobals.OGLOGFILE
|
||||||
|
if 'jsonlog' == t.lower(): return ogGlobals.OGJSONLOGFILE
|
||||||
elif 'command' == t.lower(): return ogGlobals.OGLOGCOMMAND
|
elif 'command' == t.lower(): return ogGlobals.OGLOGCOMMAND
|
||||||
elif 'session' == t.lower(): return ogGlobals.OGLOGSESSION
|
elif 'session' == t.lower(): return ogGlobals.OGLOGSESSION
|
||||||
else: raise Exception (f'unknown log type ({t})')
|
else: raise Exception (f'unknown log type ({t})')
|
||||||
|
@ -35,23 +37,39 @@ def ogEcho (logtypes, loglevel, msg):
|
||||||
logfiles = ['/dev/stdout']
|
logfiles = ['/dev/stdout']
|
||||||
if type (logtypes) is list:
|
if type (logtypes) is list:
|
||||||
for l in logtypes:
|
for l in logtypes:
|
||||||
|
if 'log' == l:
|
||||||
|
logfiles.append (_logtype2logfile ('log'))
|
||||||
|
logfiles.append (_logtype2logfile ('jsonlog'))
|
||||||
|
else:
|
||||||
logfiles.append (_logtype2logfile (l))
|
logfiles.append (_logtype2logfile (l))
|
||||||
else: ## string
|
else: ## string
|
||||||
|
if 'log' == logtypes:
|
||||||
|
logfiles.append (_logtype2logfile ('log'))
|
||||||
|
logfiles.append (_logtype2logfile ('jsonlog'))
|
||||||
|
else:
|
||||||
logfiles.append (_logtype2logfile (logtypes))
|
logfiles.append (_logtype2logfile (logtypes))
|
||||||
|
|
||||||
if loglevel is None or 'help' == loglevel:
|
if loglevel is None or 'help' == loglevel:
|
||||||
if ogGlobals.DEBUG.lower() != "no":
|
if ogGlobals.DEBUG.lower() != "no":
|
||||||
logfiles.append (ogGlobals.OGLOGFILE)
|
logfiles.append (ogGlobals.OGLOGFILE)
|
||||||
|
logfiles.append (ogGlobals.OGJSONLOGFILE)
|
||||||
for f in logfiles:
|
for f in logfiles:
|
||||||
with open (f, 'a') as fd:
|
with open (f, 'a') as fd:
|
||||||
|
if ogGlobals.OGJSONLOGFILE == f:
|
||||||
|
fd.write (json.dumps ({'message':msg}) + '\n')
|
||||||
|
else:
|
||||||
fd.write (msg + '\n')
|
fd.write (msg + '\n')
|
||||||
return
|
return
|
||||||
|
|
||||||
if 'info' == loglevel or 'warning' == loglevel or 'error' == loglevel:
|
if 'info' == loglevel or 'warning' == loglevel or 'error' == loglevel:
|
||||||
DATETIME = datetime.datetime.now(ZoneInfo(ogGlobals.TZ)).strftime("%F %T %Z")
|
DATETIME = datetime.datetime.now (ZoneInfo (ogGlobals.TZ)).strftime ('%F %T %Z')
|
||||||
|
DATETIME_json = datetime.datetime.now (ZoneInfo (ogGlobals.TZ)).strftime ('%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
for f in logfiles:
|
for f in logfiles:
|
||||||
with open (f, 'a') as fd:
|
with open (f, 'a') as fd:
|
||||||
|
if ogGlobals.OGJSONLOGFILE == f:
|
||||||
|
fd.write (json.dumps ({'timestamp':DATETIME_json, 'severity':loglevel, 'message':msg}) + '\n')
|
||||||
|
else:
|
||||||
fd.write (f"OpenGnsys {loglevel} {DATETIME} {msg}\n")
|
fd.write (f"OpenGnsys {loglevel} {DATETIME} {msg}\n")
|
||||||
else:
|
else:
|
||||||
raise Exception (f'unknown loglevel ({loglevel})')
|
raise Exception (f'unknown loglevel ({loglevel})')
|
||||||
|
@ -75,9 +93,17 @@ def ogExecAndLog (logtypes, fun, *args, **kwargs):
|
||||||
if type (logtypes) is list:
|
if type (logtypes) is list:
|
||||||
for l in logtypes:
|
for l in logtypes:
|
||||||
logtypes = list (map (lambda x: x.lower(), logtypes))
|
logtypes = list (map (lambda x: x.lower(), logtypes))
|
||||||
|
if 'log' == l:
|
||||||
|
logfiles.append (_logtype2logfile ('log'))
|
||||||
|
logfiles.append (_logtype2logfile ('jsonlog'))
|
||||||
|
else:
|
||||||
logfiles.append (_logtype2logfile (l))
|
logfiles.append (_logtype2logfile (l))
|
||||||
else: ## string
|
else: ## string
|
||||||
logtypes = logtypes.lower()
|
logtypes = logtypes.lower()
|
||||||
|
if 'log' == logtypes:
|
||||||
|
logfiles.append (_logtype2logfile ('log'))
|
||||||
|
logfiles.append (_logtype2logfile ('jsonlog'))
|
||||||
|
else:
|
||||||
logfiles.append (_logtype2logfile (logtypes))
|
logfiles.append (_logtype2logfile (logtypes))
|
||||||
|
|
||||||
if not fun:
|
if not fun:
|
||||||
|
@ -103,7 +129,6 @@ def ogExecAndLog (logtypes, fun, *args, **kwargs):
|
||||||
# ## redirect stdout only
|
# ## redirect stdout only
|
||||||
# eval $COMMAND | tee -a $FILES
|
# eval $COMMAND | tee -a $FILES
|
||||||
|
|
||||||
import time
|
|
||||||
sout = serr = ''
|
sout = serr = ''
|
||||||
if 'command' in logtypes:
|
if 'command' in logtypes:
|
||||||
os.unlink (ogGlobals.OGLOGCOMMAND)
|
os.unlink (ogGlobals.OGLOGCOMMAND)
|
||||||
|
@ -121,6 +146,11 @@ def ogExecAndLog (logtypes, fun, *args, **kwargs):
|
||||||
if sout or serr or ('True' != rc_str and 'False' != rc_str and 'None' != rc_str):
|
if sout or serr or ('True' != rc_str and 'False' != rc_str and 'None' != rc_str):
|
||||||
for f in logfiles:
|
for f in logfiles:
|
||||||
with open (f, 'a') as fd:
|
with open (f, 'a') as fd:
|
||||||
|
if ogGlobals.OGJSONLOGFILE == f:
|
||||||
|
if sout: fd.write (json.dumps ({'message':sout}) + '\n')
|
||||||
|
if serr: fd.write (json.dumps ({'message':serr}) + '\n')
|
||||||
|
if rc_str: fd.write (json.dumps ({'message':rc_str}) + '\n')
|
||||||
|
else:
|
||||||
if sout: fd.write (f'{sout}\n')
|
if sout: fd.write (f'{sout}\n')
|
||||||
if serr: fd.write (f'{serr}\n')
|
if serr: fd.write (f'{serr}\n')
|
||||||
if rc_str: fd.write (f'{rc_str}\n')
|
if rc_str: fd.write (f'{rc_str}\n')
|
||||||
|
|
|
@ -6,33 +6,6 @@ import os.path
|
||||||
import locale
|
import locale
|
||||||
import importlib.util
|
import importlib.util
|
||||||
|
|
||||||
## required for defining OGLOGFILE
|
|
||||||
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]
|
|
||||||
ip = ogGetIpAddress()
|
|
||||||
|
|
||||||
def load_lang (name):
|
def load_lang (name):
|
||||||
global lang
|
global lang
|
||||||
if name in sys.modules:
|
if name in sys.modules:
|
||||||
|
@ -88,8 +61,8 @@ OGPYFUNCS = os.path.join (OPENGNSYS, 'functions')
|
||||||
OGSCRIPTS = os.path.join (OPENGNSYS, 'scripts')
|
OGSCRIPTS = os.path.join (OPENGNSYS, 'scripts')
|
||||||
OGIMG = os.path.join (OPENGNSYS, 'images')
|
OGIMG = os.path.join (OPENGNSYS, 'images')
|
||||||
OGCAC = os.path.join (OPENGNSYS, 'cache')
|
OGCAC = os.path.join (OPENGNSYS, 'cache')
|
||||||
OGLOG = os.path.join (OPENGNSYS, 'log')
|
OGLOGFILE = '/var/log/clone-engine.log'
|
||||||
OGLOGFILE = f'{OGLOG}/{ip}.log'
|
OGJSONLOGFILE = '/var/log/clone-engine.json.log'
|
||||||
DEBUG = 'yes'
|
DEBUG = 'yes'
|
||||||
_path = os.environ['PATH'] + ':/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin:/opt/oglive/rootfs/opt/drbl/sbin'
|
_path = os.environ['PATH'] + ':/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin:/opt/oglive/rootfs/opt/drbl/sbin'
|
||||||
os.environ['PATH'] = ':'.join ([OGSCRIPTS, _path, OGAPI, OGBIN])
|
os.environ['PATH'] = ':'.join ([OGSCRIPTS, _path, OGAPI, OGBIN])
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -145,6 +145,10 @@ def main (repo, imgname, disk, par, proto='UNICAST', protoopt=''):
|
||||||
SystemLib.ogEcho (['log', 'session'], None, f'[55] {ogGlobals.lang.MSG_HELP_ogRestoreImage}: restoreImage {params}')
|
SystemLib.ogEcho (['log', 'session'], None, f'[55] {ogGlobals.lang.MSG_HELP_ogRestoreImage}: restoreImage {params}')
|
||||||
retval = subprocess.run (['restoreImage.py'] + params).returncode
|
retval = subprocess.run (['restoreImage.py'] + params).returncode
|
||||||
|
|
||||||
|
## turn shell's success into python success (without ending up with True or False)
|
||||||
|
if retval: retval = 0
|
||||||
|
else: retval = 1
|
||||||
|
|
||||||
# Mostrar resultados.
|
# Mostrar resultados.
|
||||||
resumerestoreimage = subprocess.run (['grep', '--max-count', '1', 'Total Time:', ogGlobals.OGLOGCOMMAND], capture_output=True, text=True).stdout
|
resumerestoreimage = subprocess.run (['grep', '--max-count', '1', 'Total Time:', ogGlobals.OGLOGCOMMAND], capture_output=True, text=True).stdout
|
||||||
SystemLib.ogEcho (['log', 'session'], None, f' [ ] {resumerestoreimage} ')
|
SystemLib.ogEcho (['log', 'session'], None, f' [ ] {resumerestoreimage} ')
|
||||||
|
|
|
@ -21,7 +21,7 @@ if len (sys.argv) > 1:
|
||||||
#SERVERLOGDIR = unused
|
#SERVERLOGDIR = unused
|
||||||
|
|
||||||
# Fichero de listado: hard-IP
|
# Fichero de listado: hard-IP
|
||||||
HARDFILE = f'{ogGlobals.OGLOG}/hard-{ogGetIpAddress()}'
|
HARDFILE = f'/tmp/hard-{ogGetIpAddress()}'
|
||||||
out = ogListHardwareInfo()
|
out = ogListHardwareInfo()
|
||||||
with open (HARDFILE, 'w') as fd:
|
with open (HARDFILE, 'w') as fd:
|
||||||
fd.write (out)
|
fd.write (out)
|
||||||
|
|
|
@ -18,7 +18,7 @@ prog = os.path.basename (sys.argv[0])
|
||||||
|
|
||||||
def main (disk, par, reduced):
|
def main (disk, par, reduced):
|
||||||
ip = NetLib.ogGetIpAddress()
|
ip = NetLib.ogGetIpAddress()
|
||||||
softfile = f'{ogGlobals.OGLOG}/soft-{ip}-{disk}-{par}'
|
softfile = f'/tmp/soft-{ip}-{disk}-{par}'
|
||||||
software_list = InventoryLib.ogListSoftware (disk, par)
|
software_list = InventoryLib.ogListSoftware (disk, par)
|
||||||
|
|
||||||
if reduced:
|
if reduced:
|
||||||
|
|
|
@ -114,5 +114,5 @@ t = time.time() - t0
|
||||||
SystemLib.ogEcho (['log', 'session'], None, f'[100] Duracion de la operacion {int (t/60)}m {int (t%60)}s')
|
SystemLib.ogEcho (['log', 'session'], None, f'[100] Duracion de la operacion {int (t/60)}m {int (t%60)}s')
|
||||||
|
|
||||||
# Código de salida del comando prinicpal de restauración.
|
# Código de salida del comando prinicpal de restauración.
|
||||||
sys.exit (retval)
|
sys.exit (not retval) ## negated for the shell
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue