テクニカルプア

備忘録と若干の補足

DS61 V1.1 を買った + xrdp で RDP と仲良くなるまでのメモ

通して読んでみると別に RDP と仲良くなれてないな。まあいいか。そんなかんじの内容です。

前フリ

掲題のパソコンを友人から購入した。以下で紹介されているものを手頃な金額で譲ってもらえた。 hanjuku-am2.hatenablog.com

とくに目的のない買い物ではあった。悩む理由が金なら買え、という古からの箴言に従ったかたちとなる。

手にいれてからしばらく放置していたのだが、宅内サーバ的な用途で動かしたり動かさなかったりしている ThinkPad X61 & X201s をこいつで置き換えてしまおうと思い立ち、いつもどおり Arch をいれて動かせるようにしてみた。

ちなみに後者はこれで入手したものである。もう3年もまえになるのだな……。

で、作業している間にこいつを Blu-ray 再生専用機に仕立て上げ、手元の PC(これも今だにこの X201s。もう6年も前か……)に負荷をかけることなく映画を観ようと思い至った。 xrdp あたりをいれて手元 PC へ RDP で映像と音を飛ばしてもらうおうという魂胆である。

で、やってみたのだが割と苦戦した。DS61 V1.1 の中の SSD が吹き飛んで再びセットアップしなくてはならなくなった時に泣かないよう、今回泣いた内容を記録しておこうと思う。ということで私的な備忘録であり体系立ってはいないメモをかく。

初期設定

Installation guide - ArchWiki に従い素直にやる。

とりあえずちゃんと動くようになったら yay とかをいれて AUR も使えるようにしておく。

sudo の設定をした上で必要そうなグループにもユーザをいれておく:

$ sudo gpasswd -a $USER users

X をうごかす

まずはお約束のやつをいれる:

# pacman -S xorg-server
# pacman -S xf86-video-intel xf86-video-fbdev xf86-video-vesa

/etc/mkinitcpio.confMODULESi915 をいれてカーネルイメージを作りなおすやつもやる:

# grep 'MODULES=' /etc/mkinitcpio.conf | grep -v '#'
MODULES=(i915)
# mkinitcpio -P

おわったら再起動をする。

こんかい当初はデスクトップ環境という大物をいれるのはやめて i3 + ly でシンプルにやろうとした。が、挫折した。諦めて馴れ親しんだ KDE をうごかすことにした:

# pacman -S plasma

当初は SDDM もいれたが、xrdp でリモートデスクトップをやる場合はディスプレイマネージャが不要なので SDDM は不要であった。ゆえに消してある。これに気付くまでかなり時間がかかった。 要するに startx みたいな感じで X が起動されるため .xinitrc$HOME 下に置かねばならぬということで以下のようにする:

(注:ここの '#' はプロンプトではなくコメントの意)
# cat ~/.xinitrc
export DESKTOP_SESSION=plasma
exec dbus-run-session startplasma-x11

ディスプレイマネージャは不要ということがわかったので、次回おなじ作業をやるときは i3 でリベンジできるかもしれない。

PulseAudio でいいので以下のようにする:

# pacman -S pulseaudio pulseaudio-alsa

一応この時点で必要そうなグループにユーザをいれておく:

$ sudo gpasswd -a $USER audio

xrdp をうごかす

素直に以下のようにする:

$ yay -S xrdp xordxrdp pulseaudio-module-xrdp

今回バックエンドを xorgxrdp にしたので Xrdp - ArchWiki に従い /etc/X11/XWrapper.config をつくる:

(注:ここの '#' はプロンプトではなくコメントの意)
# cat /etc/X11/Xwrapper.config
allowed_users=anybody

わたしの環境だと xrdp.service が吊るしのままだとうまく起動しなかった。 どうもネットワーク系サービスの起動中にこいつが起きてしまうせいでコケるようだったので、こいつが依存している xrdp-sesman.servicenetwork-online.target の後で起動させるようにしてみた:

(注:ここの '#' はプロンプトではなくコメントの意)
# cat /etc/systemd/system/xrdp-sesman.service.d/override.conf
[Unit]
After=network-online.target

ここまでやったら以下のようにして xrdp が起動してくるようにしてやる:

# systemctl enable xrdp.service
# systemctl enable xrdp-sesman.service

必要そうなグループにユーザをいれるやつもやる:

$ sudo gpasswd -a $USER video

Blu-ray を再生できるようにする

いつも mpv を使用しているのでそんな感じにやる:

$ sudo pacman -S mpv libbluray
$ yay -S makemkv-cli
$ yay -S makemkv-libaacs

makemkv-cli の作業中に教えてもらえる以下もやる:

# echo sg > /etc/modules-load.d/sg.conf

必要なグループにユーザをいれる。これをしないと RDP セッション内で Blu-ray ドライブにアクセスできなかった:

$ sudo gpasswd -a $USER lp
$ sudo gpasswd -a $USER optical

あとはよしなに mpv の設定をする。個人の好みがあると思われるので内容は省略。 カーネルモジュールを読み込む設定をやっているので作業のキリがよいところでマシンを再起動してやる。

RDP でつなぐ

KDE ユーザなので KRDC で繋ぐようにしてみた。適当に設定をして繋ぐ。ただしSoundOn This ComputerPulseAudio を選択してやる必要がある。

xrdp.service がうごいていれば問題なく接続できるはず。 ただしこれだと pulseaudio-module-xrdp をいれているにもかかわらず RDP セッション内からサウンドバイスがみえない。どうしたものか。

RDP セッション内で音を出せるようにする

2日くらい難儀した結果、以下の情報をみつけた:

github.com

これに従い設定をしてみる。まずは以下をやる:

$ systemctl --user mask pulseaudio.service
$ systemctl --user mask pulseaudio.socket

このとき RDP セッション内のターミナルから作業すると Failed to get properties: Process org.freedesktop.systemd1 exited with status といわれて詰むので SSH などの別セッションから作業するとよい。

次にデスクトップ環境側から PulseAudio を起動させるようにする。KDE の場合は以下のようにする:

  1. System Settings を開く
  2. Startup and Shutdown -> Autostart
  3. Add から Add Application を選択
  4. /usr/bin/pulseaudio を実行するよう色々設定する
    • 画面内でコマンドを指定する箇所があるので絶対パスを入れてやればよい
    • Teminal options はとくにいじらなくてよい

ここまでやって RDP セッションを一度落として(単にログアウトすればよい)再度立ち上げると無事に KMix あたりから xrdp sinkxrdp source が見えるようになる。これで RDP を経由して手元の PC から音が出るようになる。

やってみて

X201s に WQHD な解像度に設定したモニタを接続し、全画面で RDP して Blu-ray を再生してみた。

X201s で Blu-ray を再生した場合はほとんど全てのコマが落ちて観れたものではないのだが、RDP 経由だとガクつきがするがまあ我慢すれば観れるかな程度までなんとかなることがわかった。

モニタ解像度を Full HD 程度まで落とせば現実的な快適さで観れるようになるだろう。LAN 的な影響は考慮していない。

リモートデスクトップというものをやってみたい気持ちがずっとあったが、その気持ちをようやく消化できて有意義だった、というところでオチとしておく。

参考

パスワード認証しないで 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) 買った

f:id:aaodsn:20200726212438j:plain
画面は Arch 側で起動させたもの

掲題の買い物をした。友人から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 くらいの速度しかでていない。これも隔世の念がある。


  1. カーネル 5.7.10 で確認

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月下旬だった:

github.com

やることは単純で、

  1. AUR ユーザがもってる PKGBUILD を総浚いする
  2. 総浚いした中で GitHub 上で開発されているものの最新バージョンをチェックする
  3. 2. で確認した最新バージョンが PKGBUILD 上のそれと異なる場合に新バージョンと見做して更新
    • PKGBUILD 更新
    • .SRCINFO(パッケージのメタデータ)更新
    • makepkg -sfmL --noconfirm してちゃんと新バージョンでパッケージが作れるか確認
  4. 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 からノベルティを貰った話

f:id:aaodsn:20191022141203j:plain
DigitalOcean ロゴの向き間違ってた(すみません)

わたしは AUR にいくらか PKGBUILD を公開しており、その中に DigitalOcean (https://www.digitalocean.com/) の CLI ツールである https://aur.archlinux.org/packages/doctl/ というものがある。 upstream はこれ:

ある日こいつが makepkg -sri でビルドするとコケるようになり、doctl 側をみてみたところビルドスクリプトに難があるようだった。 ビルドが通らないと困るので直すことにした。それが以下のプルリク:

中身をみてもらえればわかる通り大した内容ではない。

で、このプルリクのコメント最下にあるように DigitalOcean の中の人から連絡くれというメッセージがきていたのでやりとりをし、いろいろあってノベルティを貰えることになった。

貰ったノベルティが本項目冒頭の写真になる。シャツ1枚にステッカー3枚、握ってストレスをどうこうするやつひとつ。ドイツから遠路はるばる今日到着した。

https://sngsk.infohttps://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 の dependsmakedepends に書かれてるものを 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 -Umkosi.postinst で実行してあげればよい。 また mkosi.buildmakepkg -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.postinstpacman -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 パッケージが依存するパッケージを全部列記してインストールしておくようにしたほうがよい。

実例

  1. https://github.com/nosada/mkosi-files/blob/41302ee69b925ee9b65693122eab59b48d5f456b/guispawn/Makefile#L13-L20 のようにする
  2. https://github.com/nosada/mkosi-files/blob/41302ee69b925ee9b65693122eab59b48d5f456b/guispawn/mkosi.postinst#L12-L14 のようにする
  3. https://github.com/nosada/mkosi-files/blob/41302ee69b925ee9b65693122eab59b48d5f456b/guispawn/mkosi.default.tmpl#L11-L40 のように必要なパッケージを書いておく
  4. こうすると make で AUR パッケージ入りのイメージが生成される

  1. mkosi 中に AUR パッケージをビルドできず挫折したのもこれが原因。ただこれ systemd-nspawn の問題というよりは veth に対しての iptables ルールが原因な気もしている。