GentooをConoHaに２つのスクリプトでインストールする

Gentooのインストール手順にはそれぞれ意味があるのだが、面倒に感じる人もいるだろう。
ここでは二枚のスクリプトでこれを単純化してみた。

# 事前課題

- chrootを行うので、chroot前後でスクリプトを分割する必要がある
- 512MBプランだとgentoo-sourcesの導入中に落ちる
  - これは単なるメモリ不足なのでswapfileを作成すれば解決する

# 基本調査

## Handbook walkthrough

https://wiki.gentoo.org/wiki/Handbook:AMD64#Installing_Gentoo

### デバイス、ネットワーク
特に明記されてないが、ConoHaのVPSではXeon以外のCPUを想定する必要がないと思われる。

https://qiita.com/nothink/items/6ef2d03f4872b605470f

```shell-session
# cat /proc/cpuinfo
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 62
model name	: Intel(R) Xeon(R) CPU E5-2650 v2 @ 2.60GHz
stepping	: 4
microcode	: 0x1
cpu MHz		: 2599.719
cache size	: 4096 KB
physical id	: 0
siblings	: 1
core id		: 0
cpu cores	: 1
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 13
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl cpuid pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm fsgsbase tsc_adjust smep erms xsaveopt
bugs		:
bogomips	: 5199.43
clflush size	: 64
cache_alignment	: 64
address sizes	: 46 bits physical, 48 bits virtual
power management:

   <snip>
```
また、既定だとVirtioが有効、またDHCPサーバも立っている。
なのでAMD64だとGentooは意外なほどすんなりと入る。
まずはこの「すんなり入るGentoo」の手順を単純化しよう。

### メディア

メディアは[conoha-iso](https://github.com/hironobu-s/conoha-iso)のようにOpenStack準拠のREST API経由で挿入できる。
最新のメディアは `/gentoo/releases/amd64/autobuilds/latest-iso.txt` を確認して取得する。日本のミラーはJAISTとIIJだか、tyo1はIIJの方が近いようなので[IIJ HTTPのlatest-iso.txt](
http://ftp.iij.ad.jp/pub/linux/gentoo/releases/amd64/autobuilds/latest-iso.txt)を確認して取得する。
形式はこんな感じ。

```text:latest-iso.txt
# Latest as of Thu, 09 Nov 2017 00:30:01 +0000
# ts=1510187401
20170209/hardened/admincd-amd64-20170209.iso 424673280
20170907/install-amd64-minimal-20170907.iso 283115520
```

インストール用は後者なので miminal なり install なりで引いて、ここまでのパスを足せばISOイメージのURLが出来上がる。こんな感じに。

```bash
curl http://ftp.iij.ad.jp/pub/linux/gentoo/releases/amd64/autobuilds/latest-iso.txt | grep minimal | sed -e 's/^/http:\/\/ftp.iij.ad.jp\/pub\/linux\/gentoo\/releases\/amd64\/autobuilds\//g' | sed -e 's/ [0-9]*$//g'
```

落としてみた。

```shell-session
$ curl http://ftp.iij.ad.jp/pub/linux/gentoo/releases/amd64/autobuilds/latest-iso.txt | grep minimal | sed -e 's/^/http:\/\/ftp.iij.ad.jp\/pub\/linux\/gentoo\/releases\/amd64\/autobuilds\//g' | sed -e 's/ [0-9]*$//g' | xargs curl -O
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   172  100   172    0     0   7479      0 --:--:-- --:--:-- --:--:--  7818
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  270M  100  270M    0     0  1875k      0  0:02:27  0:02:27 --:--:-- 1625k
$ ls -l install*
-rw-r--r--  1 gakongakon  yasagure  283115520 32  13 25:61 install-amd64-minimal-20170907.iso
```

[conoha-iso](https://github.com/hironobu-s/conoha-iso)に投げ込むときはURL指定なので、こんな感じになる。

```console
$ curl http://ftp.iij.ad.jp/pub/linux/gentoo/releases/amd64/autobuilds/latest-iso.txt | grep minimal | sed -e 's/^/http:\/\/ftp.iij.ad.jp\/pub\/linux\/gentoo\/releases\/amd64\/autobuilds\//g' | sed -e 's/ [0-9]*$//' | xargs -I{} conoha-iso download -i {}
```

### パーティショニング

私はSSDの時はswapパーティションを作らず、インストール後にswapファイルを必要なだけ確保する。
今回もrootパーティションだけを作成する。

パフォーマンス的に特に問題ないと仮定して、MBRかGPT上にext4で作る。

https://linux.die.net/man/8/parted
https://qiita.com/ngyuki/items/93da394fd0847ed5155e

また、複数パーティションにすると fstab の修正が面倒なので、やはりrootのみで。

### Stage3 tarball

Stage3 tarball もメディアと同じく `/gentoo/releases/amd64/autobuilds/latest-stage3-*.txt` を確認すれば最新を取得できる。例えば

- latest-stage3-amd64-hardened+nomultilib.txt
- latest-stage3-amd64-hardened.txt
- latest-stage3-amd64-nomultilib.txt
- latest-stage3-amd64-systemd.txt
- latest-stage3-amd64-uclibc-hardened.txt
- latest-stage3-amd64-uclibc-vanilla.txt
- latest-stage3-amd64.txt
- latest-stage3-x32.txt
- latest-stage3.txt

などがあるが、nomultilibである必要もなくGentooらしくsystemd無しではじめて、普通にglibcを選ぶと無難に `latest-stage3-amd64.txt` となる。
(一覧が欲しい場合は `latest-stage3.txt` を取る)

同じくtyo1最寄りの[IIJにあるlatest-stage3-amd64.txt](http://ftp.iij.ad.jp/pub/linux/gentoo/releases/amd64/autobuilds/latest-stage3-amd64.txt)を取得した後、目的のStage3 tarballを取ろう。

```bash
curl http://ftp.iij.ad.jp/pub/linux/gentoo/releases/amd64/autobuilds/latest-stage3-amd64.txt | grep stage3-amd64 | sed -e 's/^/http:\/\/ftp.iij.ad.jp\/pub\/linux\/gentoo\/releases\/amd64\/autobuilds\//g' | sed -e 's/ [0-9]*$//g' | xargs curl -O
```

宗教上の都合でnomultilibの場合はこんな感じ。

```bash
curl http://ftp.iij.ad.jp/pub/linux/gentoo/releases/amd64/autobuilds/latest-stage3-amd64-nomultilib.txt | grep stage3-amd64 | sed -e 's/^/http:\/\/ftp.iij.ad.jp\/pub\/linux\/gentoo\/releases\/amd64\/autobuilds\//g' | sed -e 's/ [0-9]*$//g' | xargs curl -O
```

余裕があるなら SHA512 checksum をチェック。

### make.conf

make.confをいじる場合はGitHubにでも配置してリリースされたものをcurlなりwgetなりで取るのが楽だろう。

幸いにもアーキテクチャは明確だが代替わりの可能性もあるので、 `-march=native` で対応。
動的修正は、`MAKEOPTS` を論理プロセッサ数 + 1 に書き換える程度。

```bash
grep processor /proc/cpuinfo | wc -l
```

ただここで無理していじるより、規定値でインストールした後に編集して `emerge -uDN @world` や `emerge -e @world` のほうがわかりやすそう

### プロファイル他

プロファイルはインストール後に選ぶほうが効率が良さそうなので変更せずに行う。
タイムゾーンや言語については一考が必要だが、ひとまず `Asia/Tokyo` に `en` で通すべき？

### kernel

選択肢
- genkernel
- make localyesconfig 等を駆使
- カスタマイズされた .config を準備

#### genkernel

簡単に済ますなら `genkernel` になる。
ただし、`genkernel` は結構な量のモジュールを有効にしているため長い待ち時間が発生するのが弱点。

あと、LiveCDのkernelを使ったり既存インストール済みkernelをそのまま使えるに越したことはないので `make localyesconfig` の方が良いかもしれない。

#### localyesconfig 等を駆使

まずlocalyesconfigを使う場合はベースとなる.configが必要になる。

```console
% make help
<snip>

Configuration targets:
<snip>

  localmodconfig  - Update current config disabling modules not loaded
  localyesconfig  - Update current config converting local mods to core
```

make menuconfig を使わないとなるとlsmodくらいしか手がかりがないため、ConoHaなどのVPSの場合はすでにインストールされているkernelの.configを引っ張ってくるのが一番楽。
あとは、makeが未設定項目の挙動について尋ねてくるのでその対応を行う。

```
yes | make localyesconfig
```

もし組み込みたくない、不要なものはできるだけ削ぎ落としたいとなると localmodconfig の出番だが、今回は簡易さを優先する。


### ネットワーク

DHCPで問題がないため、dhcpcdを使うのが妥当だろう。
この段階でのイーサネットインターフェイスは単体と仮定して作業を進めれば特に問題はない。ありがたいことに大抵の場合 `eth0` として認識される。

### 選択

ここからは自由度が増す部分。
一応テンプレ構成を導入するが選択できるようにしても面白そう。

- logger : sysklogd
- cron : cronie
- bootloader : grub(>=2)
- sshd : 有効化してセット済みの公開鍵を設定 or ランダムなパスワードを生成？

Gentooの慣例だとこの段階ではrootしかいない。なのでsshd_confgもPermitRootLoginが有効になっている。


# できあがり例

https://github.com/nothink/conohoo/tree/master/src/sh/manual

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

# creating a single partition.
parted -s -a optimal /dev/vda -- mklabel msdos mkpart primary 1 -1 set 1 boot on
# creating file systems.
mkfs.ext4 -F /dev/vda1

# mounting the root partition
mount /dev/vda1 /mnt/gentoo

# copying chrooted install script
cp install-chroot.sh /mnt/gentoo/

# creating swapfile and swapon (4GB)
dd if=/dev/zero of=/mnt/gentoo/swapfile bs=1M count=4096
mkswap /mnt/gentoo/swapfile
swapon /mnt/gentoo/swapfile

# setting the datetime
ntpd -q -g

# downloading the gentoo stage tarball
cd /mnt/gentoo
curl http://ftp.iij.ad.jp/pub/linux/gentoo/releases/amd64/autobuilds/latest-stage3-amd64.txt | grep stage3-amd64 | sed -e 's/^/http:\/\/ftp.iij.ad.jp\/pub\/linux\/gentoo\/releases\/amd64\/autobuilds\//g' | sed -e 's/ [0-9]*$//g' | xargs curl -O
# unpacking the stage tarball
tar xvjpf stage3-*.tar.bz2 --xattrs --numeric-owner

# TODO : edit /etc/portage/make.conf
# TODO : setting mirrors

# copy DNS info
cp --dereference /etc/resolv.conf /mnt/gentoo/etc/

# mounting the necessary filesystems
mount --types proc /proc /mnt/gentoo/proc
mount --rbind /sys /mnt/gentoo/sys
mount --make-rslave /mnt/gentoo/sys
mount --rbind /dev /mnt/gentoo/dev
mount --make-rslave /mnt/gentoo/dev

# chroot: entering the new env
chroot /mnt/gentoo /install-chroot.sh

# filanize.
cd
umount -l /mnt/gentoo/dev{/shm,/pts,}
umount -R /mnt/gentoo
reboot
```

```bash:install-chroot.sh
#!/bin/bash

# chrooted: entering the new env
source /etc/profile

# installing an ebuild repository snapshot from the web
emerge-webrsync

# updating the ebuild repository
# TODO not need
#emerge --sync

# mark news items as read
eselect news read

# updating the @world
# TODO not need
#emerge --update --deep --newuse @world

echo "Asia/Tokyo" > /etc/timezone

# configure locales
sed -i 's/^#en_US.UTF-8 UTF-8$/en_US.UTF-8 UTF-8/' /etc/locale.gen
sed -i 's/^#ja_JP.UTF-8 UTF-8$/ja_JP.UTF-8 UTF-8/' /etc/locale.gen
locale-gen
env-update
source /etc/profile

# installing the kernel sources 'gentoo-sources'
emerge sys-kernel/gentoo-sources
# installing the kernel using genkernel
emerge sys-kernel/genkernel
genkernel all

# creating the fstab file
blkid /dev/vda1 -o value -s UUID | while read uuid; do echo UUID=$uuid / ext4 defaults,noatime,discard 0 1; done >> /etc/fstab

# configuring the network
echo config_eth0=\"dhcp\" >> /etc/conf.d/net
# automatically start networking at boot
cd /etc/init.d
ln -s net.lo net.eth0
rc-update add net.eth0 default

# installing the system logger(sysklogd)
emerge app-admin/sysklogd
rc-update add sysklogd default

# installing the cron daemon(cronie)
emerge sys-process/cronie
rc-update add cronie default

# automatically start sshd at boot
rc-update add sshd default

# installing filesystem tools
emerge sys-fs/e2fsprogs

# installing networking tools (dhcpcd)
emerge net-misc/dhcpcd

# installing grub2
emerge sys-boot/grub:2
grub-install /dev/vda
grub-mkconfig -o /boot/grub/grub.cfg

# change password reboot
echo root:conohoo37564 | /usr/sbin/chpasswd

# exit this chroot systems
exit
```