211 lines
9.6 KiB
Python
211 lines
9.6 KiB
Python
#!/usr/bin/python3
|
|
|
|
import sys
|
|
import os
|
|
import logging
|
|
import subprocess
|
|
import glob
|
|
import stat
|
|
import shutil
|
|
|
|
curdir = os.path.dirname (__file__)
|
|
sys.path.insert (0, curdir)
|
|
from boottoolsfunctions import _run, _mount, _umount, _read_config, btogGetOsInfo1, btogGetOsInfo2, btogGetVar, btogSetFsVirtual, btogSetFsAccess, btogSetFsBase, boottoolsFsOpengnsys, boottoolsSshServer, boottoolsSshClient, btogFsInitrd, btogFsSqfs, btogIsoGenerator
|
|
|
|
def _logging():
|
|
#logging.root.handlers = []
|
|
|
|
numeric_level = getattr (logging, lvl.upper(), None)
|
|
if numeric_level is None:
|
|
numeric_level = getattr (logging, 'INFO')
|
|
|
|
logging.basicConfig (
|
|
format='%(levelname)s %(asctime)s (%(funcName)s) %(message)s',
|
|
level=numeric_level,
|
|
handlers = [
|
|
logging.FileHandler ('/tmp/boot-tools_installation.log'),
|
|
logging.StreamHandler (sys.stdout),
|
|
],
|
|
)
|
|
return logging.getLogger ('boottools')
|
|
|
|
def clone_client_dirs (ogrepo_url, ogrepo_branch, ogrepo_dir):
|
|
if not os.path.exists ('/tmp/opengnsys/engine'):
|
|
_run (['git', 'clone', '-c', 'http.sslVerify=false', '--branch', ogrepo_branch, ogrepo_url, ogrepo_dir])
|
|
_run (['rsync', '-aH', f'{ogrepo_dir}/client/engine', f'{ogrepo_dir}/client/shared', '/tmp/opengnsys/'])
|
|
|
|
def _mount_rootfs():
|
|
global btrootfsimg, btrootfsmnt
|
|
try: _mount (btrootfsimg, btrootfsmnt, opts=['-o', 'loop,offset=32256'])
|
|
except:
|
|
logger.error ('mount failed')
|
|
sys.exit (1)
|
|
|
|
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'])
|
|
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
|
|
|
|
def _mkrootfs():
|
|
logger.info ('Fase 3.1 Generar y formatear el disco virtual. Generar el dispositivo loop.')
|
|
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 (1)
|
|
|
|
def _schroot (btrootfsimg):
|
|
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.info ('Fase 3.3 Generar sistema de archivos con 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()')
|
|
_mount_rootfs()
|
|
try: btogSetFsBase (btrootfsimg, btrootfsmnt, osarch, oscodename, oshttp)
|
|
except Exception as e:
|
|
logger.error (str (e))
|
|
sys.exit (1)
|
|
|
|
# Incluir revisión.
|
|
def _initramfs_version (gitrelease, osrelease, btdir):
|
|
## 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'])
|
|
|
|
def _copy_files (btrootfsmnt, osdistrib, oscodename):
|
|
_mount_rootfs()
|
|
builder = '/tmp/opengnsys/oglive_builder'
|
|
og_shared = '/tmp/opengnsys/shared'
|
|
og_engine = '/tmp/opengnsys/engine'
|
|
boottoolsFsOpengnsys (builder, og_shared, og_engine, btrootfsmnt, osdistrib, oscodename)
|
|
_umount (btrootfsmnt)
|
|
|
|
def _install_compile_software (curdir, osrelease, osarch):
|
|
logger.info ('Fase 5.1 instalar paquetes deb con apt-get')
|
|
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:')
|
|
for i in stdout.strip().split('\n'): logger.debug (' ' + i)
|
|
|
|
logger.info ('Fase 5.2 compilar software.')
|
|
logger.debug (f'running \'schroot --chroot IMGogclient -- {curdir}/04-boottoolsSoftwareCompile.py\'')
|
|
stdout, _ = _run (['schroot', '--chroot', 'IMGogclient', '--', f'{curdir}/04-boottoolsSoftwareCompile.py'])
|
|
logger.debug (f'04-boottoolsSoftwareCompile stdout follows:')
|
|
for i in stdout.strip().split('\n'): logger.debug (' ' + i)
|
|
|
|
def _debconf2 (curdir):
|
|
logger.info ('Fase 6.1 Configurar las locales')
|
|
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:')
|
|
for i in stdout.strip().split('\n'): logger.debug (' ' + i)
|
|
|
|
logger.info ('Fase 6.3 Crear initrd')
|
|
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:')
|
|
for i in stdout.strip().split('\n'): logger.debug (' ' + i)
|
|
## esto deja initrd.img-6.8.0-31-generic y vmlinuz-6.8.0-31-generic en /tmp
|
|
|
|
def _ssh_stuff():
|
|
logger.info ('Fase 6.2 Configurar ssh')
|
|
_mount_rootfs()
|
|
boottoolsSshServer (btrootfsmnt)
|
|
boottoolsSshClient (btrootfsmnt)
|
|
_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
|
|
|
|
def _mkinitrd_squashfs_isofs (bttargetdir, osrelease, btrootfsmnt, pxepkg, isolinux_tpl nameisoclient):
|
|
logger.info ('Fase 7.1 Copiar el initrd a su sitio')
|
|
_mount_rootfs()
|
|
btogFsInitrd (bttargetdir, osrelease)
|
|
|
|
logger.info ('Fase 7.2 Generar fichero sqfs a partir del fichero img')
|
|
btogFsSqfs (bttargetdir, btrootfsmnt)
|
|
_umount (btrootfsmnt)
|
|
|
|
logger.info ('Fase 7.3 Generar la ISO')
|
|
btogIsoGenerator (pxepkg, isolinux_tpl, bttargetdir, nameisoclient)
|
|
|
|
|
|
|
|
config = _read_config ('boottoolsgenerator.cfg')
|
|
if config is None:
|
|
sys.exit (1)
|
|
isolinux_tpl = config['General'].get ('isolinux_template')
|
|
lvl = config['General'].get ('logging_level')
|
|
|
|
logger = _logging()
|
|
type_client = sys.argv[1] if len(sys.argv)>1 else 'host'
|
|
|
|
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')
|
|
ogrepo_url = 'https://ognproject.evlt.uma.es/gitea/opengnsys/opengnsys.git'
|
|
ogrepo_branch = 'main'
|
|
ogrepo_dir = '/tmp/ogrepo'
|
|
clone_client_dirs (ogrepo_url, ogrepo_branch, ogrepo_dir)
|
|
|
|
logger.info ('FASE 1 - Asignación de variables')
|
|
osdistrib, oscodename, osrelease, osarch, oshttp = btogGetOsInfo1(type_client)
|
|
btdir, bttargetdir, btrootfsimg, btrootfsmnt, btrootfsimglabel, log_file, versionboottools, btvirtualdisksize = btogGetVar(osarch)
|
|
gitrelease, nameisoclient, namehostclient = btogGetOsInfo2(ogrepo_dir, versionboottools, oscodename, osrelease, osarch)
|
|
|
|
logger.info (':'.join ([osdistrib, oscodename, osrelease, osarch, oshttp]))
|
|
|
|
## this is convenient in case the previous run failed and we want to run this program again
|
|
try: _umount (btrootfsmnt)
|
|
except: pass
|
|
|
|
logger.info ('FASE 2 - Instalación de software adicional.')
|
|
pxepkg = _get_pxepkg()
|
|
_run (['apt-get', '-y', 'install', 'jq', 'syslinux', 'syslinux-efi', 'syslinux-utils', 'debootstrap', 'subversion', 'schroot', 'squashfs-tools', 'syslinux', 'genisoimage', 'qemu-utils', 'lsof', pxepkg]) ## TODO qemu no existe, hace falta?
|
|
|
|
logger.info ('FASE 3 - Creación del Sistema raiz RootFS (Segundo Sistema archivos (img))')
|
|
_mkrootfs()
|
|
_schroot (btrootfsimg)
|
|
_debootstrap()
|
|
|
|
logger.info ('FASE 4 - Incorporando ficheros OpenGnsys al sistema raíz rootfs')
|
|
_initramfs_version (gitrelease, osrelease, btdir)
|
|
_copy_files (btrootfsmnt, osdistrib, oscodename, osrelease, osarch, oshttp)
|
|
|
|
logger.info ('FASE 5 - Instalar software')
|
|
_install_compile_software (curdir, osrelease, osarch)
|
|
|
|
logger.info ('FASE 6 - Personalizar el sistema creado')
|
|
_debconf2 (curdir)
|
|
_ssh_stuff()
|
|
|
|
logger.info ('FASE 7 - Generar distribucion')
|
|
_mkinitrd_squashfs_isofs (bttargetdir, osrelease, btrootfsmnt, pxepkg, isolinux_tpl nameisoclient)
|
|
|
|
logger.info ('OpenGnsys installation finished')
|