blog.ryota-ka.me

Nix flakeからprivateなリソースにアクセスする

HERPでは,開発体験の向上のため,順次flakesの導入を進めている.「次世代のNix」とでも呼ぶに相応しいflakesは,未だ実験的な機能と位置付けられているものの,従来のNixでは保証し切れなかったより高いビルドの再現性や,統一的なインタフェースの規定,刷新されたコマンド体系など,様々な改良が盛り込まれている.

再現性への追求に対する代償として,flakesは純粋性に関して従来よりも厳しい制約を設けている.特にnetrcImpureEnvVarsが利用できないため,privateなリソースにアクセスしたい場合に前回の記事で紹介した方法が利用できない.そこで本稿では,flakeからprivateなリソースにアクセスする方法を紹介する.

Flakeのinputとして利用する場合#

ここでは例として,GitHub上のyour-company/private-repoというprivate repositoryをflakeのinputとして利用するケースを想定する.

GitHubやGitLabなど,アクセストークンを通じた認証機構を提供するプラットフォームからリソースを取得したい場合には,access-tokensオプションが利用できる.このオプションには,host=tokenという形式の文字列をスペースで区切った値を指定する.以下ではgho_XXXXXXXXがGitHubのアクセストークンであるとする.

マシン上にグローバルに設定する場合は,/etc/nix/nix.confaccess-tokensオプションを指定する.

特定のユーザのみに設定する場合は,$XDG_CONFIG_HOME/nix/nix.confextra-access-tokensオプション*1を指定する.

個人の開発環境では,personal access tokenを発行し,上記のような設定を行うとよいだろう.一方,Nixに限った話ではないが,CI上で利用するアクセストークンの発行には一考を要する.一つの解決策としては,必要なリポジトリに対するread権限を持たせたGitHub appを用意しておくことで,ジョブごとに短命なアクセストークンを発行することができる.HERPでは,self-hosted runnerの$ACTIONS_RUNNER_HOOK_JOB_STARTEDに指定したシェルスクリプト内でアクセストークンを発行し,前述の形式でnix.confに書き込むようにしている.こうすることで,各リポジトリでは何ら特別な設定を行うことなく,inputsに指定したリソースを取得できる.

その他一般のリソースの場合#

ここでは例として,privateなnpm packageに依存したパケッジをビルドするためにyarn2nixを利用するケースを想定する.また,npm packageはAWS CodeArtifact上にホストされているものとする.Flakesを利用するという以外の状況設定は前回の記事と同様であるため,そちらも合わせて参照されたい.

こうしたケースでは,builtins.fetchurlpkgs.fetchurlとは異なりnetrc-fileオプションを参照してくれるという性質が利用できる.このオプションにはnetrcファイルへの絶対パスを指定する.

AWS CodeArtifactのアクセストークンのような,短命な認可情報をオプションとして指定する場合には,前節で紹介したnix.confに書き込む方式ではなく,nixコマンドのオプションを指定するのがよいだろう.ビルドに先立ち,前回の記事で紹介した内容が記述されたnetrcファイルをカレントディレクトリ中に生成しておけば,以下のようなコマンドでビルドが行える.

$ nix --netrc-file "$PWD/netrc" build

ただし,builtins.fetchurlはSHA-512に対応していない*2という問題があるため,SHA-512のハッシュ値を要求するYarnなどと組み合わせて使う場合には実のところうまく機能しない.

幸い,NixOS/nixリポジトリのsrc/libexpr/fetchurl.nixで定義されている関数が,SHA-512に対応する代替品として使用できる.src/libexpr/以下のファイルのパスは<nix/PATH>という形で参照できるため,この関数はimport <nix/fetchurl.nix>というexpressionで得られる.

yarn2nixで生成したNixファイルが./nix/yarn.nixに存在している場合,以下のようなNix expressionを書けばよいだろう.

謝辞#

この記事の内容は,インターンである@kgtkrによる調査の成果に負うところが大きい.感謝します.

広告#

株式会社HERPでは,プロダクト開発に集中できる環境を整備できるエンジニアを募集している.

また,Nix日本語コミュニティでは,Discord上でNixに関する情報交換を行っている.

脚注#

*1: extra-を付けることで,グローバルの設定を上書きせずに追加で値を設定できる.

*2: 引数にsha512attributeを受け付けない.