#!/usr/bin/python3 import os import sys import glob import subprocess import tempfile import shutil import re import functools parameters = dict( release='testing', #mirror='http://fr.archive.ubuntu.com/ubuntu/', mirror='http://httpredir.debian.org/debian', arch='armhf', packages=''' aptitude bash bash-completion bind9-host bmon busybox bzip2 curl htop iftop ifupdown iotop iperf iproute2 iptables iputils-ping less lftp locales ncdu ncurses-base ncurses-term net-tools netbase netcat nload openssh-client openssh-server psmisc python3 ranger rsync screen sed socat strace tar tcpdump telnet tmux tree tzdata ubuntu-archive-keyring vim vim-nox vim-runtime w3m wget zsh '''.split(), ) open8 = functools.partial(open, encoding='utf8') numerical_sort = lambda y: [int(x) if x.isdigit() else x for x in re.split('(\d+)', y)] def join(item0, *items): return os.path.join(item0, *[p.lstrip('/') for p in items]) def mlstrip(s): return re.sub(r'^\s*', '', s, flags=re.MULTILINE) def run(*l, **kw): print('run:', *l) return subprocess.run(*l, **kw) def reexec_root(): # run as root if os.geteuid() != 0: os.execvp("sudo", ["sudo"] + sys.argv) def system_customization(rootdir): os.unlink(rootdir + '/etc/localtime') shutil.copy('files/zoneinfo', join(rootdir, 'etc/zoneinfo')) shutil.copy(rootdir + '/usr/share/zoneinfo/Europe/Paris', rootdir + '/etc/localtime') shutil.copy('files/interfaces', join(rootdir, 'etc/network/interfaces')) shutil.copy('files/hosts', join(rootdir, 'etc/hosts')) shutil.copy('files/hostname', join(rootdir, 'etc/hostname')) os.makedirs(rootdir + '/boot/firmware', mode=0o755) shutil.copy('files/fstab', join(rootdir, 'etc/fstab')) os.symlink('/lib/systemd/system/serial-getty@.service', join(rootdir, '/etc/systemd/system/getty.target.wants/serial-getty@ttyAMA0.service')) os.makedirs(rootdir + '/etc/systemd/system/serial-getty@ttyAMA0.service.d', mode=0o755) shutil.copy('files/autologin.conf', join(rootdir, '/etc/systemd/system/serial-getty@ttyAMA0.service.d/autologin.conf')) shutil.copy('files/keyboard', join(rootdir, 'etc/default/keyboard')) shutil.copy('files/locale', join(rootdir, 'etc/default/locale')) shutil.copy('files/vimrc', join(rootdir, 'etc/vim/vimrc')) shutil.copy('files/ubuntu.pref', join(rootdir, 'etc/apt/preferences.d')) shutil.copy('files/ubuntu.sources', join(rootdir, 'etc/apt/sources.list.d')) shutil.copy('files/main.sources', join(rootdir, 'etc/apt/sources.list.d')) os.unlink(join(rootdir, 'etc/apt/sources.list')) shutil.copy('files/vg-copy-rpi', join(rootdir, 'etc/kernel/postinst.d')) os.makedirs(join(rootdir, 'etc/kernel/postrm.d'), mode=0o755) os.symlink('../postinst.d/vg-copy-rpi', join(rootdir, 'etc/kernel/postrm.d/vg-copy-rpi')) open8(rootdir + '/etc/bash.bashrc', 'a').write(mlstrip( '''\ # enable bash completion in interactive shells if ! shopt -oq posix; then if [ -f /usr/share/bash-completion/bash_completion ]; then . /usr/share/bash-completion/bash_completion elif [ -f /etc/bash_completion ]; then . /etc/bash_completion fi fi alias ls="ls --color=aut" alias l="ls -CF" alias ll="l -lh" alias la="l -a" alias e="vim" alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' export PAGER=less export EDITOR=vim export VISUAL=vim ''')) for locale in ['fr_FR', 'en_US', 'en_GB', 'en_DK', 'de_DE']: run([ 'localedef', '--prefix={}'.format(rootdir), '-f', 'UTF-8', '-i', locale, '{}.UTF-8'.format(locale) ], check=True) run(['chroot', rootdir, '/usr/bin/qemu-arm-static', '/usr/bin/apt', 'update'], check=True) run(['chroot', rootdir, '/usr/bin/qemu-arm-static', '/usr/bin/apt', 'install', '--no-install-recommends', '-yq', 'linux-image-raspi2'], check=True) def main(): reexec_root() rootdir = 'debootstrapdir' os.makedirs(rootdir, mode=0o755) print('debootstrapping...') run([ 'qemu-debootstrap', '--arch=' + parameters['arch'], '--include=' + ','.join(parameters['packages']), '--components=main,contrib', parameters['release'], rootdir, parameters['mirror'], ], check=True) print('doing system customization on debootstrapped system...') system_customization(rootdir) if __name__ == '__main__': main()