#!/bin/bash set -e exec 3>&1 exec >/tmp/debootstrap.log echo "I: log=/tmp/debootstrap.log">&2 #set -x if [ "$(id -ru)" != "0" ]; then echo "Run this script as root">&2 exit 1 fi # you can abuse official mirror for debootstrap since we are going to cache # packages anyway. RELEASE=raring MIRROR=http://fr.archive.ubuntu.com/ubuntu/ ARCH=amd64 #DESTDIR=/tmp/debootstrap-mountpoint PKGS="$(sed 's/^#.*$//'<<EOF vim-nox htop screen tmux less bzip2 bash-completion locate acpid # acpi-support-base: should not be needed in ubuntu bind9-host locales busybox runit iperf ncdu ranger tree psmisc w3m lftp curl wget ncurses-base ncurses-term linux-image-virtual # or linux-image, linux-virtual, or linux-image-virtual, wich depend on latest # pkgs # maybe not a systematic case #openssh-server extlinux EOF )" while [ -n "$1" ]; do case "$1" in -d) shift; DESTDIR="$1";; *) echo "Unknown option $arg">&2; exit 1;; esac shift done #[ -z "$BLOCKDEV" ] && { echo "Specify block device (-d)">&2; exit 1; } [ -z "$DESTDIR" ] && { echo "Specify destdir (-d)">&2; exit 1; } ARCHIVE=$PWD/$RELEASE-$ARCH-debootstrap.tgz KERNEL=$PWD/$RELEASE-$ARCH-vmlinuz #BLOCKDEV="$(df -P "$DESTDIR" | tail -n 1 | cut -d' ' -f1)" #( #echo "I: blockdevice associated to destination is $BLOCKDEV" #echo "I: blockdevice will not be manipulated directly," #echo "I: it is only used for informational purposes (such as UUID)" #)>&2 echo "I: script will begin in 10seconds...">&2 printf "I: ">&2 for i in $(seq 10 -1 0); do sleep 1; printf "%d... " $i>&2; done echo>&2 #echo "Warning: will erase $BLOCKDEV with mkfs.ext4 in 10seconds...">&2 #for i in $(seq 10 -1 0); do sleep 1; printf "%d... " $i>&2; done #echo>&2 #mkfs -q -F -t ext4 -L rootfs "$BLOCKDEV" || exit 1 #mkdir -p "$DESTDIR" #echo "mounting block device...">&2 #mount -v -t ext4 "$BLOCKDEV" "$DESTDIR" || \ # mount -v -t ext4 -o loop "$BLOCKDEV" "$DESTDIR" || exit 1 #echo "In case of error, please remember to umount $DESTDIR">&2 if [ ! -e "$ARCHIVE" ]; then echo "I: debootstrap archive does not exists, making it">&2 debootstrap --foreign --arch="$ARCH" \ --include="$PKGS" --components=main,universe \ --make-tarball "$ARCHIVE" \ "$RELEASE" "$DESTDIR" "$MIRROR" || exit 1 fi echo "I: debootstraping...">&2 debootstrap --foreign --arch="$ARCH" \ --include="$PKGS" --components=main,universe \ --unpack-tarball "$ARCHIVE" \ "$RELEASE" "$DESTDIR" "$MIRROR" if [ ! -e "$KERNEL" ];then echo "I: wget kernel...">&2 wget -q "$MIRROR/dists/$RELEASE/main/installer-$ARCH/current/images/netboot/ubuntu-installer/$ARCH/linux" -O "$KERNEL" fi echo "I: adjust configuration...">&2 rm -f "$DESTDIR/etc/localtime" cat "$DESTDIR/usr/share/zoneinfo/Europe/Paris" > "$DESTDIR/etc/localtime" # network cat >"$DESTDIR/etc/network/interfaces"<<EOF auto lo iface lo inet loopback auto eth0 iface eth0 inet static address 10.1.1.252 netmask 255.255.255.0 gateway 10.1.1.254 EOF echo "127.0.0.1 localhost localhost.localdomain">"$DESTDIR/etc/hosts" echo "localhost">"$DESTDIR/etc/hostname" echo "servername 10.1.1.254">"$DESTDIR/etc/resolv.conf" for f in "$DESTDIR"/etc/init/tty[1-6].conf; do echo "manual">${f%.conf}.override done chmod +w /etc/sudoers sed 's,#* *%sudo.*,%sudo ALL=(ALL) NOPASSWD: ALL,' -i /etc/sudoers chmod -w /etc/sudoers #UUID="$(blkid "$BLOCKDEV" | sed 's/^.*UUID="\([a-zA-Z0-9-]\+\)".*$/\1/')" cat >"$DESTDIR/etc/fstab"<<EOF # <device> <mount point> <type> <options> <dump> <pass> /dev/vda / ext4 errors=remount-ro,noatime 0 1 tmpfs /tmp tmpfs mode=1777,noatime,size=128m,nodev,nosuid,noexec 0 0 tmpfs /var/log tmpfs mode=1777,noatime,size=4m,nodev,nosuid,noexec 0 0 tmpfs /var/tmp tmpfs mode=1777,noatime,size=128m,nodev,nosuid,noexec 0 0 #UUID=$UUID / ext4 errors=remount-ro,noatime 0 1 #UUID=use blkid for uuid discovery /home ext4 noatime 0 2 #UUID=6d9ac889-3c25-4e05-90f3-d183f8b14aca none swap sw,auto 0 0 EOF mkdir -p "$DESTDIR/etc/sv/ttyS0/" mkdir -p "$DESTDIR/etc/service/" cat >"$DESTDIR/etc/sv/ttyS0/run"<<"EOF" #!/bin/bash dev=/dev/ttyS0 /bin/stty -F $dev sane clocal -crtscts -hupcl exec <$dev >$dev 2>$dev echo echo "Press enter to continue..."; read cd /root /usr/bin/env -i HOME=/root PATH=/usr/sbin:/usr/bin:/sbin:/bin TERM=screen-256color /usr/bin/setsid /bin/bash exec wait #exec /bin/bash #exec /usr/bin/env -i /bin/sh #exec /usr/bin/setsid /bin/sh EOF chmod +x "$DESTDIR/etc/sv/ttyS0/run" ln -sfv "/etc/sv/ttyS0/" "$DESTDIR/etc/service/" mkdir -p "$DESTDIR/etc/ssh" cat >"$DESTDIR/etc/ssh/sshd_config"<<EOF Port 22 Protocol 2 HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_dsa_key HostKey /etc/ssh/ssh_host_ecdsa_key UsePrivilegeSeparation yes KeyRegenerationInterval 3600 ServerKeyBits 768 SyslogFacility AUTH LogLevel INFO LoginGraceTime 120 PermitRootLogin no StrictModes yes RSAAuthentication yes PubkeyAuthentication yes IgnoreRhosts yes RhostsRSAAuthentication no HostbasedAuthentication no PermitEmptyPasswords no ChallengeResponseAuthentication no PasswordAuthentication no X11Forwarding yes X11DisplayOffset 10 PrintMotd no PrintLastLog yes TCPKeepAlive yes AcceptEnv LANG LC_* Subsystem sftp /usr/lib/openssh/sftp-server UsePAM yes AllowUsers calendros EOF cat > "$DESTDIR/etc/apt/sources.list" <<EOF deb $MIRROR $RELEASE main universe deb http://security.ubuntu.com/ubuntu/ $RELEASE-security main universe EOF # /etc/default files: cat > "$DESTDIR/etc/default/console-setup"<<EOF VERBOSE_OUTPUT="no" ACTIVE_CONSOLES="/dev/ttyS0" CHARMAP="UTF-8" CODESET="Uni2" FONTFACE="Fixed" FONTSIZE="16" if [ -f /etc/default/keyboard ]; then . /etc/default/keyboard fi EOF cat >"$DESTDIR/etc/default/keyboard"<<EOF XKBMODEL="pc105" XKBLAYOUT="fr" XKBVARIANT="bepo" XKBOPTIONS="" EOF cat >"$DESTDIR/etc/default/locale"<<EOF LANG="en_US.UTF-8" LC_TIME="en_DK.UTF-8" LC_PAPER="en_GB.UTF-8" LC_MEASUREMENT="en_GB.UTF-8" EOF cat >>"$DESTDIR/etc/bash.bashrc"<<EOF # 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 EOF mkdir -p "$DESTDIR/etc/vim" cat >"$DESTDIR/etc/vim/vimrc"<<EOF set nocompatible set modelines=0 set backspace=2 syntax on set autoindent set ts=4 set shiftwidth=4 set ruler set laststatus=2 set statusline=%<%f%h%m%r%=%l,%c\ %P set wildmode=list:full set nobackup nowritebackup set hlsearch set whichwrap=<,>,[,] set scrolloff=1 EOF rm -r "$DESTDIR/etc/skel" mkdir -p "$DESTDIR/etc/skel" cat > "$DESTDIR/init-stage2.sh" << EOF #!/bin/sh export PATH="/usr/sbin:/usr/bin:/sbin:/bin" mount -no remount,rw / mount -t proc proc /proc mount -t sysfs sysfs /sys /debootstrap/debootstrap --second-stage # second stage may unmount this... [ -e /proc/mounts ] || mount -t proc proc /proc [ -e /sys/kernel ] || mount -t sysfs sysfs /sys busybox mdev -s echo '------ mounts:' cat /proc/mounts echo '------' mv /etc/default/extlinux /etc/default/extlinux.dist cat >/etc/default/extlinux<<EOF2 EXTLINUX_UPDATE="true" EXTLINUX_ALTERNATIVES="default" EXTLINUX_DEFAULT="l0" EXTLINUX_ENTRIES="all" EXTLINUX_MEMDISK="true" EXTLINUX_MEMDISK_DIRECTORY="/boot" EXTLINUX_MENU_LABEL="Ubuntu GNU/Linux, kernel" EXTLINUX_OS_PROBER="false" EXTLINUX_PARAMETERS="ro quiet console=ttyS0,115200n8 panic=120 oops=panic" EXTLINUX_ROOT="root=/dev/vda" EXTLINUX_THEME="none" EXTLINUX_TIMEOUT="1" # wait 1 tenth of a second (0 is wait forever...) EOF2 [ -e /dev/root ] || ln -sv /dev/vda /dev/root extlinux -i /boot/extlinux/ passwd -d -l root useradd -M -b /home -d /home/calendros -U -G sudo -s /bin/bash calendros mkdir -p /home/calendros/.ssh/ touch /home/calendros/.ssh/authorized_keys chmod 700 /home/calendros/.ssh chmod 600 /home/calendros/.ssh/authorized_keys chown calendros:calendros -R /home/calendros echo '. /etc/bash.bashrc' >~root/.bashrc echo '. ~/.bashrc' >~root/.bash_profile echo '. /etc/bash.bashrc' >~calendros/.bashrc echo '. ~/.bashrc' >~calendros/.bash_profile locale-gen en_US.UTF-8 en_GB.UTF-8 en_DK.UTF-8 fr_FR.UTF-8 # dhclient may erase /etc/resolv.conf, and is not really useful here #ip link set eth0 up #dhclient eth0 #apt-get update echo "Dropping a shell, press Ctrl-D or type exit to finish." /bin/bash rm -v /etc/udev/rules.d/70-persistent-*.rules echo "Bootstrap ended, poweroff in 10seconds..." rm /init-stage2.sh #sleep 10 || exec /bin/bash # for debug #poweroff & # does not work sync fuser -k / sleep 1 mount -o remount,ro / exit 0 # will panic, but does not matter now (don't know how to shutdown o/w) EOF chmod +x "$DESTDIR/init-stage2.sh" cat >&2 <<EOF I: please umount destination blockdev... I: like: sudo umount -v "$DESTDIR" I: then run vm, deboostrap phase 2 (adjust blockdev)... I: export DEV=blockdev; qemu-system-x86_64 -machine accel=kvm -m 256 \\ -monitor unix:/tmp/debootstrap-monitor,server,nowait \\ -serial unix:/tmp/debootstrap-serial,server \\ -vga vmware -display none \\ -drive file="\$DEV",if=virtio \\ -kernel "$KERNEL" \\ -append "quiet rootdelay=10 root=/dev/vda init=/init-stage2.sh console=ttyS0,115200n8" I: To copy this image to another host, remember to run: I: extlinux -i /yourcopyplace/boot/extlinux/ I: end of script... EOF