oglive-builder/boottoolsgenerator.py

264 lines
11 KiB
Python

#!/usr/bin/python3
import sys
import os
import logging
import subprocess
import glob
import stat
import configparser
import shutil
curdir = os.path.dirname (__file__)
sys.path.insert (0, curdir)
from boottoolsfunctions import _run, _is_mounted, btogGetOsInfo1, btogGetOsInfo2, btogGetVar, btogSetFsVirtual, btogSetFsAccess, btogSetFsBase, boottoolsSshServer, boottoolsSshClient, btogFsInitrd, btogFsSqfs, btogIsoGenerator
def _logging():
#logging.root.handlers = []
logging.basicConfig (
format='%(levelname)s %(asctime)s (%(funcName)s) %(message)s',
level=logging.INFO,
handlers = [
logging.FileHandler ('/tmp/boot-tools_installation.log'),
logging.StreamHandler (sys.stdout),
],
)
return = logging.getLogger ('boottools')
logger = _logging()
config = configparser.ConfigParser (comment_prefixes='#', inline_comment_prefixes='#')
if not os.path.exists ('boottoolsgenerator.cfg'):
print ('configuration file "boottoolsgenerator.cfg" not found')
sys.exit (1)
config.read ('boottoolsgenerator.cfg')
isolinux_tpl = config['ISOLinux'].get ('template')
def clone_client_dirs():
if not os.path.exists ('/tmp/opengnsys_installer/opengnsys/client/engine'):
branch = 'main'
tmpdir, _ = _run (['mktemp', '--tmpdir', '--directory', 'oggit.XXXXXX'])
logger.debug (f'tmpdir "{tmpdir}"')
_run (['git', 'clone', '-c', 'http.sslVerify=false', '--branch', branch, 'https://ognproject.evlt.uma.es/gitea/opengnsys/opengnsys.git', tmpdir])
_run (['rsync', '-aH', f'{tmpdir}/client/engine', f'{tmpdir}/client/shared', '/tmp/opengnsys_installer/opengnsys/client/'])
_run (['rm', '-rf', tmpdir])
type_client = sys.argv[1] if len(sys.argv)>1 else 'host'
#WORKDIR = '/tmp/opengnsys_installer'
#INSTALL_TARGET = '/opt/opengnsys'
#PROGRAMDIR = $(readlink -e $(dirname "$0"))
if os.getuid():
logger.error ('ERROR: this program must run under root privileges!!')
sys.exit (1)
#os.chdir ('/tmp')
logger.info ('OpenGnsys CLIENT installation begins')
clone_client_dirs()
####################################################################3
logger.info ('FASE 1 - Asignación de variables')
ogclientcfg, osdistrib, oscodename, osrelease, osarch, oshttp = btogGetOsInfo1(type_client)
btdir, bttargetdir, btrootfsimg, btrootfsmnt, btrootfsimglabel, log_file, versionboottools, btvirtualdisksize = btogGetVar(osarch)
gitrelease, nameisoclient, namehostclient = btogGetOsInfo2(type_client, versionboottools, ogclientcfg, osdistrib, oscodename, osrelease, osarch, oshttp)
## this is convenient in case the previous run failed and we want to run this program again
if _is_mounted (btrootfsmnt):
_run (['umount', btrootfsmnt])
##########################################################################
logger.info ('FASE 2 - Instalación de software adicional.')
def _get_pxepkg():
#grep "http://free.nchc.org.tw/drbl-core" /etc/apt/sources.list || echo "deb http://free.nchc.org.tw/drbl-core drbl stable" >> /etc/apt/sources.list
_run (['apt-get', 'update']) #>>/tmp/fase2.out
acse_gpxe, _ = _run (['apt-cache', 'search', 'gpxe'])
acse_ipxe, _ = _run (['apt-cache', 'search', 'ipxe'])
if acse_ipxe:
pxepkg = 'ipxe'
elif acse_gpxe:
pxepkg = 'gpxe'
else:
logger.error ('neither gpxe nor ipxe found in apt-cache')
sys.exit (1)
logger.info (f'PXE package is "{pxepkg}"')
return pxepkg
pxepkg = _get_pxepkg()
## TODO qemu no existe, hace falta?
_run (['apt-get', '-y', 'install', 'jq', 'syslinux', 'syslinux-efi', 'syslinux-utils', 'debootstrap', 'subversion', 'schroot', 'squashfs-tools', 'syslinux', 'genisoimage', 'qemu-utils', 'lsof', pxepkg]) #>>/tmp/fase2.out
def _mkrootfs():
rc = subprocess.run (f'file "{btrootfsimg}" |grep -q "partition 1 *: ID=0x83"', shell=True).returncode
print (rc)
if (rc): ## 'file|grep' failed
try: btogSetFsVirtual (btrootfsimg, btrootfsimglabel, btrootfsmnt, btvirtualdisksize, bttargetdir, osarch)
except Exception as e:
logger.error (str (e))
sys.exit (2)
logger.info ('FASE 3 - Creación del Sistema raiz RootFS (Segundo Sistema archivos (img))')
logger.info ('Fase 3.1 Generar y formatear el disco virtual. Generar el dispositivo loop.')
_mkrootfs()
logger.info ('Fase 3.2 - Configurar acceso schroot al Segundo Sistema de archivos (img)')
btogSetFsAccess (btrootfsimg)
## para hacer schroot --cosas, el mntpt tiene que estar desmontado
## si está montado da un pete tal que 'E: 10mount: mount: /run/schroot/mount/IMGogclient-7fbf51a2-e37e-48e5-8e5d-83f8901fc7ed: wrong fs type, bad option, bad superblock on /dev/loop1, missing codepage or helper program, or other error.'
def _debootstrap():
logger.debug ('Try creation of a file within chroot (this operation may fail with "... etc/resolv.conf: No such file or directory"--that is ok)')
logger.debug ('Running \'schroot --chroot IMGogclient -- stat /etc\'')
cp = subprocess.run (['schroot', '--chroot', 'IMGogclient', '--', 'stat', '/etc'])
if (cp.returncode):
logger.debug (f'schroot returned code "{cp.returncode}", calling btogSetFsBase()')
try: _run (['mount', btrootfsimg, btrootfsmnt, '-o', 'loop,offset=32256'])
except:
logger.error ('mount failed')
sys.exit (3)
try: btogSetFsBase (btrootfsimg, btrootfsmnt, osarch, oscodename, oshttp) #>>/tmp/fase3.out
except Exception as e:
logger.error (str (e))
sys.exit (3)
logger.info ('Fase 3.3 Generar sistema de archivos con debootstrap')
_debootstrap()
logger.info ('FASE 4 - Incorporando ficheros OpenGnsys al sistema raíz rootfs')
## por qué esta copia???
#cp -a ${BTDIR}/includes/usr/bin/* /tmp >>/tmp/fase5.out
#_run (['cp', '-a'] + glob.glob (f'{btdir}/includes/usr/bin/*') + ['/tmp'])
#chmod +x /tmp/boot-tools/*.sh
#for i in glob.glob ('/tmp/boot-tools/*.sh'):
# st = os.stat (i)
# os.chmod (i, st.st_mode|stat.S_IXUSR|stat.S_IXGRP|stat.S_IXOTH)
# Incluir revisión.
## FIXME esto la incluye incondicionalmente, y luego terminamos con "OpenGnsys Client 1.2.0-rc1 gitrelease (osrelease) gitrelease (osrelease) gitrelease (osrelease) gitrelease (osrelease) gitrelease (osrelease) gitrelease (osrelease) ..."
#sed -i "1 s/$/ $GITRELEASE ($OSRELEASE)/" ${BTDIR}/includes/etc/initramfs-tools/scripts/VERSION.txt
_run (['sed', '-i', f'1 s/$/ {gitrelease} ({osrelease})/', f'{btdir}/includes/etc/initramfs-tools/scripts/VERSION.txt'])
# En Ubuntu 13.04+ es necesario matar proceso de "udev" antes de desmontar.
#umount $BTROOTFSMNT 2>/dev/null || (kill -9 $(lsof -t $BTROOTFSMNT); umount $BTROOTFSMNT) 2>/dev/null
def _cerodos():
if (not _is_mounted (btrootfsmnt)):
try: _run (['mount', btrootfsimg, btrootfsmnt, '-o', 'loop,offset=32256'])
except:
logger.error ('mount failed')
sys.exit (3)
logger.debug (f'running \'{curdir}/02-boottoolsFsOpengnsys.py --mntpt "{btrootfsmnt}" --osdistrib "{osdistrib}" --oscodename "{oscodename}" --osrelease "{osrelease}" --osarch "{osarch}" --oshttp "{oshttp))}"\'')
stdout, _ = _run ([f'{curdir}/02-boottoolsFsOpengnsys.py', '--mntpt', btrootfsmnt, '--osdistrib', osdistrib, '--oscodename', oscodename, '--osrelease', osrelease, '--osarch', osarch, '--oshttp', oshttp])
logger.debug (f'02-boottoolsFsOpengnsys stdout follows: {stdout}')
_run (['umount', btrootfsmnt])
_cerodos()
## aqui empiezan las cosas de chroot
def _cerotres():
logger.debug (f'running \'schroot --chroot IMGogclient -- {curdir}/03-boottoolsSoftwareInstall.py --osrelease "{osrelease}" --osarch "{osarch))}"\'')
stdout, _ = _run (['schroot', '--chroot', 'IMGogclient', '--', f'{curdir}/03-boottoolsSoftwareInstall.py', '--osrelease', osrelease, '--osarch', osarch])
logger.debug (f'03-boottoolsSoftwareInstall stdout follows: {stdout}')
logger.info ('FASE 5 - Instalar software')
logger.info ('Fase 5.1 instalar paquetes deb con apt-get')
_cerotres()
def _cerocuatro():
logger.debug ('running \'schroot --chroot IMGogclient -- {}/04-boottoolsSoftwareCompile.py\'')
#cd /
stdout, _ = _run (['schroot', '--chroot', 'IMGogclient', '--', f'{curdir}/04-boottoolsSoftwareCompile.py'])
#cd -
logger.debug (f'04-boottoolsSoftwareCompile stdout follows: {stdout}')
logger.info ('Fase 5.2 compilar software.')
_cerocuatro():
## ya no chroot
def _ssh_stuff():
try: _run (['mount', btrootfsimg, btrootfsmnt, '-o', 'loop,offset=32256'])
except:
logger.error ('mount failed')
sys.exit (3)
#cd /
#schroot --chroot IMGogclient -- /usr/bin/boot-tools/boottoolsSshServer.sh ## no necesita chroot
boottoolsSshServer (btrootfsmnt)
#cd -
#schroot --chroot IMGogclient -- /usr/bin/boot-tools/boottoolsSshClient.sh ## no necesita chroot
boottoolsSshClient (btrootfsmnt)
if _is_mounted (btrootfsmnt):
_run (['umount', btrootfsmnt])
## el resultado es:
## - hay un nuevo par de claves en la VM /root/.ssh
## - hay otro nuevo par de claves en el rootfs /var/lib/tftpboot/ogclient/ogclientmount/root/.ssh
## - las dos claves públicas (una de cada par) están autorizadan en el rootfs /var/lib/tftpboot/ogclient/ogclientmount/root/.ssh/authorized_keys
logger.info ('FASE 6 - Personalizar el sistema creado')
logger.info ('Fase 6.1 Incorporar la clave publica del servidor')
logger.info ('Fase 6.2 Incorporar la clave publica del propio cliente')
_ssh_stuff()
## chroot de nuevo
def _cerocinco():
logger.debug (f'running \'schroot --chroot IMGogclient -- {curdir}/05-boottoolsFsLocales.py\'')
stdout, _ = _run (['schroot', '--chroot', 'IMGogclient', '--', f'{curdir}/05-boottoolsFsLocales.py'])
logger.debug (f'05-boottoolsFsLocales stdout follows: {stdout}')
logger.info ('Fase 6.3 Configurando las locales')
_cerocinco()
def _ceroseis():
#cd /
#schroot -c IMGogclient -- /usr/bin/boot-tools/boottoolsInitrdGenerate.sh
logger.debug (f'running \'schroot --chroot IMGogclient -- {curdir}/06-boottoolsInitrdGenerate.py --osrelease "{osrelease))}"\'')
stdout, _ = _run (['schroot', '--chroot', 'IMGogclient', '--', f'{curdir}/06-boottoolsInitrdGenerate.py', '--osrelease', osrelease])
logger.debug (f'06-boottoolsInitrdGenerate stdout follows: {stdout}')
## esto deja initrd.img-6.8.0-31-generic y vmlinuz-6.8.0-31-generic en /tmp
_ceroseis()
## ya no chroot
logger.info ('FASE 7 - Generar distribucion')
logger.info ('Fase 7.1 Generar el initrd')
btogFsInitrd (bttargetdir, osrelease)
logger.info ('Fase 7.2 Generar fichero sqfs a partir del fichero img')
try: _run (['mount', btrootfsimg, btrootfsmnt, '-o', 'loop,offset=32256'])
except:
logger.error ('mount failed')
sys.exit (3)
btogFsSqfs (bttargetdir, btrootfsmnt)
_run (['umount', btrootfsmnt])
logger.info ('Fase 7.3 Generar la ISO')
btogIsoGenerator (pxepkg, isolinux_tpl, bttargetdir, nameisoclient)
logger.info ('OpenGnsys installation finished')