VSCodeのRemote SSHでNixOS on WSL2に接続する

TL;DR

  1. flake.nixnixos-vscode-serverを追加
  2. Windows側の$HOME/.vscode/extensions/.../wslDaemon.js内の.push("sh","-c".push("sh","-l","-c"に一括置換

すでにWSLにNixOSがインストールされており、また、Nix Flakesで環境構築済みである前提で話を進めます。ちなみに、NixOS on WSLには以下を使うと楽でした。ありがたい。 github.com

nixos-vscode-server を追加

VSCodeのRemoteSSHでNixOS on WSLに接続を試みても失敗します。どのようなエラーメッセージが出ていたか、手元でメモしておくのを忘れました。

解消のため、以下を追加しましょう。

github.com

手順などは上記のReadme通りです。

VSCodeのwslDaemon.jsを書き換えてNixOSの環境変数が通るようにする

しかし、以下のエラーメッセージを受け取ります。

[2024-03-16 21:57:55.394] Extension version: 0.86.0
[2024-03-16 21:57:55.395] L10N bundle: file:///c%3A/Users/USERNAME/.vscode/extensions/ms-vscode-remote.remote-wsl-0.86.0/l10n/bundle.l10n.ja.json
[2024-03-16 21:57:55.407] authorityHierarchy: wsl+NixOS
[2024-03-16 21:57:55.407] WSL extension activating for a local WSL instance
[2024-03-16 21:57:55.415] Resolving wsl+NixOS, resolveAttempt: 1
[2024-03-16 21:57:55.415] WSL feature installed: true (dll path)
[2024-03-16 21:57:55.415] NodeExecServer run: C:\Windows\System32\wsl.exe --list --verbose
[2024-03-16 21:57:55.575] 5 distros found
[2024-03-16 21:57:55.577] Starting VS Code Server inside WSL (wsl2)
[2024-03-16 21:57:55.577] Windows build: 19045. Multi distro support: available. WSL path support: enabled
[2024-03-16 21:57:55.577] Scriptless setup: false
[2024-03-16 21:57:55.577] No shell environment set or found for current distro.
[2024-03-16 21:57:55.829] WSL daemon log file: 
[2024-03-16 21:57:55.833] Probing if server is already installed: if [ -d ~/.vscode-server/bin/863d2581ecda6849923a2118d93a088b0745d9d6 ]; then printf 'install-found '; fi; if [ -f /etc/alpine-release ]; then printf alpine-; fi; uname -m
[2024-03-16 21:57:55.833] NodeExecServer run: C:\Windows\System32\wsl.exe -d NixOS -e sh -c if [ -d ~/.vscode-server/bin/863d2581ecda6849923a2118d93a088b0745d9d6 ]; then printf 'install-found '; fi; if [ -f /etc/alpine-release ]; then printf alpine-; fi; uname -m
[2024-03-16 21:57:57.677] Unable to detect if server is already installed: Error: Failed to probe if server is already installed: code: Failed to probe if server is already installed: code: 127, <3>WSL (37858) ERROR: CreateProcessParseCommon:748: getpwnam(nixos) failed 5
[2024-03-16 21:57:57.677] /nix/store/032wiarm65zp3bh9ak3dz2sqcr3n8g70-bash-interactive-5.2p26/bin/sh: line 1: uname: command not found
[2024-03-16 21:57:57.677] , 
[2024-03-16 21:57:57.678] NodeExecServer run: C:\Windows\System32\wsl.exe -d NixOS sh -c '"$VSCODE_WSL_EXT_LOCATION/scripts/wslServer.sh" 863d2581ecda6849923a2118d93a088b0745d9d6 stable code-server .vscode-server --host=127.0.0.1 --port=0 --connection-token=3310471485-982298393-618761714-2787472227 --use-host-proxy --without-browser-env-var --disable-websocket-compression --accept-server-license-terms --telemetry-level=all'
[2024-03-16 21:57:57.920] Setting up server environment: Looking for /root/.vscode-server/server-env-setup. Not found.
[2024-03-16 21:57:57.920] WSL version:  NixOS
[2024-03-16 21:57:57.921] <3>WSL (37861) ERROR: CreateProcessParseCommon:748: getpwnam(nixos) failed 5
[2024-03-16 21:57:57.921] /mnt/c/Users/USERNAME/.vscode/extensions/ms-vscode-remote.remote-wsl-0.86.0/scripts/wslServer.sh: line 28: uname: command not found
[2024-03-16 21:57:57.921] /mnt/c/Users/USERNAME/.vscode/extensions/ms-vscode-remote.remote-wsl-0.86.0/scripts/wslServer.sh: line 32: dirname: command not found
[2024-03-16 21:57:57.921] /mnt/c/Users/USERNAME/.vscode/extensions/ms-vscode-remote.remote-wsl-0.86.0/scripts/wslServer.sh: line 32: /wslDownload.sh: No such file or directory
[2024-03-16 21:57:57.921] スタートアップの問題のヘルプについては、https://code.visualstudio.com/docs/remote/troubleshooting#_wsl-tips にアクセスしてください
[2024-03-16 21:58:08.179] Download in background is enabled

パスが見つからないと言われます。それを解消するためにnixos-vscode-serverを導入したつもりでしたが、こまった。

https://nixos.wiki/wiki/Visual_Studio_Code#Remote_WSL ここを読むと、なんだかうまく参照できていなさそうなことがわかります。

Similar to SSH hosts, both nix-vscode-server and nix-ld solution allows a VSCode Windows client to connect a NixOS-WSL host. However, by default the VSCode Windows client uses wsl.exe --exec to start the code server, which bypasses NixOS environment variables required by nix-ld, resulting in failures.

とりあえず、当該の章にあるように、$HOME\.vscode\extensions\...\wslDaemon.js内の.push("sh","-c".push("sh","-l","-c"に置換します。力技です。2箇所ありました。

そして再度Remote SSHを試すと、無事に繋がりました。

NixOSでバイナリファイルを参照するときのつらみをあまり理解できていないので、また今度読みます。 blog.thalheim.io

NixOS on WSLを立ち上げると、rootユーザーでログインしてしまう

ところで、NixOS on WSLだとrootユーザーでログインしてしまう問題があります。以下のようなエラーメッセージを毎回受け取ることになっています。

<3>WSL (10563) ERROR: CreateProcessParseCommon:748: getpwnam(nixos) failed 5

discourse.nixos.org

ググると上記のディスカッションを発見しましたが、これだ!という解決策は見当たりませんでした。この件については、ログインするたびに su <username>で切り替えることで対応することにしました。

NixOS + home-manager で環境構築した覚書

盆栽置き場 github.com


自宅外でコード書く必要が出たので、中古でレッツノートLX6(Core i7, 16GB, US配列)を買いました。これで手元のPCは全部で5台です。

Windowsでの開発ならWSL2上でubuntu環境を立てるのですが、メモリ16GBだと動作速度に少々不安があります。なので、もともと入っているWindows10は潰して何かしらのLinuxディストリビューションを入れようと考えました。

それはいいのですが、毎回毎回あたらしいPCが手元にくるたびに、同じような手順を踏んで環境構築するのは流石に面倒になってきました。特にLinuxディストリビューションで日本語まわりの設定をするのは非常に面倒です。面倒なので2年ほど日本語化せずに使い続けているPCがあります。

どうしようかと思案しているとき、少し前にNixOSで最強のLinuxデスクトップを作ろうという記事を読んだのを思い出しました。

NixOSは、純粋関数型パッケージマネージャであるNixをベースにしたLinuxディストリビューションです。NixOSではなんと環境構築を完全に宣言的に行うことができます。つまり、望む環境の状態をコードで記述してNixOSに処理させることで、自動的にパッケージのインストールやシステムの設定などを行ってくれるのです。

かっこいい~

Nix環世界

あちこち記事を読んでみて、Nixまわりを以下のように理解しました。

NixとはUnix環境向けのパッケージマネージャ + ビルドツールのことであり、また、このシステムのための純粋関数型言語の名称でもあります。Nixで取り扱えるパッケージは、Nixpkgsというパッケージリポジトリ上に集められています。

NixOSは、言語設定、キーボードレイアウト、ブートオプションなど、OSの設定管理にNixを採用しているLinuxディストリビューションです。この、システム設定をNixで記述し管理できる仕組みをNixOS modulesと呼びます。

NixOS modulesの古典的な設定方法は/etc/nixos/configuration.nixファイルに記述していくことです。しかし、この方法にはデータソースがnix-channelに依存してしまうこと、バージョンロックの仕組みがないことの2点により、再現性を担保できないという問題がありました。

そのため、NixOS modulesを管理するための機能として、2021年にFlakesが実験的に追加されました。これはpackage.jsonCargo.tomlのようなもので、flake.nixに依存関係や各種設定を記述していきます。2024年3月現在、このFlakesを用いた環境構築が一般的なようです。

NixOS modulesはシステムの環境構築に重きを置いており、ユーザーの環境構築を行うには少し物足りない部分があります。そのため、home-managerというnix-community製のユーザー環境構築ツールがあります。NixOS modulesはもちろんNixOSの機能ですが、こちらのhome-managerはNixOSに限らず、どのプラットフォームでも導入することができます。母艦はNixOS + home-managerで環境を作っておき、サブや仕事用の環境はMacOS + home-manager、ということもできます。

NixOSのインストール、Flakeとhome-managerの有効化

NixOSで最強のLinuxデスクトップを作ろう

特筆することはなく、上述の記事の手順通りに進めればすべてがうまくいきます。 そのうえでいくつか。

設定のモジュール化

設定ファイルは時間の経過とともに秘伝のタレのようになっていくことが予想されるので、早めにディレクトリを切るなり、共通化できそうなところはまとめておくなりしておくとよさそうです。 このあたりはNixOS & Flakes Book の Modularize Your NixOS Configuration の章が参考になります。

github.com mitchellh 氏のflake.nixを眺めていると、MBPのとき、WSLのとき…と、設定ファイルを出し分けしていてスマートです。

Git 管理している場合、flakes は作業ツリーのファイルのみを参照してビルドする

For flakes in git repos, only files in the working tree will be copied to the store. Flakes - NixOS Wiki

あたらしいファイルやディレクトリを作成してビルドするとき、git add .して作業ツリーに上げるのを忘れるとファイルを認識してくれないのでうまく動きません。これを忘れていたため、「なぜかフォルダが無いって言われてる…」と1時間つぶしてしまいました。

ビルドコマンドを忘れるのでそのメモ

NixOSのビルド

sudo nixos-rebuild switch --flake .#hostname

home-managerのビルド

rm flake.lock
git add .
nix run nixpkgs#home-manager -- switch --flake .#username@hostname

追記:2024/03/11

nixos-and-flakes.thiscute.world

コマンド簡略化のためにjustを使うといいと書いてある。

nixos-and-flakes.thiscute.world

NeovimやZshの設定を変更したら、再ビルドしないといけない…めんどうだ…と思ったら、こちらもソリューションが提示されている。


home-managerは、令和版dotfiles盆栽という趣を感じます。形式がバラバラだったソフトウェアの設定をNix言語で統一して書けるというのは嬉しいかもしれません。Nix言語で書くといっても、こまごまとした設定はJSONみたいな書き味なので分かりやすくていいですね。

コマンドを叩いてあれこれ設定していくのがどうにも苦手だったので、NixOS modulesのように設定ファイルに記述していくだけで済むというのはとても楽です。

Nix、いいですね。

趣味の時間を夜につくるから眠れなくなる

この一ヶ月で21時半就寝5時起床の生活リズムが定着してきました。

一ヶ月に一度は徹夜をしてそのまま昼夜逆転したり、起きる時間は9時以降…自分のことを夜型だと思いながら四半世紀以上生きてきましたが、そんなことはなかったみたいです。長年変わらなかった不健康な生活リズムを、本当に単純なことで変えることができました。

起きる→仕事→趣味の時間→寝る

これを、

起きる→趣味の時間→仕事→寝る

こうしました。

学生時代のころからずっとそうですが、夜ご飯を食べ終わってから寝るまでの時間を趣味の時間にあてていました。そうするとだいたい、趣味に没頭して「寝る時間がもったいないモード」になってしまって睡眠時間はずるずると後ろ倒しになっていきます。無理やり切り上げて布団に入っても、交感神経優位なので目はバチバチに覚めており、まったく眠れません。

楽しいんですけどね。でも、この生活を続けていると、睡眠時間がじわじわと足りなくなっていき、知らない間にメンタルが不調になっていきます。なりました。

なので、「寝る時間がもったいないモード」が起動する前にさっさと寝てしまう。風呂に入ったあとはパソコンの前などに向かわず、速やかに布団に入る。「早起きしてやりたいことをやるぞ~」という希望を胸に眠りにつくと、つらいはずの朝もサクッと起きられます。寝続けたら楽しい趣味の時間がなくなってしまうので…。

問題は、夜に友達とゲームをしたり、酒を飲んだり、そういうことがまったくできないことでしょうか。とはいえメンタルも大事なので悩ましいところ。週末くらいは夜に遊ぶことを許容して、うまくバランスを取っていきたいですね。

AtCoderの第1回マスターズ選手権予選にビジュアライザー担当として出ました

atcoder.jp 上のコンテストに『ふくろうさんチーム』のビジュアライザー担当として出ました。

昨年末にチームメンバーを募集していて、ビジュアライザーのみでも、とのことだったので好奇心で手を上げてみました。 ヒューリスティクスコンテストに馴染みが無いので、そもそもビジュアライザーって何、という感じでしたが、解法がいい感じだといい感じの動きをするので気分がいいやつだな…というざっくりとした理解をしました。

コンテスト中に作ったのはこちら(動く)。 Heuristic Contest Visualizer

ビジュアライザー

開始から2時間経過くらいで最低限動くものをデプロイして、残りはチームメイトの考察をふんふん聞きながらクエリ文(直前の操作)を表示させたり、壁を表示させるべく奮闘したりしていました(だめだった)。壁を表示できていたら異常テストケースを確認することができてよかっただろうに…チームメイトには心の目で見てもらいました。感謝しかない。

ちなみに、ビジュアライザー担当として手を上げたのに、予選一週間前までろくすっぽビジュアライザーを作れない状態でした。本当にすみません。そこから毎朝4時半に起きて2時間半のビジュアライザ筋トレをし、なんとかなりました。

ビジュアライザーを作るにあたっては以下の記事とテンプレートにとてもお世話になりました。本当にありがとうございます。

github.com yunix-kyopro.hatenablog.com zenn.dev

普段の業務や個人開発では、TypeScript(React, Vue)しか触らないので、Rust!?WebAssembly!?という感じで混迷を極めていましたが、本当になんとかなってよかった。 ちゃんと作れた…という安心感と、あとは普段さわらない技術を学べたことで好奇心が満たされてとても満足です。もっとRustと仲良くなりたいという気持ち。


そんなこんなで、チームメイトの健闘によって21位になり、決勝に進むことができるそうです。がんばりたい。

ところで、SVGを1万個描画するとブラウザがそこそこ重かったり、そもそもSVGだと微妙に表示の融通が利かないなど色々と不便したので、ビジュアライズ部分の構成を Wasm + Rust + WebGL にしたいなあとか考えています。 シェーダーの素振りをやっていくつもりですが、なんもわからんになったらThree.jsに逃げようかな。三次元がきても安心。

20240225

最近考えていること

ソースコードを読むとき

  • 関数名、引数と返り値の型の3つを見たときに想起される処理と、実際に書かれている処理が食い違う時に苦しみがある
  • どっちでもいいことは「どっちでもいいな」と思えるようになった
    • 変数名の型は定義を書くのか、型推論に任せるのか、とか

数値目標を意識しながらの行動はつらい

  • 「目標」から遠ざかったときの苦しみがある
  • 「3kg痩せるために走る」→「走ってるのに体重増えた、もうだめや…」→嫌になる
  • 「できるだけ毎日走ろう」→「体重増えたけど、まあ走ってたらいいやろ」→続けられる

数値目標は「*kg落とすこと」だけれど、「毎日走る習慣をつける」という目標を立てたことで、いまのところ一ヶ月程度続けられている。 体重は落ちてない。けど、毎日走れてるから全然OK。

SNS見るのやめたらメンタルが強くなった気がするし時間も増えた

SNSは「交流したい」というモチベーションが無いときに見ると終わる。