パスワード認証しないで machinectl から nspawn コンテナを操作する
掲題のような事をしたい気持ちになることが時々ある。というよりずっとあっていつか調べようと思って放置していた。
やっと調べる気になった結果以下のような Polkit ルールを /etc/polkit/rules.d/
下に適当な名前(10-nopassword-machinectl.rules
など)で配置して systemctl restart polkit
してあげればよい:
このルールの場合全てのユーザでパスワード認証を迂回するわけではなく wheel
なグループにいるユーザのみに限定される。
わたしの場合 sudo の許可でこのグループにユーザをいれているので特に不都合はない。不要な場合は subject.isInGroup("wheel")
の行を消してやればよい。
これで少しは machinectl
で nspawn コンテナを使って潰してというやつがやりやすくなると思う。とても嬉しい。
参考
MacBook Pro (Late 2012) 買った
掲題の買い物をした。友人から3万円也。
JIS 配列のキーボードがついたパソコンを買うのは ThinkPad X40 を買った頃以来なので10年ぶりくらいのはず。
当初はこれも US 配列なキーボードに入れ替えるつもりだったが小手調べのつもりで裏蓋をあけた瞬間に ThinkPad いじりの常識やノウハウが一切活かせないシビアな光景が目に入ったので諦めた。つくりをみれば当然なのだがキーボードだけではなくガワも交換せねばならず、ガワを交換するにもキーボードへアクセスするにもあらゆる部品をひっぺがえさねばらなず、これは壊すな、と感じたのだった。
JIS 配列の違和感も最初の1時間くらいでなくなった。実用上はおそらく SSH で入って操作するのであまり困らないなと思っている。
とりあえず macOS と Arch Linux のデュアルブートにした。Arch 側はいつもどおり KDE(Plasma + SDDM)にした。 景気よく OSX をフッ飛ばして Arch だけにしようと当初は思っていたのだが、https://wiki.archlinux.org/index.php/Mac#Firmware_updates を読んで OSX は残したほうがよいとのことだったのでこれも止した。
GPD Pocket の次に新しい年代のパソコンがこれになり、それがもう8年前の機械か、なんならまだ現役の ThinkPad X201s は2011年製だから9年前か、という状態。隔世の念がある。
ちなみに写真で本体左側についている黒いのは Elecom WDC-433SU2Mで802.11acな通信を実現したかった - テクニカルプア と Elecom WDC-433SU2Mで802.11acな通信を実現したのかわからないけどとりあえず動いた - テクニカルプア で苦しんだ Elecom の WiFi アダプタ。当該2記事ではドライバ入手やらコンパイルやらでゴタゴタやっているが、2020年現在は Linux カーネル本体に(おそらく互換のきく)ドライバがとりこまれたようで、挿したら何もせず認識してくれた 1。ただし ac ではなく n くらいの速度しかでていない。これも隔世の念がある。
AUR のパッケージ更新を日次で勝手にやるようにして楽をしている話
半年くらい放置しているので意図しないものが出るようになっている。出さなくさせる為に書く。
いろんなところで散々言及しているがわたしは AUR でいくらかの PKGBUILD を公開している: AUR (en) - Search Criteria: nosada
PKGBUILD を公開といってもやることは開発元のコードを落としてきて pacman
が解釈できるパッケージに落とすというだけなので大した内容ではない。
ただ開発元が新しいバージョンをリリースする度に PKGBUILD 側でもバージョンを更新してメタデータも書き換えて AUR に反映させてとそれなりに作業が発生するので、手間がかかる作業ではある。
去年末から今年の始めにかけて https://github.com/x-motemen/ghq が、そしてほぼ恒常的に https://github.com/digitalocean/doctl が、それぞれ結構な頻度で新しいバージョンをリリースしており、その度に PKGBUILD を更新して……という作業をするのが面倒になってきた。無論新しいバージョンがリリースされること自体はとても喜ばしいのだが、普通に作業量が多くてしんどくなってしまったのは事実である。
どうにかしたいな、バージョンが更新されたらそいつを PKGBUILD に落として AUR への反映までやってくれるようなやつ欲しいな、としばらく考えていた。 で、作った。今確認したら最後に更新したの1月下旬だった:
やることは単純で、
- AUR ユーザがもってる PKGBUILD を総浚いする
- 総浚いした中で GitHub 上で開発されているものの最新バージョンをチェックする
2.
で確認した最新バージョンが PKGBUILD 上のそれと異なる場合に新バージョンと見做して更新- PKGBUILD 更新
- .SRCINFO(パッケージのメタデータ)更新
makepkg -sfmL --noconfirm
してちゃんと新バージョンでパッケージが作れるか確認
3.
できちんとパッケージが作れることが確認できたら AUR 更新分を反映
ということを https://hub.docker.com/r/archlinux/base/ を基にした Docker コンテナ内でやる。 この Docker コンテナを systemd-timer を使って一日一回起動してくるようにし、開発元で更新があればこのタイミングで PKGBUILD の更新が発生するようにしてある。
既にこいつを使用しはじめて2ヶ月程度経つが、わたしが管理している AUR の PKGBUILD で目立った問題は発生していない。はず。
README.md に拙く書いた通りビルドの進捗や更新の成否を通知する都合上 Slack に依存していたり、作業内容の性格上既に AUR にユーザアカウントが存在している必要があったりと制約が多い内容ではあるが、AUR で公開している PKGBUILD を更新し続けるのが面倒になってきた人にとっては便利なものになっていると思っている。
現時点では GitHub 上で開発されているものしかバージョン更新の検知に対応していないので、他の環境上で開発されているものもきちんと更新を検知できるようにしていきたい。
doctl にプルリク投げたら DigitalOcean からノベルティを貰った話
わたしは AUR にいくらか PKGBUILD を公開しており、その中に DigitalOcean (https://www.digitalocean.com/) の CLI ツールである https://aur.archlinux.org/packages/doctl/ というものがある。 upstream はこれ:
ある日こいつが makepkg -sri
でビルドするとコケるようになり、doctl 側をみてみたところビルドスクリプトに難があるようだった。
ビルドが通らないと困るので直すことにした。それが以下のプルリク:
中身をみてもらえればわかる通り大した内容ではない。
で、このプルリクのコメント最下にあるように DigitalOcean の中の人から連絡くれというメッセージがきていたのでやりとりをし、いろいろあってノベルティを貰えることになった。
貰ったノベルティが本項目冒頭の写真になる。シャツ1枚にステッカー3枚、握ってストレスをどうこうするやつひとつ。ドイツから遠路はるばる今日到着した。
https://sngsk.info や https://mastodon.sngsk.info を動かしているサーバは DigitalOcean の一番安い VPS を使っている。今後もお世話になります。
ちなみにすぐ直したわけではなくしばらく様子をみてはいた。その間 AUR に投稿した内容にパッチを含めて誤魔化したりしていた。
mkosi で実行される処理に AUR パッケージのビルドとインストールを含める
の続編。件の記事で挫折した内容が達成できたので書く。
mkosi
によるイメージのビルド時に AUR パッケージのビルドとインストールもあわせてやる方法が実現できた。
これによって先の内容は無用となった。哀しい。
TL; DR
をみてもらうのが手っ取り早い。
解説
上の通りなのだがそれではブログに書く意味がないので言葉で説明する。
ビルド中のコンテナから外に出れない
mkosi.default
の [Packages]
内で WithNetwork=yes
を与えるか mkosi
自体に --with-network
を与える。
こうすることで mkosi.build
スクリプトが実行される段階(mkosi
の man 内容でいう development image)でコンテナから外に出れる。
man に書いてあったのを見落としていた。man はちゃんと読むべきだった。
ちなみに WithNetwork=yes
をすると mkosi
を実行しているホストのネットワークがそのまま使用され、そうでない場合は systemd-nspawn
コマンドに --private-network
が付与されるようだった。
ホストとコンテナとでネットワークまわりの namespace が共有されてしまうのはちょっと気持ち悪いが、まあいいか……。
ビルド対象が依存するパッケージをいれる
上の WithNetwork=yes
でインターネットに出れるようになる為、 pacman -U
する際の依存関係解決も pacman
側で任せられるようになる。
よって mkosi.default
の [Packages]
内に依存パッケージをズラズラ書いておく必要がなくなる。単に pacman -U --noconfirm
とかすればよい。
ただデフォルトでは /etc/pacman.d/mirrorlist
の内容が全部コメントアウトされているので、 mkosi.postinst
あたりで適当なミラーをアンコメントするなり適当なファイルで書き換えるなりする処理がが必要。
私は後者を選んだ。
PKGBUILD をコンテナ内に持ち込む
あらかじめ AUR 上のパッケージを手元に git clone
しておく。以下では git clone
してできたディレクトリを aurpkg/
とする。
mkosi.default
の [Package]
内で以下のようにしてやればよい:
BuildSources=aurpkg
を指定SourceFileTransfer=mount
を指定
こうすると mkosi
するディレクトリの中にある aurpkg/
というディレクトリがビルド用コンテナ内から $SRCDIR
(/root/src
) で参照できる。
makepkg
コマンドを叩く
makepkg
コマンドは root では実行できない。しかし mkosi.build
は root として実行される。どうするか。nobody ユーザとして makepkg
を実行してやればよさそう。
具体的には sudo -u nobody -- bash -c "makepkg -sr"
などとやればよい。
ただしこれを実行すると AUR パッケージが必要とするパッケージをインストールする段階にうつり、nobody ユーザが sudo
で root になる為のパスワードをきかれてしまい悲しいことになる。
なので事前に PKGBUILD の depends
や makedepends
に書かれてるものを pacman -S --noconfirm
しておくのがよい。
以上を踏まえて私は以下のようにした:
source $SRCDIR/PKGBUILD [[ -n "$depends" ]] && pacman -Sy --noconfirm "${depends[@]}" [[ -n "$makedepends" ]] && pacman -Sy --noconfirm "${makedepends[@]}"
また makepkg
は自身が使うディレクトリを一旦 mkdir -p
してみる実装になっているようで 1、 $SRCDIR
(/root/src/
) や $BUILDDIR
(/root/build/
) を nobody ユーザで mkdir -p
できるようになっていないとエラーを吐いてコケてしまう。これには /root/
で nobody ユーザが実行権限をもっている必要がある。
加えて $BUILDDIR
や $SRCDIR
および後述する $DESTDIR
(/root/dest/
) それ自体も nobody ユーザから読み書きができるようになっていないと必要なファイルを参照したり作成できなくなってしまうので、これまたコケてしまう。
よって setfacl
で以下のようにしてやる:
for DIR in $BUILDDIR $SRCDIR $DESTDIR; do setfacl -m u:nobody:rwx $DIR setfacl -d --set u:nobody:rwx,o::- $DIR done setfacl -m u:nobody:rwx /root setfacl -d --set u:nobody:rwx,o::- /root
makepkg
の結果をどうインストールするか
mkosi.build
が実行される development image の段階で生成物を pacman -U
しても最終的に得られるイメージには反映されない。development image はあくまで中間イメージであり、最終成果物を得る為の過程にすぎない為だ。
また mkosi.build
を実行することで作成された内容は $DESTDIR
(通常はコンテナ内 /root/dest/
)に移しておかないと mkosi.build
終了時に中間イメージごと消滅してしまう。
mkosi.postinst
は中間イメージ作成時と最終イメージ作成時の双方で実行されるので、 pacman -U
を mkosi.postinst
で実行してあげればよい。
また mkosi.build
で makepkg -sr
した結果作成されたパッケージを $DESTDIR
下に移すには makepkg
する際に PKGDEST
という環境変数を $DESTDIR
にしてやればよい。こうすることで作成されたパッケージは $DESTDIR
以下に出力される。
$DESTDIR
に移された成果物は最終イメージ内 /
直下に配置されるので、 mkosi.postinst
では /
下にあるパッケージを pacman -U
してやればよい。
# mkosi.build # mkosi.build は $SRCDIR (/root/src/) で実行されるので makepkg する前にディレクトリを移動する必要はない # PKGEXT を変えているのは生成物を xz で圧縮させないようにさせるため sudo -u nobody -- bash -c "PKGDEST=$DESTDIR PKGEXT='.pkg.tar' makepkg -sr"
# mkosi.postinst for CANDIDATE in /*.pkg.tar; do if [ -e "$CANDIDATE" ]; then pacman -U --noconfirm "$CANDIDATE" rm -f "$CANDIDATE" fi done
まとめ
とりあえずやりたいことはできるようになったのでよかった。なんかもっとシンプルにできそうな気もするが、今はこれが限界。
参考
mkosi でつくる nspawn 用イメージに AUR パッケージをインストールしたい
2019-10-05 追記: この内容は古くなった。もっと確実な方法を以下で書いている。 ただし単純さでいえば本項目のほうが優れているかも。
90日以上放置すると出るアレが出ていたのでくだらん内容で凌ぐ。 それと mkosi はとくに systemd-nspawn 専用のツールというわけでもなく qemu などで起動する VM 用のイメージも作れるようだが、まあ、うん、いいじゃないですか。
最初に書いておくと mkosi
する過程で AUR パッケージをビルドしてイメージにインストールするという方法は扱っていない。
それをやろうとして2ヶ月ほど苦悩し、結局挫折して今に至る。
TL; DR
devtools
いれて事前にホスト側でパッケージつくる。
作ったパッケージを mkosi.extra
内に置いた上で mkosi.postinst
で pacman -U
するようにして mkosi
する。
動機
https://aur.archlinux.org/packages/tor-browser/ を使いたかったのだが Firefox が動くことになるので GTK が必要だった。 一方で現在 KDE を使っていて GTK なしでなんとかなっているので GTK をインストールしたくないという気持ちがあった。 既に Chromium が動くようになっている systemd-nspawn 用イメージがあるので、そこから起動してくるコンテナに件のパッケージをインストールしてやれば万事解決するのではと考えた。
方針
AUR パッケージをビルドする際に必要となると思しきパッケージをインストールすることでホストを汚したくないという向きの為に https://www.archlinux.org/packages/extra/any/devtools/ というものがある。 どうやらこれは Arch Linux 開発者向けのものらしいが、Arch 用パッケージを作るだけという用途でも充分に効果を発揮する。
https://wiki.archlinux.org/index.php/DeveloperWiki:Building_in_a_clean_chroot が詳しいが、 devtools
に同梱される各種スクリプトを使用することで chroot で隔離された環境で makepkg
に類することができる。
今回の用途としては AUR から git clone
してできたディレクトリ内で extra-x86_64-build
してやれば事足りる。
こうすると extra-x86_64-build
を実行したときに居たディレクトリ内に pacman
で処理できるパッケージができる。こいつを mkosi
で処理できる場所に置いてやればよい。
mkosi
はこれを実行したディレクトリ内にある mkosi.extra/
というディレクトリの中身をビルド対象イメージ内に全部コピーするので、先のパッケージをこのディレクトリに置いてやればイメージ内にパッケージが持ち込まれる。
これをどうインストールしてやるかについては mkosi.postinst
というビルド処理完了時にイメージ内で実行されるスクリプトがあるので、この中で対象のパッケージを pacman -U
してやるようにすればよい。
なお AUR パッケージの依存関係解決が走る場合、 mkosi.postinst
が実行される段階ではネットワークがうまく疎通できなくなる 1 ので、ビルド内容を定義する mkosi.default
なファイルで事前に AUR パッケージが依存するパッケージを全部列記してインストールしておくようにしたほうがよい。
実例
- https://github.com/nosada/mkosi-files/blob/41302ee69b925ee9b65693122eab59b48d5f456b/guispawn/Makefile#L13-L20 のようにする
- https://github.com/nosada/mkosi-files/blob/41302ee69b925ee9b65693122eab59b48d5f456b/guispawn/mkosi.postinst#L12-L14 のようにする
- https://github.com/nosada/mkosi-files/blob/41302ee69b925ee9b65693122eab59b48d5f456b/guispawn/mkosi.default.tmpl#L11-L40 のように必要なパッケージを書いておく
- こうすると
make
で AUR パッケージ入りのイメージが生成される
nspawn コンテナの中で nginx を動かそうとすると /dev/null が open() できずコケる件が解消された
GitHub のプルリクやらイシューの観察日記なのでこの項目を読む価値はないです。
mastodon.sngsk.info が死んだ / 潰れたとき用兼 TL; DR
- [Arch|AUR] After upgrading to 3.4 nginx won't start on container because it can't open /dev/null · Issue #4950 · lxc/lxd · GitHub というものがあった
- [RFC] core: adapt PrivateDevices= to changed behavior on 4.18 kernels by brauner · Pull Request #9483 · systemd/systemd · GitHub というプルリクが systemd に対して存在していて、これはマージこそされなかったが事象は解消された的なメッセージが添えられて閉じられている
- あとは掲題通り
mastodon.sngsk.info が動いてる時だけ用を成す本文
sngsk.info の現在 - テクニカルプア でも言及していた下記が修正されていた:
以下これに気付いたときの記録:
Docker から逃れるために nspawn 使ってたのに nspawn が使えなくなって Docker に逃げるというアベコベな状況がなんとかなってよかった。