[c6cf378] | 1 | #!/usr/bin/python3 |
---|
| 2 | |
---|
| 3 | import sys |
---|
| 4 | import os |
---|
| 5 | import logging |
---|
[acc32a2] | 6 | import subprocess |
---|
| 7 | import glob |
---|
| 8 | import stat |
---|
[960b66e] | 9 | import shutil |
---|
[d4564f6] | 10 | import argparse |
---|
[c6cf378] | 11 | |
---|
[31e3607] | 12 | curdir = os.path.dirname (__file__) |
---|
| 13 | sys.path.insert (0, curdir) |
---|
[d1822ec] | 14 | from boottools import utils, apt, btog |
---|
[c6cf378] | 15 | |
---|
[53310a8] | 16 | os.chdir (curdir) |
---|
| 17 | |
---|
[d4564f6] | 18 | def _logging (lvl='INFO'): |
---|
[f04ace2] | 19 | numeric_level = getattr (logging, lvl.upper(), None) |
---|
| 20 | if numeric_level is None: |
---|
| 21 | numeric_level = getattr (logging, 'INFO') |
---|
| 22 | |
---|
[c5e9f68] | 23 | logging.basicConfig ( |
---|
| 24 | format='%(levelname)s %(asctime)s (%(funcName)s) %(message)s', |
---|
[0371870] | 25 | level=numeric_level, |
---|
[c5e9f68] | 26 | handlers = [ |
---|
| 27 | logging.FileHandler ('/tmp/boot-tools_installation.log'), |
---|
| 28 | logging.StreamHandler (sys.stdout), |
---|
| 29 | ], |
---|
| 30 | ) |
---|
[0371870] | 31 | return logging.getLogger ('boottools') |
---|
[c5e9f68] | 32 | |
---|
[45f533a] | 33 | def _mount_rootfs(): |
---|
| 34 | global btrootfsimg, btrootfsmnt |
---|
[95a24ac] | 35 | try: utils.mount (btrootfsimg, btrootfsmnt, opts=['-o', 'loop,offset=32256']) |
---|
[bd56977] | 36 | except: |
---|
| 37 | logger.error ('mount failed') |
---|
| 38 | sys.exit (1) |
---|
[45f533a] | 39 | |
---|
[c5e9f68] | 40 | def _get_pxepkg(): |
---|
| 41 | #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 |
---|
[9a6fecf] | 42 | pxepkg = None |
---|
| 43 | cache = apt.cache_search (['gpxe', 'ipxe']) |
---|
| 44 | if cache['gpxe']: pxepkg = 'gpxe' |
---|
| 45 | if cache['ipxe']: pxepkg = 'ipxe' |
---|
| 46 | if pxepkg is None: |
---|
| 47 | logger.error ('neither gpxe nor ipxe found in apt cache') |
---|
[c5e9f68] | 48 | sys.exit (1) |
---|
| 49 | logger.info (f'PXE package is "{pxepkg}"') |
---|
| 50 | return pxepkg |
---|
| 51 | |
---|
| 52 | def _mkrootfs(): |
---|
[feae768] | 53 | logger.info ('Stage 3.1 - create, partition and format the rootfs') |
---|
[c5e9f68] | 54 | rc = subprocess.run (f'file "{btrootfsimg}" |grep -q "partition 1 *: ID=0x83"', shell=True).returncode |
---|
| 55 | if (rc): ## 'file|grep' failed |
---|
[d1822ec] | 56 | try: btog.mkrootfs (btrootfsimg, btrootfsimglabel, btrootfsmnt, btvirtualdisksize, bttargetdir, osarch) |
---|
[c5e9f68] | 57 | except Exception as e: |
---|
| 58 | logger.error (str (e)) |
---|
[e6aa11e] | 59 | sys.exit (1) |
---|
| 60 | |
---|
[cc5701c] | 61 | ## para hacer schroot --cosas, el mntpt tiene que estar desmontado |
---|
| 62 | ## 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.' |
---|
[31e3607] | 63 | |
---|
[c5e9f68] | 64 | def _debootstrap(): |
---|
[f002c56] | 65 | logger.info ('Stage 3.2 - debootstrap system') |
---|
[c5e9f68] | 66 | 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)') |
---|
| 67 | logger.debug ('Running \'schroot --chroot IMGogclient -- stat /etc\'') |
---|
| 68 | cp = subprocess.run (['schroot', '--chroot', 'IMGogclient', '--', 'stat', '/etc']) |
---|
| 69 | if (cp.returncode): |
---|
[d1822ec] | 70 | logger.debug (f'schroot returned code "{cp.returncode}", calling btog.debootstrap()') |
---|
[bd56977] | 71 | _mount_rootfs() |
---|
[d1822ec] | 72 | try: btog.debootstrap (btrootfsimg, btrootfsmnt, osarch, oscodename, oshttp) |
---|
[c5e9f68] | 73 | except Exception as e: |
---|
| 74 | logger.error (str (e)) |
---|
[e6aa11e] | 75 | sys.exit (1) |
---|
| 76 | |
---|
| 77 | # Incluir revisión. |
---|
| 78 | def _initramfs_version (gitrelease, osrelease, btdir): |
---|
| 79 | ## 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) ..." |
---|
| 80 | #sed -i "1 s/$/ $GITRELEASE ($OSRELEASE)/" ${BTDIR}/includes/etc/initramfs-tools/scripts/VERSION.txt |
---|
[95a24ac] | 81 | utils.run (['sed', '-i', f'1 s/$/ {gitrelease} ({osrelease})/', f'{btdir}/includes/etc/initramfs-tools/scripts/VERSION.txt']) |
---|
[c5e9f68] | 82 | |
---|
[d1822ec] | 83 | def _copy_og_files (btrootfsmnt, osdistrib, oscodename): |
---|
[bd56977] | 84 | _mount_rootfs() |
---|
| 85 | builder = '/tmp/opengnsys/oglive_builder' |
---|
| 86 | og_shared = '/tmp/opengnsys/shared' |
---|
| 87 | og_engine = '/tmp/opengnsys/engine' |
---|
[d1822ec] | 88 | btog.copy_og_files (builder, og_shared, og_engine, btrootfsmnt, osdistrib, oscodename) |
---|
[95a24ac] | 89 | utils.umount (btrootfsmnt) |
---|
[c5e9f68] | 90 | |
---|
[feae768] | 91 | def _chroot_tasks (curdir, osrelease, osarch): |
---|
[d1822ec] | 92 | logger.debug (f'running \'schroot --chroot IMGogclient -- {curdir}/chroot-tasks.py --osrelease "{osrelease}" --osarch "{osarch}"\'') |
---|
[d4564f6] | 93 | stdout, _ = utils.run (['schroot', '--chroot', 'IMGogclient', '--', f'{curdir}/chroot-tasks.py', '--osrelease', osrelease, '--osarch', osarch, '--config', args.config or 'mkoglive.cfg']) |
---|
[c5e9f68] | 94 | ## esto deja initrd.img-6.8.0-31-generic y vmlinuz-6.8.0-31-generic en /tmp |
---|
| 95 | |
---|
[bd56977] | 96 | def _ssh_stuff(): |
---|
| 97 | _mount_rootfs() |
---|
[d1822ec] | 98 | btog.ssh_server (btrootfsmnt) |
---|
| 99 | btog.ssh_client (btrootfsmnt) |
---|
[95a24ac] | 100 | utils.umount (btrootfsmnt) |
---|
[bd56977] | 101 | ## el resultado es: |
---|
| 102 | ## - hay un nuevo par de claves en la VM /root/.ssh |
---|
| 103 | ## - hay otro nuevo par de claves en el rootfs /var/lib/tftpboot/ogclient/ogclientmount/root/.ssh |
---|
| 104 | ## - las dos claves públicas (una de cada par) están autorizadan en el rootfs /var/lib/tftpboot/ogclient/ogclientmount/root/.ssh/authorized_keys |
---|
| 105 | |
---|
[95a24ac] | 106 | def _mkinitrd_squashfs_isofs (bttargetdir, osrelease, btrootfsmnt, pxepkg, isolinux_tpl, nameisoclient): |
---|
[feae768] | 107 | logger.info ('Stage 6.1 - Put initrd in place') |
---|
[bd56977] | 108 | _mount_rootfs() |
---|
[d1822ec] | 109 | btog.move_initrd (bttargetdir, osrelease) |
---|
[e6aa11e] | 110 | |
---|
[feae768] | 111 | logger.info ('Stage 6.2 - make squash filesystem') |
---|
[d1822ec] | 112 | btog.mksquashfs (bttargetdir, btrootfsmnt) |
---|
[95a24ac] | 113 | utils.umount (btrootfsmnt) |
---|
[e6aa11e] | 114 | |
---|
[feae768] | 115 | logger.info ('Stage 6.3 - make iso filesystem') |
---|
[d1822ec] | 116 | btog.mkisofs (pxepkg, isolinux_tpl, bttargetdir, nameisoclient) |
---|
[e6aa11e] | 117 | |
---|
| 118 | |
---|
[d4564f6] | 119 | parser = argparse.ArgumentParser() |
---|
| 120 | parser.add_argument ('--loglevel', help='Log level', action='store') |
---|
| 121 | parser.add_argument ('--codename', help='OS codename', action='store') |
---|
| 122 | parser.add_argument ('--config', help='Path to configuration file', action='store') |
---|
| 123 | args = parser.parse_args() |
---|
[e6aa11e] | 124 | |
---|
[d4564f6] | 125 | config = utils.read_config (args.config or 'mkoglive.cfg') |
---|
[e6aa11e] | 126 | if config is None: |
---|
| 127 | sys.exit (1) |
---|
| 128 | isolinux_tpl = config['General'].get ('isolinux_template') |
---|
[d4564f6] | 129 | cfg_loglevel = config['General'].get ('logging_level') |
---|
[c5e9f68] | 130 | |
---|
[d4564f6] | 131 | logger = _logging (args.loglevel or cfg_loglevel) |
---|
| 132 | type_client = args.codename or 'host' |
---|
[f04ace2] | 133 | |
---|
| 134 | if os.getuid(): |
---|
| 135 | logger.error ('ERROR: this program must run under root privileges!!') |
---|
| 136 | sys.exit (1) |
---|
| 137 | |
---|
[feae768] | 138 | ## this is convenient in case the previous run failed and we want to run this program again |
---|
| 139 | try: utils.umount (btrootfsmnt) |
---|
| 140 | except: pass |
---|
| 141 | |
---|
[f04ace2] | 142 | logger.info ('OpenGnsys CLIENT installation begins') |
---|
[feae768] | 143 | |
---|
| 144 | logger.info ('STAGE 1 - clone opengnsys repo') |
---|
[866cdb4] | 145 | |
---|
| 146 | fd = open (f'{curdir}/gitrelease', 'r') ## per the Dockerfile |
---|
| 147 | gitrelease = fd.readline().strip() |
---|
| 148 | fd.close() |
---|
[c5e9f68] | 149 | |
---|
[feae768] | 150 | osdistrib, oscodename, osrelease, osarch, oshttp = btog.GetOsInfo1 (type_client) |
---|
[bb2d57b] | 151 | if osdistrib is None: |
---|
| 152 | logger.error ('GetOsInfo1() failed') |
---|
| 153 | sys.exit (1) |
---|
[feae768] | 154 | btdir, bttargetdir, btrootfsimg, btrootfsmnt, btrootfsimglabel, log_file, versionboottools, btvirtualdisksize = btog.GetVar (osarch) |
---|
[866cdb4] | 155 | nameisoclient, namehostclient = btog.GetOsInfo2 (versionboottools, oscodename, osrelease, osarch, gitrelease) |
---|
[bd56977] | 156 | logger.info (':'.join ([osdistrib, oscodename, osrelease, osarch, oshttp])) |
---|
| 157 | |
---|
[feae768] | 158 | logger.info ('STAGE 2 - install software in the VM') |
---|
[f04ace2] | 159 | pxepkg = _get_pxepkg() |
---|
| 160 | |
---|
[feae768] | 161 | logger.info ('STAGE 3 - create and bootstrap rootfs') |
---|
[f04ace2] | 162 | _mkrootfs() |
---|
| 163 | _debootstrap() |
---|
| 164 | |
---|
[feae768] | 165 | logger.info ('STAGE 4 - copy files to the rootfs') |
---|
[e6aa11e] | 166 | _initramfs_version (gitrelease, osrelease, btdir) |
---|
[d1822ec] | 167 | _copy_og_files (btrootfsmnt, osdistrib, oscodename) |
---|
[f04ace2] | 168 | |
---|
[feae768] | 169 | logger.info ('STAGE 5 - perform tasks within the chroot') |
---|
| 170 | _chroot_tasks (curdir, osrelease, osarch) |
---|
[f04ace2] | 171 | |
---|
| 172 | _ssh_stuff() |
---|
[c6cf378] | 173 | |
---|
[feae768] | 174 | logger.info ('STAGE 6 - generate distribution files') |
---|
[95a24ac] | 175 | _mkinitrd_squashfs_isofs (bttargetdir, osrelease, btrootfsmnt, pxepkg, isolinux_tpl, nameisoclient) |
---|
[960b66e] | 176 | |
---|
| 177 | logger.info ('OpenGnsys installation finished') |
---|