oglive-builder/mkoglive.py

187 lines
7.7 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 boottools import utils, apt, btog
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'):
utils.run (['git', 'clone', '-c', 'http.sslVerify=false', '--branch', ogrepo_branch, ogrepo_url, ogrepo_dir])
utils.run (['rsync', '-aH', f'{ogrepo_dir}/client/engine', f'{ogrepo_dir}/client/shared', '/tmp/opengnsys/'])
def _mount_rootfs():
global btrootfsimg, btrootfsmnt
try: utils.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
pxepkg = None
cache = apt.cache_search (['gpxe', 'ipxe'])
if cache['gpxe']: pxepkg = 'gpxe'
if cache['ipxe']: pxepkg = 'ipxe'
if pxepkg is None:
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 ('Stage 3.1 - create, partition and format the rootfs')
rc = subprocess.run (f'file "{btrootfsimg}" |grep -q "partition 1 *: ID=0x83"', shell=True).returncode
print (rc)
if (rc): ## 'file|grep' failed
try: btog.mkrootfs (btrootfsimg, btrootfsimglabel, btrootfsmnt, btvirtualdisksize, bttargetdir, osarch)
except Exception as e:
logger.error (str (e))
sys.exit (1)
def _schroot (btrootfsimg):
logger.info ('Stage 3.2 - configure schroot in the VM')
btog.configure_schroot (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 ('Stage 3.3 - debootstrap system')
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 btog.debootstrap()')
_mount_rootfs()
try: btog.debootstrap (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
utils.run (['sed', '-i', f'1 s/$/ {gitrelease} ({osrelease})/', f'{btdir}/includes/etc/initramfs-tools/scripts/VERSION.txt'])
def _copy_og_files (btrootfsmnt, osdistrib, oscodename):
_mount_rootfs()
builder = '/tmp/opengnsys/oglive_builder'
og_shared = '/tmp/opengnsys/shared'
og_engine = '/tmp/opengnsys/engine'
btog.copy_og_files (builder, og_shared, og_engine, btrootfsmnt, osdistrib, oscodename)
utils.umount (btrootfsmnt)
def _chroot_tasks (curdir, osrelease, osarch):
logger.debug (f'running \'schroot --chroot IMGogclient -- {curdir}/chroot-tasks.py --osrelease "{osrelease}" --osarch "{osarch}"\'')
stdout, _ = utils.run (['schroot', '--chroot', 'IMGogclient', '--', f'{curdir}/chroot-tasks.py', '--osrelease', osrelease, '--osarch', osarch])
logger.debug (f'chroot-tasks.py stdout follows:')
## esto deja initrd.img-6.8.0-31-generic y vmlinuz-6.8.0-31-generic en /tmp
for i in stdout.strip().split ('\n'): logger.debug (' ' + i)
def _ssh_stuff():
_mount_rootfs()
btog.ssh_server (btrootfsmnt)
btog.ssh_client (btrootfsmnt)
utils.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 ('Stage 6.1 - Put initrd in place')
_mount_rootfs()
btog.move_initrd (bttargetdir, osrelease)
logger.info ('Stage 6.2 - make squash filesystem')
btog.mksquashfs (bttargetdir, btrootfsmnt)
utils.umount (btrootfsmnt)
logger.info ('Stage 6.3 - make iso filesystem')
btog.mkisofs (pxepkg, isolinux_tpl, bttargetdir, nameisoclient)
config = utils.read_config ('mkoglive.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')
## this is convenient in case the previous run failed and we want to run this program again
try: utils.umount (btrootfsmnt)
except: pass
logger.info ('OpenGnsys CLIENT installation begins')
logger.info ('STAGE 1 - clone opengnsys repo')
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)
osdistrib, oscodename, osrelease, osarch, oshttp = btog.GetOsInfo1 (type_client)
btdir, bttargetdir, btrootfsimg, btrootfsmnt, btrootfsimglabel, log_file, versionboottools, btvirtualdisksize = btog.GetVar (osarch)
gitrelease, nameisoclient, namehostclient = btog.GetOsInfo2 (ogrepo_dir, versionboottools, oscodename, osrelease, osarch)
logger.info (':'.join ([osdistrib, oscodename, osrelease, osarch, oshttp]))
logger.info ('STAGE 2 - install software in the VM')
apt.update()
apt.upgrade()
pxepkg = _get_pxepkg()
apt.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 ('STAGE 3 - create and bootstrap rootfs')
_mkrootfs()
_schroot (btrootfsimg)
_debootstrap()
logger.info ('STAGE 4 - copy files to the rootfs')
_initramfs_version (gitrelease, osrelease, btdir)
_copy_og_files (btrootfsmnt, osdistrib, oscodename)
logger.info ('STAGE 5 - perform tasks within the chroot')
_chroot_tasks (curdir, osrelease, osarch)
_ssh_stuff()
logger.info ('STAGE 6 - generate distribution files')
_mkinitrd_squashfs_isofs (bttargetdir, osrelease, btrootfsmnt, pxepkg, isolinux_tpl, nameisoclient)
logger.info ('OpenGnsys installation finished')