Raspberry Pi OSの /boot/wpa_supplicant.conf や /boot/ssh は、後からでも有効

## 結論から

Raspberry Pi OS の `/boot/wpa_supplicant.conf` や `/boot/ssh` の仕組みは、起動してしまった microSD でも有効です。

#### 私の思い違い

Raspberry Pi OS は microSD に書き込んだ後、初回起動時にパーティションを設定したりと自己構成をします。 `/boot/**` の仕組みは、その初回起動時だけの仕組みだと思い込んでおりました。

## /boot/ssh 等を利用する設定は systemd にある

### wpa_supplicant.conf

`ConditionPathExists` でファイルの存在を確認したら `ExecStart` などを実行するようになってます。おそらく問答無用で overwrite されるのでご注意。

```ini:/lib/systemd/system/raspberrypi-net-mods.service
[Unit]
Description=Copy user wpa_supplicant.conf
ConditionPathExists=/boot/wpa_supplicant.conf
Before=dhcpcd.service
After=systemd-rfkill.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/mv /boot/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf
ExecStartPost=/bin/chmod 600 /etc/wpa_supplicant/wpa_supplicant.conf
ExecStartPost=/usr/sbin/rfkill unblock wifi

[Install]
WantedBy=multi-user.target
```

#### 有効化の作業

`/boot/wpa_supplicant.conf` を作成したら `sudo systemctl reboot` で再起動すれば Wi-Fi は動作します。
再起動をしたくない場合は以下の通りです。

```console
$ sudo ip link set wlan0 up
$ sudo systemctl start raspberrypi-net-mods.service
$ sudo systemctl daemon-reload
$ sudo systemctl restart dhcpcd.service
```

### ssh

`/boot/ssh` でも `/boot/ssh.txt` でも動くようになってる。 `ConditionPathExistsGlob` 素敵！

```ini:/lib/systemd/system/sshswitch.service
[Unit]
Description=Turn on SSH if /boot/ssh is present
ConditionPathExistsGlob=/boot/ssh{,.txt}
After=regenerate_ssh_host_keys.service

[Service]
Type=oneshot
ExecStart=/bin/sh -c "systemctl enable --now ssh && rm -f /boot/ssh ; rm -f /boot/ssh.txt"

[Install]
WantedBy=multi-user.target
```

#### 有効化の作業

`/boot/ssh` を作成したら `sudo systemctl reboot` で再起動すれば sshd は動作します。
再起動をしたくない場合は以下の通りです。

```console
$ sudo systemctl start sshswitch.service
```

※ `/boot/ssh` ファイルを使わずに `sudo systemctl enable --now ssh` としても問題ありません。

## 調べた背景

Raspberry Pi OS (特に Lite) を利用する際に重要なのがネットワークです。
キーボードやモニターが無い、いわゆる "Headless" 利用になるため、設定やメンテナンスはネットワークを介したリモートアクセスになるからです。

[Setting up a Raspberry Pi headless](https://www.raspberrypi.org/documentation/configuration/wireless/headless.md) にも書かれている通り、 `wpa_supplicant.conf` と `ssh` ファイルを作り、 microSD の **boot** パーティションに配置することで、それぞれ Wi-Fi と sshd が起動時に有効化できるのは知られている話ですが、冒頭でも書いた通り私の思い違いでした。いつでも有効だったんです。

Raspberry Pi 4 が発売され、[USB Type-C ケーブルが USB On-The-Go(OTG) の Ether Gadget として使えることがわかり](https://dev.classmethod.jp/hardware/raspberry-pi-4-develop-with-mac-using-usb-c-cable)「超べんりじゃん！」と思ったのですが、結局 `apt update` するためにはネットワークが必要となることがわかったので、Wi-Fi の設定を後から入れる方法を探していたというところです。

### USB On-The-Go(OTG) / Ether Gadget の設定

Raspberry Pi Zero (W) や Raspberry Pi 4 で利用可能な USB OTG の Ether Gadget と組み合わせれば、Wi-Fi が無くとも Raspberry Pi OS にログインして設定することができ、後から Wi-Fi の設定を入れることが可能となります。

1. OTG のセットアップは [Windows10でRaspberry Pi Zero (W) をOTGを使ってセットアップする](https://qiita.com/msquare33/items/dc6fc9098f50d9b9dbf2) の通りに行えば OK (Zero だけでなく 4 も同様の手順で OTG できます)
2. USB Ether 経由で `raspberrypi.local` へログイン
3. Raspberry Pi OS 上で `/boot/wpa_supplicant.conf` を作成し以下を実行 (もしくは `$ sudo systemctl reboot` で再起動するのも良しです)

### おまけ: 

`$ sudo grep -r '/boot' /lib/systemd/system/` としたら `apply_noobs_os_config.service` というファイルが見つかりました。

```ini:/lib/systemd/system/apply_noobs_os_config.service
[Unit]
Description=Apply NOOBS config
ConditionPathExists=/boot/os_config.json
Before=display-manager.service getty.target autologin@tty1.service

[Service]
Type=oneshot
TimeoutSec=300
ExecStart=/usr/bin/raspi-config --apply-os-config
ExecStartPost=/bin/systemctl disable apply_noobs_os_config

[Install]
WantedBy=multi-user.target
```

どうやら `raspi-config` を non-interactive で設定できるようです。が、、、肝心の `/usr/bin/raspi-config` の `do_apply_os_config()` を見てみると...

```bash
# TODO: This is probably broken
do_apply_os_config() {
  [ -e /boot/os_config.json ] || return 0
```

> *This is probably broken*

工工エエｴｴ(´Д\`)ｴｴエエ工工
`os_config.json` のリファレンスも見当たらないので、使わない方がいいかもしれません。 (この仕組み自体は参考になるかも)

## あとがき

microSD は速い奴がいい。
特に Wirte=60MB/sを超えてくると 2.3GB くらいでも2分くらいで終わる。(無論 USB 3.0接続だよ)

EoT