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[].key' | xargs cat Derive( [("debug","/nix/store/b073nwng2fy24zaqbdx6zbimxkad7dyk-coreutils-full-9.3-debug","",""), ("info","/nix/store/1pd076gkjwh0wdv8cnxy6p7kl141jnk2-coreutils-full-9.3-info","",""), ("out","/nix/store/03167shkax5dxclnv6r3sd8waa6lq7ny-coreutils-full-9.3","","")], [("/nix/store/5q67fxm276bdp87jpmckvz3n81akw6a5-perl-5.38.2.drv",["out"]), ("/nix/store/98sv0g544bqmks49d6vgylbkh9sccdvm-attr-2.5.1.drv",["dev"]), ("/nix/store/9jcfzyyb0h86mvc31s9qmxs6lncqrwhc-acl-2.3.1.drv",["dev"]), ("/nix/store/akpwym6q116hivciyq2vqj9n5jk9f5i6-xz-5.4.4.drv",["bin"]), ("/nix/store/d1qldhg6iix84bqncbzml2a1nw8p95bg-gmp-with-cxx-6.3.0.drv",["dev"]), ("/nix/store/ks5ivc59k57kwii93qlsfgcx2a7xma1k-autoreconf-hook.drv",["out"]), ("/nix/store/mnrjvk62d35v8514kc5w31fg3py0smr8-coreutils-9.3.tar.xz.drv",["out"]), ("/nix/store/mvvhw7jrrr8wnjihpalw4s3y3g7jihgw-stdenv-linux.drv",["out"]), ("/nix/store/szciaprmwb7kdj7zv1b56midf7jfkjnw-bash-5.2-p15.drv",["out"]), ("/nix/store/wd100hlzyh5w9zkfljkaagp87b7h7733-openssl-3.0.12.drv",["dev"])], ["/nix/store/1cwqp9msvi5z8517czfl88dd42yhrdwg-separate-debug-info.sh", "/nix/store/v6x3cs394jgqfbi0a42pam708flxaphh-default-builder.sh"], "x86_64-linux", "/nix/store/7dpxg7ki7g8ynkdwcqf493p2x8divb4i-bash-5.2-p15/bin/bash", ["-e","/nix/store/v6x3cs394jgqfbi0a42pam708flxaphh-default-builder.sh"], [("FORCE_UNSAFE_CONFIGURE",""), ("NIX_CFLAGS_COMPILE",""), ("NIX_LDFLAGS",""), ("__structuredAttrs",""), ("buildInputs","/nix/store/hwb08pf2byl2a1rnmaxq56f389h6b6yn-acl-2.3.1-dev /nix/store/djciacxl96yr2wd02lcxyn8z046fzrqr-attr-2.5.1-dev /nix/store/1fszsmhmlhbi4yzl2wgi08cfw0dng7pq-gmp-with-cxx-6.3.0-dev /nix/store/2d8yhfx7f2crn8scyzdk6dg3lw7y1ifh-openssl-3.0.12-dev"), ("builder","/nix/store/7dpxg7ki7g8ynkdwcqf493p2x8divb4i-bash-5.2-p15/bin/bash"), ("cmakeFlags",""), ("configureFlags","--with-packager=https://nixos.org --enable-single-binary=symlinks --with-openssl gl_cv_have_proc_uptime=yes"), ("debug","/nix/store/b073nwng2fy24zaqbdx6zbimxkad7dyk-coreutils-full-9.3-debug"), ("depsBuildBuild",""), ("depsBuildBuildPropagated",""), ("depsBuildTarget",""), ("depsBuildTargetPropagated",""), ("depsHostHost",""), ("depsHostHostPropagated",""), ("depsTargetTarget",""), ("depsTargetTargetPropagated",""), ("doCheck","1"), ("doInstallCheck",""), ("enableParallelBuilding","1"), ("enableParallelChecking","1"), ("enableParallelInstalling","1"), ("info","/nix/store/1pd076gkjwh0wdv8cnxy6p7kl141jnk2-coreutils-full-9.3-info"), ("mesonFlags",""), ("name","coreutils-full-9.3"), ("nativeBuildInputs","/nix/store/nsl35d8x8jp0vy8n4xy8sx9v68gdh444-autoreconf-hook /nix/store/rza0ib08brnkwx75n7rncyjq97j76ris-perl-5.38.2 /nix/store/3q6fnwcm677l1q60vkhcf9m1gxhv83jm-xz-5.4.4-bin /nix/store/1cwqp9msvi5z8517czfl88dd42yhrdwg-separate-debug-info.sh"), ("out","/nix/store/03167shkax5dxclnv6r3sd8waa6lq7ny-coreutils-full-9.3"), ("outputs","out info debug"), ("patches",""), ("pname","coreutils-full"), ("postInstall",""), ("postPatch","# The test tends to fail on btrfs, f2fs and maybe other unusual filesystems.\nsed '2i echo Skipping dd sparse test && exit 77' -i ./tests/dd/sparse.sh\nsed '2i echo Skipping du threshold test && exit 77' -i ./tests/du/threshold.sh\nsed '2i echo Skipping cp reflink-auto test && exit 77' -i ./tests/cp/reflink-auto.sh\nsed '2i echo Skipping cp sparse test && exit 77' -i ./tests/cp/sparse.sh\nsed '2i echo Skipping rm deep-2 test && exit 77' -i ./tests/rm/deep-2.sh\nsed '2i echo Skipping du long-from-unreadable test && exit 77' -i ./tests/du/long-from-unreadable.sh\n\n# Some target platforms, especially when building inside a container have\n# issues with the inotify test.\nsed '2i echo Skipping tail inotify dir recreate test && exit 77' -i ./tests/tail-2/inotify-dir-recreate.sh\n\n# sandbox does not allow setgid\nsed '2i echo Skipping chmod setgid test && exit 77' -i ./tests/chmod/setgid.sh\nsubstituteInPlace ./tests/install/install-C.sh \\\n --replace 'mode3=2755' 'mode3=1755'\n\n# Fails on systems with a rootfs. Looks like a bug in the test, see\n# https://lists.gnu.org/archive/html/bug-coreutils/2019-12/msg00000.html\nsed '2i print \"Skipping df skip-rootfs test\"; exit 77' -i ./tests/df/skip-rootfs.sh\n\n# these tests fail in the unprivileged nix sandbox (without nix-daemon) as we break posix assumptions\nfor f in ./tests/chgrp/{basic.sh,recurse.sh,default-no-deref.sh,no-x.sh,posix-H.sh}; do\n sed '2i echo Skipping chgrp && exit 77' -i \"$f\"\ndone\nfor f in gnulib-tests/{test-chown.c,test-fchownat.c,test-lchown.c}; do\n echo \"int main() { return 77; }\" > \"$f\"\ndone\n\n# intermittent failures on builders, unknown reason\nsed '2i echo Skipping du basic test && exit 77' -i ./tests/du/basic.sh\n"), ("preInstall",""), ("propagatedBuildInputs",""), ("propagatedNativeBuildInputs",""), ("separateDebugInfo","1"), ("src","/nix/store/8f1x5yr083sjbdkv33gxwiybywf560nz-coreutils-9.3.tar.xz"), ("stdenv","/nix/store/kv5wkk7xgc8paw9azshzlmxraffqcg0i-stdenv-linux"), ("strictDeps",""), ("system","x86_64-linux"), ("version","9.3")] ) drvファイルをにらむと、データ型としては以下のパターンしかなさそうだとわかる。 ...

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.D論文のp.91が詳しい nix nar dump-path <ファイル・ディレクトリ名>で、NAR形式がどんなものか見ることが可能(バイナリなので、odやhexdumpコマンドを嚙ませたほうが見やすいかも) closure:あるstore pathに直接または間接的に依存するstore pathの集合 閉包(closure)という名の通り、closureの任意のstore pathについて、それに依存するstore pathは必ずそのclosureの要素になっている(言い換えると、ある要素に対して「その依存関係を列挙する」という操作を定義したとき、closureはその操作について閉じている) パッケージのビルドとderivationについて NixOSを使うとなるとたいていはconfiguration.nixやhome.nixを設定するだけなので、derivationに触れない場合が多いかもしれないので、一応ここで少し詳細な解説をはさむ。 ...

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.0M 0 0:00:03 0:00:03 --:--:-- 24.5M [bombrary@nixos:~]$ tar -xzf cpython-3.12.1+20240107-x86_64-unknown-linux-gnu-install_only.tar.gz [bombrary@nixos:~]$ cd python/bin [bombrary@nixos:~/python/bin]$ ls 2to3 2to3-3.12 idle3 idle3.12 pip pip3 pip3.12 pydoc3 pydoc3.12 python3 python3-config python3.12 python3.12-config 実行してみると、required file not found という、先ほどのNo such file or directoryと同じようなエラーが出てくる。 ...

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.com/guide/installation/ This installer will install rye to /home/bombrary/.rye This path can be changed by exporting the RYE_HOME environment variable. Details: Rye Version: 0.24.0 Platform: linux (x86_64) ✔ Continue? · yes ✔ Select the preferred package installer · pip-tools (slow but stable) ✔ Determine Rye's python Shim behavior outside of Rye managed projects · Make Rye's own Python distribution available ✔ Which version of Python should be used as default toolchain? · cpython@3.12 ところが、最後のcpython@3.12.1のダウンロード後、No such file or directory という一見謎のエラーで終了する。 ...

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

ブログをGitHub Actionsを使ったビルドに切り替えたときの手順

このブログはまだCI/CDも分からない頃に始めたのもあって、GitHub Actionsを使っていないビルドをしていた。いちいちビルドしてリポジトリにpushするのも面倒だし、Chanomic Sketchを昨年開設したときにGitHub Actionによるビルドを学んだので、重い腰を上げて切り替えようと思った。そのときのメモ。 色々調べていたら、Chanomic Sketchで上げたときとは違って、gh-pagesのようなブランチを作らなくても良い方法が作られていたので、その方法でやっていく。 基本的な手順はHugoの公式に書かれているが、一応現時点でのやり方をメモっておく。 (参考)現状のデプロイ方法と今後のデプロイ方法の比較 現状は、 hugo new posts/.../index.mdで記事を作成 記事を書いてhugo serverで確認 書き終わったらindex.mdのdraft: tureを外してcommit hugoコマンドを単体で実行してページのビルドをする → docs/下にHTMLが展開されるので、それをcommit pushする と手順を踏んでいたが、今回の変更によって、 hugo new posts/.../index.mdで記事を作成 記事を書いてhugo serverで確認 書き終わったらindex.mdのdraft: tureを外してcommit pushする と手順が1個減る。また、docs/ディレクトリがなくなるためコミットログがすっきりすることも期待される。 ブログの修正 まず、config.tomlのpublishDirにてdocs/下にHTMLを展開するようにしてあったが、この記述はいらないので消す。 1 publishDir="docs" また、docs/ディレクトリは git rm -rfで消す。 GitHub Pagesの設定 Pagesの設定に移動して、Build and deploymentの項目のSourceを、「Deploy from a branch」から「GitHub Actions」に変更。 workflowの記述 次に、.github/workflows/<適当な名前>.yaml を作成し、そこに以下の記述をする。 注)これは現時点でのHugoの公式をそのまま借りてきている。最新版は公式を参照すること。 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 63 64 65 66 67 68 name: Deploy Hugo site to Pages on: push: branches: - master workflow_dispatch: permissions: contents: read pages: write id-token: write concurrency: group: "pages" cancel-in-progress: false defaults: run: shell: bash jobs: build: runs-on: ubuntu-latest env: HUGO_VERSION: 0.121.0 steps: - name: Install Hugo CLI run: | wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ && sudo dpkg -i ${{ runner.temp }}/hugo.deb - name: Install Dart Sass run: sudo snap install dart-sass - name: Checkout uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 - name: Setup Pages id: pages uses: actions/configure-pages@v4 - name: Install Node.js dependencies run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true" - name: Build with Hugo env: HUGO_ENVIRONMENT: production HUGO_ENV: production run: | hugo \ --gc \ --minify \ --baseURL "${{ steps.pages.outputs.base_url }}/" - name: Upload artifact uses: actions/upload-pages-artifact@v2 with: path: ./public deploy: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest needs: build steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v3 やっている内容としては、 ...

2024-01-14 · (updated 2024-01-14) · 2 min · 297 words

NixOSをWSL2上で構築したときのメモ

年末からお正月の間帰省したときにWindowsのラップトップを持っていった。しかしWSL2にはUbuntuしか入っておらず、最近デスクトップで使っているNixOSが入っていなかった。そこで試しに構築してみたときのメモ。最低限コーディングができる環境が整った。 (IT系あるあるだけれど)NixOS-WSLの開発はまあまあ早いため、ここに書いてある内容もすぐ陳腐化してしまいそう。 インストール RepositoryのReleasesからnixos-wsl.tar.gzをDLしてくる コマンドプロンプト or PowerShell で以下のコマンドを実行 1 2 3 wsl --import NixOS .\NixOS\ nixos-wsl.tar.gz --version 2 wsl -d NixOS nix-channel --update Flake化による初回セットアップ 今回はなるべくnix-channelを使わず、flake.nixからなるべく必要なファイルを入れるようにしたい。そのほうが、今後再セットアップするときにそのflakeファイルを指定するだけで環境が構築できることを期待しているため。 とはいえ、現状のNixOSにはVimもGitも入っておらず限界があるので、それはChannelから入手する。まず現時点での最新版のnixosのChannelを登録する。 1 2 sudo nix-channel --add https://nixos.org/channels/nixos-23.11 nixos sudo nix-channel --update 次にVimとGitを入れる。Vimはテキスト編集のため、Gitはnix-flakeの動作のために必要。 1 nix-shell -p vim git NixOSで最強のLinuxデスクトップを作ろうやUsing nix flakes with NixOSに書かれている内容を参考に進めていく。 まずホームディレクトリに移動し、適当なディレクトリnixos-configを作り、そこにNixOSの設定ファイル(configuration.nix)を持ってくる。 1 2 3 4 cd ~ mkdir nixos-config cd nixos-config cp /etc/nixos/* . flake.nixを作成し以下のようにする。 inputsにnixosのリポジトリと、NixOS-WSLのリポジトリを指定する inputsの書き方はattribute setとurl-likeな書き方の2種類がある。url-likeな書き方だとtag指定の方法がわからなかったので、NixOS-WSLのinputに関してはattribute setで書いている nixosSystemの引数としてspecialArgsが指定でき、これでconfiguration.nixに引数を渡せる 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 { inputs = { nixos.url = "github:NixOS/nixpkgs/nixos-23.11"; nixos-wsl = { type = "github"; owner = "nix-community"; repo = "NixOS-WSL"; ref = "2311.5.3"; }; }; outputs = inputs: { nixosConfigurations = { wsl = inputs.nixos.lib.nixosSystem { system = "x86_64-linux"; modules = [ ./configuration.nix ]; specialArgs = { nixos-wsl = inputs.nixos-wsl; }; }; }; }; } 現在、configuration.nixではWSL用のモジュールをnixos-wsl Channelから取得するようになっている。 ...

2024-01-13 · (updated 2024-01-14) · 3 min · 610 words

FastAPIとOAuth2でユーザログイン機能(備忘録)

何をするか 以下の3つの機能を実装する。 ユーザを作成する。 ユーザを認証してトークンを生成し返す。 ユーザがログインしていないと401を返す:ここでは「ユーザ情報を返すAPI」を作成。 ユーザがログインしているかどうかで異なるレスポンスを返す:ここでは「ログインしているかどうかを真偽値で返すAPI」を作成。 方針 使う技術・フレームワーク、ライブラリなど PythonとMySQLはDocker Composeで動かす。 PythonのパッケージはPoetryで管理する。 APIサーバーはFastAPI + uvicornで動かす。 認可の方式としてOAuth2.0を用いる。認可グラントのタイプはシンプルなROPC。 なぜこれを選んだのかというと、単純にFastAPIのドキュメントに書かれていたのがこれだったため。いつかほかのタイプも実装してみたい。 DBのマイグレーションはalbemicを使用してみる。今回はユーザ情報しか作らないので、alembicの使用は間違いなくオーバーなのだが、勉強のため使ってみる。 プロジェクト構成 プロジェクトディレクトリは次のようにする。 DBに関するCRUDs処理はcrudsモジュールに書く。 DBと対応するモデルはmodelモジュールに書く。 APIのリクエストボディ、レスポンスボディの形式はschemas.pyに書く。 DBのセッションの作成はdb.pyに書く。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 . ├── api │ ├── cruds │ │ ├── __init__.py │ │ └── user.py │ ├── models │ │ ├── __init__.py │ │ └── user.py │ ├── routers │ │ ├── __init__.py │ │ └── auth.py │ ├── schemas │ │ ├── __init__.py │ │ └── user.py │ ├── db.py │ ├── main.py │ └── migrate_db.py ├── Dockerfile ├── docker-compose.yaml ├── poetry.lock └── pyproject.toml ちなみにこの図はtree -I __pycache__ --dirsfirsで生成。 ...

2023-06-29 · (updated 2023-06-30) · 7 min · 1388 words

Alembicを使ったDBマイグレーション(備忘録)

経緯 Alembicというライブラリを知ったので、試しに触ってみたメモ。 そもそもAlembicとは Alembicとは、DBマイグレーションライブラリの1つ。SQLAlchemyと一緒に用いる。 今回やってみること 今回行うマイグレーションは、以下の3つ。 空 User(email, password)を作成 User(email, password, name)に変更 使い方 Alembicの初期化 使うDBとの紐づけ エンティティ作成 マイグレーションファイルを作成 マイグレーション 想定する状況と準備 FastAPI上でWeb APIを提供し、その中でDBを操作することを想定する。ただし、メインテーマがマイグレーションのため、この記事でFastAPIの話は一切出ない。プロジェクト作成について、詳しくはFastAPI入門を参照するとよい。この記事では、ディレクトリ構成を大きく参考にしている。 パッケージ管理にはpoetryを使う。 DBにはMySQLを使う。 マイグレーションは同期処理で行うため、入れるのはPyMySQLだけでよい。しかしFastAPIでDBを処理するときに非同期での操作を行うことを見越し、aiomysqlを入れる。この時点でPyMySQLも入る。 1 poetry add sqlalchemy alembic aiomysql alembicの初期化 次のコマンドを実行する。 1 poetry run alembic init alembic プロジェクト配下にalembic/というディレクトリが生成される。 使うDBとの紐づけ alembic.iniを編集する。sqlalchemy.urlの記述を見つけたら以下のようにする。 1 sqlalchemy.url = mysql+pymysql://<url>/<name>?charset=utf8 <url>と<name>にはそれぞれ、mysqlのサーバーのURLとそのDBの名前を指定する。例えばmysqlがdbというDocker Composeのサービスとして稼働しており、3306ポートで受け付けており、そのDBの名前がappdbだった場合、次のようになる。 1 sqlalchemy.url = mysql+pymysql://root@db:3306/appdb?charset=utf8 api/db.pyにDBエンティティのベースを作っておく。 1 2 3 from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() alembic/env.pyのtarget_metadataを以下のようにする。 1 2 3 from api.db import Base target_metadata = Base.metadata 空のマイグレーション まだエンティティを作成していない状態でマイグレーションを行ってみる。 マイグレーション用のファイル作成 以下でマイグレーション用のファイルを作成する ...

2023-06-20 · (updated 2023-06-25) · 3 min · 588 words

ReactとD3.jsを使ったWordCloudの作成(備忘録)

注意 筆者はReact歴1週間なので、筋の良い書き方でなかったり、間違った書き方であったりするかもしれない。 前半は車輪の再発明をしてしまっている。書いている途中にreact-d3-cloudライブラリの存在に気づいたので、記事の最後にサンプルコードを記載している。 プロジェクト準備 このあたりは人によりけりだが、ここでは次のようにする。 Reactのビルド環境はDockerないしDocker Composeで構築。 Reactのプロジェクトはcreate-react-appで構築。 それではまずDocker・Docker Composeの構築から。 プロジェクトディレクトリを適当に作成し、そこにdocker-compose.yamlを書く。 1 2 3 4 5 6 7 8 9 10 version: "3.0" services: app: image: node:20-slim volumes: - ./app:/src ports: - 3000:3000 command: npm start working_dir: /src 続いて次のコマンドを実行してcreate-react-appを導入し、実行する。 1 $ docker-compose run --rm app sh -c "npm install -g create-react-app && create-react-app ." これによりappディレクトリが作成され、中にReactのプロジェクトが生成される。 ...

2023-06-11 · (updated 2023-06-11) · 4 min · 777 words