#!/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, 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 _mount (btrootfsimg, btrootfsmnt, opts=['-o', 'loop,offset=32256']) 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()') try: _mount_rootfs() except: logger.error ('mount failed') sys.exit (1) 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 _cerodos(): try: _mount_rootfs() except: logger.error ('mount failed') sys.exit (1) 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:') for i in stdout.strip().split('\n'): logger.debug (' ' + i) _umount (btrootfsmnt) def _chroot_cerotres(): 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) def _chroot_cerocuatro(): logger.info ('Fase 5.2 compilar software.') 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:') for i in stdout.strip().split('\n'): logger.debug (' ' + i) def _ssh_stuff(): logger.info ('Fase 6.1 Configurar ssh') try: _mount_rootfs() except: logger.error ('mount failed') sys.exit (1) #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) _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 _chroot_cerocinco(): logger.info ('Fase 6.2 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) def _chroot_ceroseis(): logger.info ('Fase 6.3 Crear initrd') ## what?? #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:') 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 _mkinitrd (bttargetdir, osrelease): logger.info ('Fase 7.1 Generar el initrd') ## what?? btogFsInitrd (bttargetdir, osrelease) def _mksquashfs (bttargetdir, btrootfsmnt): logger.info ('Fase 7.2 Generar fichero sqfs a partir del fichero img') btogFsSqfs (bttargetdir, btrootfsmnt) def _mkisofs (pxepkg, isolinux_tpl, bttargetdir, nameisoclient): 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) ## 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) _cerodos() logger.info ('FASE 5 - Instalar software') _chroot_cerotres() _chroot_cerocuatro() logger.info ('FASE 6 - Personalizar el sistema creado') _ssh_stuff() _chroot_cerocinco() _chroot_ceroseis() logger.info ('FASE 7 - Generar distribucion') _mkinitrd (bttargetdir, osrelease) try: _mount_rootfs() except: logger.error ('mount failed') sys.exit (1) _mksquashfs (bttargetdir, btrootfsmnt) _umount (btrootfsmnt) _mkisofs (pxepkg, isolinux_tpl, bttargetdir, nameisoclient) logger.info ('OpenGnsys installation finished')