Nerves デバイスを工場出荷状態に初期化するにはどうすればいいのでしょうか?
いくつかアイデアがあります。自分でやったことはないのですが、識者の会話から学んだことをまとめます。参考になれば幸いです。
Elixir プロジェクトのpriv
ディレクトリに初期化用データを追加
最も簡単な方法は、Nerves ファームウエアを構成するElixir プロジェクトのうちどれか一つのpriv
ディレクトリに読み取り専用データを追加することです。 そのデータはElixirコードとともに Nerves イメージに含まれるので、実行時にApplication.app_dir/2 を呼び出してそのパスを取得できます。
実はこれはNerves 特有のものではなく Elixir/Erlang に備わっている機能です。
Erlangのドキュメントにはこう書かれています。
priv - Optional. Used for application specific files.
そういえばPhoenixアプリで写真とかがpriv/static/assets
に格納されてましたね。
assets - a directory that keeps source code for your front-end assets, typically JavaScript and CSS. These sources are automatically bundled by the esbuild tool. Static files like images and fonts go in priv/static.
rootfs_overlay
ディレクトリに初期化用データを追加
初期化用データをrootfs_overlay
ディレクトリに含めることにより、Nerves ファームウエアのビルド時にファイルシステムの一部にしてしまう技です。なんらかの理由で(priv
ディレクトリ以外の)特定のパスに初期化用データを置いておきたい場合はこの手法が便利です。
Nerves により生成されたElixirプロジェクトには、rootfs_overlay
ディレクトリが含まれており、config/config.exs
にそれ用の設定項目があります。
基本的に、rootfs_overlay
ディレクトリに置いたものはすべてディスク上にオーバーレイされます。 例えば、あるファイルをデバイス上の /etc/some_data_file.txt
に存在させたい場合は、そのファイルを rootfs_overlay/etc/some_data_file.txt
のリポジトリに置くことになります。
v1.9.2から以下のディレクトリのオーバーレイが禁止になりましたので、注意してください。
/root
/tmp
/dev
/sys
/proc
/root
(別名/data
)内のすべてのファイルとディレクトリを再フォーマット
工場出荷状態に初期化するとは、読み書き可能な/root
(別名/data
)内のすべてのファイルとディレクトリを削除し、SDカードをmix burn
を実行した時と同じ状態にすることと考えることができます。 その考えでいけば、すべての設定とデータを/root
に保存するということになります。
直接ファイルを削除するのではなく、下位レベルの/data
パーティションをゼロにして再フォーマットするのが確実だと考えられます。
# `/root` がマウントされている場所を確認
root_mount_point = (
System.shell("mount | grep 'on /root'")
|> elem(0)
|> String.split(" ")
|> hd()
)
# `/root`パーティションをゼロにして再フォーマット
System.cmd("dd", ["if=/dev/zero", "of=#{root_mount_point}", "bs=1M", "count=1"])
# 再起動
Nerves.Runtime.reboot
ただ、この作業はちょっと大変なので、将来のNervesリリースでなんとかこれを簡単にできるようにしたいですね。
お、もう簡単にできるようになっているのかも!うっかり見落としてました。
Nerves.Runtime.FwupOps.factory_reset/1、これで一発です。
Nerves.Runtime.FwupOps.factory_reset
WiFi SSID やパスワードなどのネットワーク設定を含む多くの設定がアプリケーション データ パーティションに保存されていることに注意してください。 出荷時設定にリセットされたデバイスは、その後ネットワークに接続できなくなる可能性があります。