NixOSでmatplotlibを使いグラフを表示する - uvを使う & 共有ライブラリとoverlayの話

要約 ここではNixOSとPythonとmatplotlibでグラフを出力するための方法を記載する。 グラフを表示するケースとして以下の2つのケースを考える。 (パターン1)NixだけでPythonのパッケージ管理をする方法 (パターン2)astral-sh/uvでPythonのパッケージ管理をする方法 前者はあっさり終わるが、後者はすんなり動かないので工夫が必要。具体的には以下の工夫がいる。 共有ライブラリのパスが解決できずエラーになる: uvが外部から持ってきたライブラリにプリコンパイルされたCの共有ライブラリファイルがあるため。LD_LIBRARY_PATH の指定をする必要がある tkinterのモジュールが解決できず、グラフが出力されない:nixpkgsに入っているPythonのデフォルトにはtkinterがついてないため。overlayとoverrideを使い、tkinter入りのPythonを用意する NixOSでほかのLinuxディストリビューションと同じようなことをしようとするとひと手間必要という良い例かも。 なお、今回紹介するのはあくまで NixOS 上での例である。例えばNixOSでないほかのOSでNixパッケージマネージャだけ導入しているようなケースでは、(環境によるが)パターン2は特に工夫なく動くかもしれない。 また、今回使うuvは0.4.8である。uvは開発が早いので、数か月後にはこの記事通りに動かなくなってるかも。 1 2 [bombrary@nixos:~/example]$ uv --version uv 0.4.8 (パターン1)Nixを用いたパッケージ管理例 はじめに、flake.nix ファイルを作る。 1 2 [bombrary@nixos:~/example]$ nix flake init wrote: /home/bombrary/example/flake.nix 以下のような flake.nix を書く。python.withPackagesを使うことで、特定のパッケージが入ったPythonを作ることができる(イメージ的には、venvと同じものを /nix/store/ で管理する感じ)。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 { description = "A very basic flake"; inputs = { nixpkgs....

2024-09-16 · (updated 2024-09-16) · 8 min · 1533 words

HugoのテーマをPaperModに変えた

今のシンプルなままでも良い気がしたが、シンプルさはそのままでもう少しだけリッチなサイトに改築してみたくなったので、それっぽいテーマを探してそちらに引っ越してみた。 移行先のテーマは PaperMod。 before と after before after やったこと PaperMod導入 PaperModのInstallationに従う。 いくつかやり方が紹介されているが、自分はsubmoduleを使ってPaperModを持ってきた。 1 git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod config.tomlの修正 PaperModのWikiを参考にすればどんな設定をすればよいのかがわかる。Wikiはyamlで書かれているが、ブログ解説当初はtomlで書いていたため、tomlに読み替えて進めた。 また、Wikiからうまく見つけられない情報があった場合は、直接PaperModの layouts ディレクトリをgrepしてそれっぽい変数が無いか探した。 searchページとarchiveページ searchページとarchiveページはそれぞれ次の項目を参考にした。 Archives Layout Search Page searchとarchiveのリンクをヘッダーに追加したいなら、次のように config.toml に書けばよい(参考:Add menu to site)。 1 2 3 4 5 6 7 8 9 10 11 [[menu.main]] identifier = "tags" name = "Tags" url = "/tags/" weight = 20 [[menu.main]] identifier = "archives" name = "Archive" url = "/archives/" weight = 30 ファイルの移動 ブログ用に書いていたCSSやKaTeXの設定を移す必要があった。...

2024-05-19 · (updated 2024-05-19) · 1 min · 202 words

Nix用いたツール実行・開発環境の構築方法

要約 この記事では、Pythonでいうvirtualenv的なことをする方法について述べる。つまり、ツールを一時的に導入したり、ツールが実行可能な開発環境を整備したりする目的として、以下の話題を扱う。 各種コマンド nix shell nix run nix develop direnv + nix-direnv nix flake init にtemplateを指定する方法 なお本記事ではNixOS固有の話ではなく、(パッケージマネージャとしての)Nixを使う場合の話をする。使用するNixとhome-managerのバージョンは以下の通り。 1 2 3 4 ~ $ nix --version nix (Nix) 2.18.1 ~ $ home-manager --version 24.05-pre はじめに Nixではユーザ環境にパッケージを入れるために、以下の2つのどちらかを使うはず(宣言的に管理できる後者がよりデファクトになっている気がする)。 nix-env home-manager これらは永続的にパッケージを導入する仕組みであるが、そうではなく一時的にパッケージを導入したいという場合があるだろう。具体的には、以下の2つの場合がありえる。 あるツールを使いたいが、別に永続的にそれを使う必要はない。試しに使ってみたい場合は、ある瞬間にそれが使えれば十分 virtualenvみたいに、開発時のみに特定のバージョンの開発ツールが導入されている状態であってほしい 前者の場合、nix shell、nix runコマンドを用いる。後者の場合、nix developコマンドを用いる。 nix shellコマンド nix shell コマンドを用いると、一時的にパッケージを導入して新しいshellに入ることができる。 以下のように使うと、パッケージを導入した状態で新しいshellに入る。パッケージは複数指定が可能。 1 nix shell (package name) (package name) ... 以下は、nix shell コマンドを用いてgccを使える状態にする例。 1 2 3 4 5 6 ~ $ nix shell nixpkgs#gcc ~ $ gcc --version gcc (GCC) 13....

2024-05-13 · (updated 2024-07-20) · 9 min · 1832 words

Nixでハッシュ関係の処理をPythonで実装してみる

前回の記事でstore pathを手で計算する方法を見てきたが、output hashの計算については手で計算するのが無理だった。これをPythonスクリプトで実装するとどうなるかをやってみた。 ゴールとしてはoutput hashを計算するコードを実装することであるが、 Nix32表現の計算とtruncateオプションの計算はそれにあたって必要なので実装した おまけでderivation hashとsource hashの計算も実装した なお、今回のコードについて Nix 2.21.1を参考に作っている すべてのパターンは網羅できていない可能性が高い(特にoutput hashの計算方法) Nixのいくつかの処理をPythonで実装してみるのコードを一部使って実装する である。また、コードの実行例にあたって、前回の記事のderivationの準備にしたがってsampleのderivationが準備されているものとする。 Nix32表現の計算 Nix32の計算はlibutil/hash.ccで行われている。 以下の並びのビット列があるとする(見やすさのため8bitごとに縦棒で区切ってある)。 1 b07 b06 b05 b04 b03 b02 b01 b00 | b15 b14 b13 b12 b11 b10 b09 b08 | b23 b22 b21 b20 b19 b18 b17 b16 | ... Nix32表現では、以下のように5bitずつ取り出していく。 1 2 3 4 5 b04 b03 b02 b01 b00 b09 b08 | b07 b06 b05 b14 b13 b12 b11 b10 b19 b18 b17 b16 | b15 ....

2024-04-21 · (updated 2024-04-21) · 3 min · 622 words

Nixのstore path計算方法メモ

Nixでは、パッケージの再現性を担保するために、/nix/store/下にハッシュ値を含んだ名前であらゆるファイルを保管する。そのハッシュ値がどのような情報から計算されるものなのかを知っておくことは、なぜNixが再現性を確保できるのかを考える上で重要である。 そこで、この記事では、Nixのstore path、つまりその中に含まれるハッシュの計算方法について解説し、実際にステップバイステップで計算してみる。 参考記事 How Nix Isntantiation Works (Web Archive) Nix manual(unstable)Store Pathの仕様 Nix PillsのChapter 18 なお、本記事では nix derivation show コマンドの結果からいろいろと情報を取り出すために jq を用いる。 store pathの種類 ほとんどStore Pathの書き起こしみたいになってしまうが書いておく。 まずstore pathは、/nix/store/<digest>-<name>の形式を持っている。 <digest>というのは、fingerprint(後述)をSHA256でハッシュ化し、160bitに圧縮したうえでNix32表現にしたもの。ドキュメントには「SHA256の先頭160bitをBase32表現にしたもの」と記載があるが、 Base32という言葉はRelease Note 2.20でNix32という名前に改められた。理由としては通常の意味のBase32表現とは処理が異なり紛らわしいためのようだ 先頭160bitを単純に切り取ってNix32表現にするのではなく、実装では complressHash という関数で圧縮処理が行われている(該当ソース)。 fingerprintは、<type>:sha256:<inner-digest>:/nix/store:<name>の形式 <type>というのは以下のいずれか text:<input store path>:<input store path>:...:derivation。<input store path>には、(存在すれば)derivationが参照する他のファイルのパスを指定する source:<input store path>:<input store path>:...:外部から持ってきたファイルをNAR形式でアーカイブ化したもの sourceがinput store pathを持つケースってどんなときなの?と感じるが、確かにlibstore/store-api.ccにそれっぽいコードが見つかる。しかし実例がまだ良くわかっていない…。 output:<id>:derivationからビルドされたもの、もしくはビルド予定のものを表す。<id>には通常outが入るが、ビルド出力結果を複数分けているようなパッケージではbinやlib、devなどが指定されうる。 <inner-digest>は、inner-fingerprintをSHA256でハッシュ化し、Base16表現にしたもの inner-fingerprintの計算方法は、上述のtypeによって異なるが、これは後々実際に計算してみつつ解説する いろいろと書いてあるが、結局/nix/store下におかれるパスの種類は実質fingerprintの種類であり、すなわち3種類である。 text:derivationを表す source:ビルドに必要なファイル、ソースコードを表す output:ビルド生成物そのもの、ないしディレクトリを表す (前準備)derivationの準備 今回手で計算するもととなるderivationを簡単に書く。 Nix PillsのChapter 7の内容をもとに。汎用性とかは意識せず、x86_64-linux前提で書く ただNix Pillsをそのまま書き起こしになってしまうのもつまらないので、flakeを使って書いてみる。 まずいくつかのファイルを作成する flake.nix:flakeファイル default.nix で分けないで、ここに直接derivationを書く mubuilder....

2024-04-20 · (updated 2024-04-21) · 7 min · 1462 words

Nixのいくつかの処理をPythonで実装してみる

Nixのパッケージ・derivationの探り方まとめにて色々なコマンドを紹介したが、それらがNix内部でどう処理されているのかを知りたくなり、その過程でPython実装を書いた。 目的は、以下の2つの処理をPythonで実装することである。 build dependenciesを(間接的なものも含め)出力する runtime dependenciesを(間接的なものも含め)出力する なお、公式ではどちらもnix-store --query --requisitesないしnix-store --query --treeで出力可能である。 (parse) drvファイルを読み込み、パースする この先の処理を実装するにあたって、drvから情報を取り出す必要があるので、ここでパーサーを実装する。 まずdrvのファイル形式は以下のようなものであった。見やすいように改行を挟んでいるが、実際には無い。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 bombrary@nixos:~$ nix derivation show `which ls` | jq -r 'to_entries[]....

2024-04-05 · (updated 2024-04-16) · 12 min · 2475 words

Nixのパッケージ・derivationの探り方まとめ

Nixで、あるパッケージがどのパッケージに依存しているのかを調べたくなったのを発端に、パッケージやその依存関係の調べ方についていろいろ調べた。 要約 アプリ・ツールがどのパッケージに収録されているのかを知る NixOS Search や nix search コマンドを使う which や realpath コマンドから /nix/store 下のディレクトリがわかるのでそこからパッケージ名を知る nix-index、 nix-index-databaseを使う derivationの詳細を知る: nix derivation show [drv or output] output ⇔ derivation outputがどのderivationでビルドされたのかを知る: niq-store --query --deriver [output] derivationのoutputを知る: nix-store --query --outputs [drv] derivationについて build dependenciesを知る: nix-store --query --references [drv] 間接的なbuild dependenciesもすべて知る: nix-store --query --requisites [drv] outputについて runtime dependenciesを知る: nix-store --query --references [output] 間接的なruntime dependenciesもすべて知る: nix-store --query --requisites [output] 前置き 用語解説 いろいろとNix固有(?)の言葉が出てくるため、ここでまとめて解説しておく。 GlossaryとNix Pills Chapter9を参考にする。 パッケージ:ファイルやデータの集まり。 derivation:何らかのビルドタスクを行うための記述書。端的にはパッケージを作るための仕様書である。次の節で詳しく述べる output:derivationから生成されたもの store object:Nixによって管理されているあらゆるオブジェクトをさす。通常は/nix/store/に保管されているはず store path:store objectが置かれている場所。通常は/nix/store/にあるはず build depencencies:ビルドの時点で必要になる依存関係。ビルドに必要なソースコードや、derivationの中で参照されている別のderivationを指す。これはderivationに記載されている runtime dependencies:実行時に必要になる依存関係。動的ライブラリや、ほかのパッケージの実行ファイルなどを指す これを検出する方法は素朴で、生成したパッケージをNAR形式で固め、そこに埋め込まれているoutputのパスがruntime dependenciesと判定するだけである NAR (Nix Archive):tarのように複数ファイルを1つのファイルに固めた形式。ただし、同じアーカイブ対象であればまったく同じNARファイルができるように、tarに比べてシンプルなつくりになっている。例えば、tarだとアーカイブする度にタイムスタンプ(mtimeフィールド)が埋め込まれるが、NARにはそれがない(参考) NARが作られた背景について、edolstra氏のPh....

2024-04-04 · (updated 2024-09-17) · 6 min · 1098 words

Nixの外でビルドされた実行バイナリをNixOSで動かす

更新内容 2024/09/14 記事の内容を整理した。もともとRyeを使う際に詰まった記録を記事にしたものだったが、あまりにRye依存になる記述が多かったので、python-build-standaloneを例とした内容に置き換えた。 Ryeのときの話はRyeをNixOS上で動かそうとしたときの記録(2024年2月)に移動した。 前置き NixOSはNixOSの内側で生活するには十分快適だが、その外で作成されたソフトウェアを持ってこようとすると、途端にめんどくさくなる。その例として 動的リンカのパスが解決できず実行バイナリが動かない shebangのパスが解決できずシェルスクリプトが実行できない が挙げられるが、今回は前者の話をする。その解決方法としてpatchelfとnix-ldがあるのでそれを紹介する(後者はenvfsで解決可能だが、もしかしたら後日記事にまとめるかも) この件についてはすでにZennでまとめてくださっている人がいる(参考:NixOS に関する小ネタ集)し、なんならnix-ldの製作者のブログでほぼ同じ内容の記事を書かれていた。が、今一度自分も整理のため、具体的にぶち当たった事例も含めて書いておこうと思う。 要約 nix-ldを導入すれば、NixOS外の実行バイナリが動くようになる 共有ライブラリが足りないなどのエラーが出た場合は、LD_LIBRARY_PATHを指定する nix developで上記環境変数が設定されるようにnixファイルを書いたほうが良い python-build-standaloneがNixOS上で動かせないことの確認 ここでは、外部でビルドされたpythonであるpython-build-standaloneをNixOS上で動かそうとしてみよう。なおpythonはnixpkgsから入手可能であり、通常利用の場合はわざわざ外部からビルド済みのpythonを持ってくる必要はないのだが、今回は例のためにこれを実行することを考える。 pythonのstandaloneをDLしてくる。 1 2 3 4 5 6 7 8 9 10 11 [bombrary@nixos:~]$ curl -LO https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.12.1+20240107-x86_64-unknown-linux-gnu-install_only.tar.gz % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 64.6M 100 64.6M 0 0 17....

2024-02-18 · (updated 2024-09-14) · 6 min · 1276 words

RyeをNixOS上で動かそうとしたときの記録(2024年2月)

更新内容 2024/09/14 これは2024年2月ごろにNixOS上でRyeを動かそうと悪戦苦闘したときの記録である。現在だと uv の登場でいろいろ変わっており、この記事の内容が再現しない可能性が高いので注意。 要約 NixOS外でビルドされたたいていのバイナリはリンカのパスが /lib/ や /lib64/ が前提であるようになっているが、NixOSにはこれがないのでそのままでは動かない 解決策としては以下のようになる nix-ldを導入する 共有ライブラリが足りないなどのエラーが出た場合は、LD_LIBRARY_PATHを指定する それでもうまく動かない場合はあるので、できればNix外のバイナリを使うのは避けたい 経緯 Pythonのプロジェクト管理ツールであるRyeを使いたくなった(もちろんNixOSを使っているんだからRyeを使わず全部nixファイルで管理しろ、と言われればその通りなのだが、手軽にパッケージや仮想環境を管理できるところに惹かれて使ってみたくなった) Ryeはまだ盛んに開発されており、まだまだ今後変わりうる可能性があるが、現バージョン(0.24.0)で試しに使ってみよう。nixの場合、以下のコマンドで一時的にRyeを入れて実行可能だ。 1 nix run nixpkgs#rye プロンプトに従って進めていく。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [bombrary@nixos:~/python/bin]$ nix run nixpkgs#rye Welcome to Rye! Rye has detected that it's not installed on this computer yet and automatically started the installer for you. For more information read https://rye-up....

2024-02-18 · (updated 2024-09-14) · 12 min · 2414 words

NixOS & Home Managerのセットアップメモ

NixOS 23.11をセットアップした時のメモ。 目標 NixOS環境については以前構築したことがあるが、勉強のためもう一度一から構築する 今後、NixOSの環境をすぐに構築できるような設定ファイル、リポジトリを作る なるべくNix Flakesを使う NixOSの設定ファイルはNix言語で記述するが、自由度が結構高くて、どうファイル分け、ディレクトリ分けをしていくのかが悩ましい。 今回はWikiの紹介されていたdotfilesリポジトリを参考にしようと思う。 とはいえ、まだまだNixOSの初学者のため、小さな部分を少し真似して作っていく。 インストールディスクの起動 Download Nixのページ下部にある「NixOS the Linux distributeion」からISOイメージをダウンロードしてくる。 ダウンロードリンクとして、Graphical ISO ImageとMinimal ISO Imageがあるが、今回は後者でやる。 Graphical ISO Imageも一度試したが、ウィザード形式で設定をポチポチ進めるだけで設定が出来上がるので分かりやすい。おそらく初学者はこれで作成された configuration.nix を眺めて、少しずつ設定を理解していくのがよいのだと思う。 Minimal ISO Imageはコンソールでインストール作業を行う。パーティションを分けたり、ファイルシステムを作ったりするのは自分でやることになる。今回は勉強のためにこれでやる。 作業の大枠はNixOS 23.11 manualに乗っているのでそれに従う。 自分の環境の場合は、ESXiの入ったPCがあるので、コンテンツライブラリにそれをアップロードし、仮想マシン作成の時にそれをCDデバイスとしてセットする 物理HWに入れる場合、ISOイメージをUSBやCDに焼いておき、起動する 起動すると次の画面になるので、一番上を選択してEnterする。 SSH接続できるようにする しばらくすると以下の画面になる。 文章を読むと、 To log in over ssh you must set a password for ether “nixos” or “root” with passwd (prefix with sudo for “root”), or … と親切にもSSHへの入り方のガイドが示されている。証跡を残すためには画像よりもテキストの方が取りやすいため、SSHで作業することにする。なお、このままコンソール上で作業する場合、loadkeys でキーボードのレイアウトを変えないと記号が思った通りに打てないので注意。 ガイド通り、パスワードを変える。 SSHで入るためには、もちろんSSHで接続しに行く側との疎通ができないといけない。これは環境によって様々。 有線の場合 DHCP有効の場合:すでにIPアドレスが取得できている状態だと思う。ip a で確認可能 journalctl -xe を見るとわかるが、どうやら dhcpcd が動いている模様 DHCP無効の場合:ip a addなりifconfigなりでIPアドレスを手動設定する 無線の場合:wpa_supplicantを使った方法で接続できるっぽいので、これを試せばよいと思う 自分の環境の場合は、VM作成時にNICをつけたし、ルータのDHCPも有効なのですでにIPアドレスが取得できている状態だった。なのでそのままログインできる。...

2024-02-11 · (updated 2024-04-20) · 12 min · 2536 words