debootstrapでdebian最小インストールするスクリプト組んでみた

# モチベーション

- 暇つぶしにQEMU上で動くDebianを最小の構成で組み上げてみたくなった。
- [公式](https://www.debian.org)には普通のインストーラの他にも最小構成インストーラ(mini.iso)があった。
- 色々弄ってたら公式の最小構成より更に小さい構成で組むことが出来た。

# 参考

- [debootstrapでubuntu最小インストール](https://qiita.com/tukiyo3/items/e16dc1d32c7bf6b5b1cc)

# ホスト環境

- Debian 9.x (Stretch) 適当な構成 (parted, cdebootstrap, zerofreeを含む)

# スクリプト

```bash:first.sh
#!/bin/bash

# インストール先デバイス
boot_dev=/dev/sdc
boot_part=${boot_dev}1
mount=mount-dir

# インストールしたDebianが使うスワップ領域
swap_dev=/dev/sdd
swap_part=${swap_dev}5

# ダウンロード先
debian_server_url='http://ftp.jp.debian.org/debian/'

# インストール先デバイスの初期化とパーティションのフォーマット
parted -s $boot_dev -- \
          mklabel msdos \
          mkpart primary ext2 0% 100%
mkfs.ext4 -F -O extent $boot_part

# スワップ領域の初期化とパーティションのフォーマット
parted -s $swap_dev -- \
          mklabel msdos \
          mkpart extended 0% 100% \
          set 1 lba off \
          mkpart logical linux-swap 0% 100%
mkswap $swap_part

# 最小構成をベースにインストール
# 但し、最小構成にはカーネルもブートローダも含まれていないため必要なだけ追加。
mkdir -p $mount
mount $boot_part $mount
cdebootstrap --flavour=minimal \
             --include=linux-image-amd64,grub2,init \
             stretch $mount $debian_server_url

# chrootの準備
mount -t proc none $mount/proc/
mount -t devtmpfs none $mount/dev/
mount -t sysfs none $mount/sys/

# second.sh (後述) をインストール先の環境で実行
cp second.sh $mount/second.sh
chroot $mount /usr/bin/env -i \
                  HOME=/root \
                  TERM=$TERM \
                  PATH=/bin:/usr/bin:/sbin:/usr/sbin \
                  boot_dev=$boot_dev \
                  /second.sh
rm $mount/second.sh

# fstab調整
boot_part_uuid=`blkid $boot_part | sed 's/.* UUID="//' | sed 's/".*$//'`
swap_part_uuid=`blkid $swap_part | sed 's/.* UUID="//' | sed 's/".*$//'`
echo "UUID=$boot_part_uuid / ext4 errors=remount-ro 0 1" > $mount/etc/fstab
echo "UUID=$swap_part_uuid none swap sw 0 0" >> $mount/etc/fstab

# キャッシュ削除(任意)
rm -rf $mount/var/cache

# マウント解除
umount -R $mount
rmdir $mount

# ディスク上の未使用領域クリア(任意)
zerofree $boot_part
```

```bash:second.sh
#!/bin/bash

# ブートローダのインストール等
grub-install $boot_dev
update-grub2

# rootのパスワード設定
echo 'Enter root password'
read root_passwd
passwd root << EOS
$root_passwd
$root_passwd
EOS
```

# 結果

3〜4割くらい小さくなった。

```bash
$ xz -k9e hdd1.raw # mini.isoを使用してインストールした後、zerofreeした物
$ qemu-img convert -f raw -O qcow2 hdd1.raw hdd1.qcow2
$ xz -k9e hdd2.raw # 今回作成したディスク
$ qemu-img convert -f raw -O qcow2 hdd2.raw hdd2.qcow2
$ ls -l
-rw-r--r--  1 owner staff   738000896  3 19 19:49 hdd1.qcow2
-rw-r--r--  1 owner staff   511639552  3 19 19:48 hdd2.qcow2
-rw-r--r--  1 owner staff   129535360  3 19 19:23 hdd1.raw.xz
-rw-r--r--  1 owner staff    98521664  3 19 19:18 hdd2.raw.xz
...
```

`apt-utils`や`console-setup`等の幾つかのパッケージが入ってないので必要に応じて`apt install`すること。

# 追記

- `ifupdown`を入れないとネットワークに繋がらないので`apt`出来ません。
  - `/etc/network/interfaces`に`iface ens3 inet dhcp`的な物を追記する必要もあります。
- `/var/cache`が無いと`apt install`がコケるようです。

```bash:second.sh(続き)
apt update
apt -y install ifupdown
for iname in `ls /sys/class/net`; do
    echo "auto $iname" >> /etc/network/interfaces
    if [ $iname = 'lo' ]; then
        echo 'iface lo inet loopback' >> /etc/network/interfaces
    else
        echo "iface $iname inet dhcp" >> /etc/network/interfaces
    fi
done

```