GNU Guix
パッケージ管理システム
From Wikipedia, the free encyclopedia
GNU Guixは、クロスプラットフォームの関数型パッケージマネージャで、Unix系オペレーティングシステムの生成や管理のためのツールでもある。Nixをベースとしており、設定やパッケージのビルドについてGuile Schemeで書くことができる。Guixという名前はGuileとNixを組み合わせたかばん語である[3]。GNU GuixはGNU Guix Systemのデフォルトのパッケージマネージャである[4]。
言語 Guile Scheme, C++ (Nix core)
|
| |
| 最新版 | |
|---|---|
| リポジトリ | |
| プログラミング 言語 | Guile Scheme, C++ (Nix core) |
| 対応言語 | 英語 |
| 種別 | オープンソース |
| ライセンス | GPL 3.0かそれ以降 |
| 公式サイト |
guix |
一般的なパッケージマネージャとは異なり、暗号学的ハッシュによって一意なディレクトリにソフトウェアがインストールされるという、Nixと同様に純粋関数的なデプロイのモデルを採用している。ソフトウェアの依存関係はそれぞれのハッシュに含まれている[5][6]。これにより、依存関係地獄の問題を解決することができ[7]、同じソフトウェアの違うバージョンが共存することができるため、パッケージをよりポータブルで再現性の高いものにすることができる[8]。このようなGuixの数学的なアプローチは、再現性の危機への有望な対処法として提案された[9][10]。
特徴
Guixのパッケージは、パッケージ管理のために設計された、Guile SchemeのAPIによって定義される。依存関係は、Guixデーモンによって遅延評価される「deriviations」と呼ばれる特別な値を通して、言語内で直接追跡できる。Guixは、不必要になったパッケージをガベージコレクションの対象にできるようにこれらを記録している。膨大なストレージの容量を消費することで、Guixのアップグレードはすべてアトミックかつロールバック可能となる。
Guixのロールバック機能はNixの設計から引き継がれている。ロールバックを可能とするには一般的でないアプローチを必要とするため、ロールバック機能は他のパッケージマネージャにはめったに見られない。しかし、GuixはNixと同様に、多くのディストリビューションで利用できる。これを利用すれば、同じシステム上の複数のユーザーが、管理者権限なしに安全にソフトウェアをインストールすることができる。
従来のパッケージマネージャと比較して、Guixのストアは大きくなりがちであり、それゆえ多くの帯域幅を必要とする。しかし、依存関係地獄を解決するために用いられる他の手法(Dockerなど)と比べれば、Guixはより無駄がなく、Don't repeat yourselfや信頼できる唯一の情報源のような慣例に忠実である。すべてをソースコードからビルドする場合は、さらに多くのストレージ容量や帯域幅が必要となる。
ストア
Nixの設計を引き継ぎ、パッケージマネージャの内容の大部分は、/gnu/store ディレクトリに保存されている。このディレクトリは、Guixデーモンのみに書き込み許可権限がある。これは特殊なマウントによって実現されており、ファイルシステムとしてのストアは読み込み専用でマウントされ、ルートユーザーからの干渉も禁止されている。一方、Guixデーモンはストアを書き込み可能として、独自のプライベート名前空間に再マウントする。Guixはこのデーモンとやりとりし、パッケージをビルドしたり、Substituteを取得したりする。ストアの目的がなくなるため、ユーザが手動でストアを書き込み可能として再マウントすることは推奨されない。
ガベージコレクション
GuixはNixと同様に、ガベージコレクション機能を内蔵しており、これはdead 状態のストアのアイテムをlive 状態に保つのに役立つ[11]。
パッケージ定義
これは hello-package のパッケージ定義の一例である。
(use-modules
(guix packages)
(guix download)
(guix build-system gnu)
(guix licenses))
(define-public hello
(package
(name "hello")
(version "2.10")
(source (origin
(method url-fetch)
(uri (string-append "mirror://gnu/hello/hello-" version
".tar.gz"))
(sha256
(base32
"0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i"))))
(build-system gnu-build-system)
(synopsis "Hello, GNU world: An example GNU package")
(description
"GNU Hello prints the message \"Hello, world!\" and then exits. It
serves as an example of standard GNU coding practices. As such, it supports
command-line arguments, multiple languages, and so on.")
(home-page "https://www.gnu.org/software/hello/")
(license gpl3+)))
これは Guile を用いて書かれている。Guix では、パッケージレシピを簡単に調べたり(例えば、guix edit helloコマンドを実行して)、変更したりすることができる。これにより、システムの透明性が高まり、改変が非常に簡単になる。
トランザクション型の更新
Nix の設計を引き継ぎ、各ストアのすべての操作は互いに独立している。ストアのディレクトリ名は、deriviation とその入力のソースコードを base32 でエンコードされたハッシュ値で始まる。
プロファイル
Guixのパッケージは世代別のプロファイルを使っている。これは、ユーザーがインストールしたものから成る、特定のストア項目へのシンボリックリンクの集合である。パッケージがインストール、または削除されるたびに、新しいプロファイルが生成される。
例えば、GNU Helloだけをインストールしたユーザーのプロファイルには、現在 guix で使われている hello のバージョン情報を保持するストア項目へのリンクが含まれる。
シンボリックリンクに加えて、guix が生成するそれぞれのプロファイルには、すべてのinfoマニュアル、アイコン、Manページなどが含まれているため、ユーザーはドキュメントを参照し、インストールされているすべてのアイコンやフォントにアクセスできる。
プロファイルへのデフォルトのシンボリックリンクは /var/guix に保存されている。
複数のプロファイル
ユーザーは、guix package -p PROFILE-NAME COMMAND を呼び出すことで、任意の数のプロファイルを作成できる。
ロールバック
Guixのパッケージは、シンボリックリンクを以前のプロファイルに変更することで、以前のプロファイルに手軽にロールバックすることが可能である。[12]。プロファイルもストアに保存される。例えば、この項目は上記の hello を含むプロファイルである: /gnu/store/b4wipjlsapvnijmbawl7sh76087vpl4n-profile ( guix install helloの実行時に有効化される)。
Guix Shell
Guix shell を使うことで、複数のプロジェクトの依存関係によってデフォルトのプロファイルに問題を起こすことなく、ソフトウェア開発に必要なパッケージを含む環境に入ることができる[13]。
例えば、 guix shell --development hello を実行すると、guix 上で hello をコンパイルするために必要なもの (gcc、guile など) がすべて揃った一時的な環境に入ることができる。
--development フラグがない場合、hello パッケージのみがインストールされ、そのビルドの依存はインストールされない。これは、パッケージの依存関係をデフォルトでインストールする guix environment コマンドに代わるものとして導入された。これは、指定されたパッケージをデフォルトでインストールし、フラグを使用して開発依存関係のみをインストールする方が直感的であると考えられたためである[14]。
継続的な開発環境
guix gc の次回実行時にガベージコレクションされない継続的な gc ルート環境が必要な場合は、ルートを作成できる。
例えば、 guix shell --root=hello-root --development hello を実行すると、guix をコンパイルするために必要なもの (gcc、guile など) がすべて存在し、現在のディレクトリにルートとして登録されている環境に入ることができる (ストア内の項目へのシンボリックリンクによって)。
pack
Guix packを使うことで、ユーザにストアアイテムを複数同時に束ねることを可能にし、Dockerバイナリイメージや、再配置可能な tarball 、squashfsバイナリ、Debianパッケージファイル、RPMパッケージファイル、AppImageなどに出力することができる[15][16][17]。
Graph
Guix graphを使用すると、パッケージとその依存関係のさまざまなグラフを表示することができる[18]。
サードパーティーチャンネル
Guixでは、パッケージ定義に使う追加のチャンネルを設定することができる[19]。
この機能を使うことにより、メインのプロジェクトではパッケージできない非自由なソフトウェアをインストールすることができる[20][21]。
Guix System(オペレーティングシステム)
GNU Guix SystemまたはGuix System[26][27](以前はGuixSDと呼ばれていた[28])は、ローリングリリースで、FOSSのLinuxディストリビューションである。NixOSがNixをベースとして構築されているのと同じように、Guix SystemはGuixをベースとしている[29]。Guix Systemは、宣言的なOSの設定を可能にし[30]、また容易にシステムの更新をロールバックすることができる[31]。GNU Shepherd initシステムとLinux-libreカーネルを利用しており[32][33]、GNU Hurdカーネルのサポートが開発中である[34]。2015年2月3日、このディストリビューションはFSFが推薦する自由なディストリビューションのリストに加えられた[35]。
アーキテクチャのサポート
現在、次のCPUアーキテクチャがサポートされている。
システムサービス
システムサービスは、Guile Schemeで定義されており[39]、デーモンとバックグランドサービスを宣言的に設定することができる。これにより、一つ、または複数の設定ファイルを用いて、オペレーティングシステム全体を構成することができる。(例えば、Torプロキシを設定したり、SSHサーバーを設定したり、システム起動時に特定のポートでnginx経由でguix-webを提供するウェブサーバーを設定したりといったことができる)。可能になることは以下の通りである[40]。
- ファイルシステムにファイルを生成する(例:/etc 内のファイル)
- デーモンを設定するためのコードを実行する
- 特定のユーザーおよびグループアカウントを作成する(例:PostgreSQLのデータベースユーザー)
GNU Shephred Init システム
Guixシステムは、GNU Shepherdデーモンをinitシステムとして使っている。GNU ShepherdはGuileで書かれており、Guixの開発と平行して行われている。これは以前 "dmd"("Daemon managing Daemons"または"Daemons-managing Daemon")として知られていたが、Digital MarsのDコンパイラとの名前の競合を避けるために名称が変更された[41]。
Shepherd は、ユーザ空間の機能をサービスとして非同期に提供する。サービスとは、Shepherd ではジェネリック関数とオブジェクトデータ型であり、定義された方法でベースとなるオペレーティングシステムを拡張するために使用される。systemd とは対照的に、ユーザ空間のShepherdプロセスはユーザーとして実行される。ユーザ空間の初期化のShepherdモデルの中心となるのは、拡張の概念である。これは、サービスが他のサービスの上に重ねられるように設計され、必要に応じてより複雑な動作や特殊な動作を可能にする、構成可能性の一形態である[42]。これは、多くの最新の init システムに見られるインスタンス化ベースの依存関係を表現し[43]、システムをモジュール化するが、サービスが他のサービスと任意の方法で可変的に対話できるようにもする。例えば、他の2つのサービスを拡張するサービスでは、1つのサービスのみが必要であり、後で生成された2番目のサービスを簡単に拡張でき、それ以上の再設定やセットアップは必要ない。
Shepherd は、システムのメール転送エージェント を生成するすべてのサービスオブジェクトなど、関連するサービスオブジェクトのクラスに対して動的ディスパッチを可能にする「バーチャルサービス」も提供する[44]。Shepherd デーモンによって制御されるシステムは、そのユーザー空間を有向非巡回グラフとして表すことができる。そのルートとして、ブートと初期化の段階を担当する「システム サービス」があり、その後に初期化されるすべてのサービスは、直接的または他のサービスを介して推移的に、システムサービスの拡張として表される[42][45]。
これは、Guile を使用するシステム管理者によって高度にプログラム可能であることを目的としているが、権限のないデーモンやサービスなど、ユーザーごとのプロファイルを管理するためにも使用できる[46]。サービスや設定はオブジェクト指向の Scheme コードとして一様に保存され、基本的な Guix System でコアとなるサービスは提供される一方で[47]、任意の新しいサービスを柔軟に宣言でき、Guile のオブジェクトシステムである GOOPS を通じて、生成時に指定された方法でサービスを動的に書き換えるように Shepherd に要求することで、既存のサービスをユーザーの裁量で再定義できる[48][49]。
GNU ShepherdはもともとGNU Hurdと連携するように設計され、後にGuix Systemに採用された[50]。
ロールバック
NixOS のロールバック機能と同様に、システムアップデートによってシステムが壊れた場合、簡単なコマンドで個々のパッケージだけでなく、システム全体の状態を簡単にロールバックすることができる:
guix package --roll-back[51]
これは、guix pull 経由でアップデートしようとするときに、バグを報告して数分待つことをいとわないユーザーにとって、他のLinuxディストリビューションで非常に一般的な安定版チャンネルが、もはや必要ないことを意味する。これは、各パッケージとシステム構成を不変かつ再現可能なエンティティとして扱う Guix の関数型パッケージマネージャと[52] 、システム構成の履歴を「世代」として保持するシステムの組み合わせによって実現される。これらの世代は個々のプロファイルとして保存され、以前の構成にロールバックすることができる[53]。また、これらの世代は、以下のコマンドで見ることができる。
guix package --list-generations.
反響
DistroWatch WeeklyのJesse SmithはGNU Guix System 0.15.0(当時のGuixSD)をレビューし、「GuixSDには私が気に入っているパッケージマネージャがある」と述べたが、限られたハードウェアサポートとドキュメント不足については批判的だった[54]。その後、ドキュメントは充実し、ビデオ[55]や、6つの言語でのチュートリアル、ハウツーガイド、例を含んだクックブック[56]などにより状況は改善した。
再現可能な科学的ワークフロー
Guix が従来のパッケージマネージャよりも優れた機能をユーザーに提供できる分野は、再現可能な科学的ワークフロー、特に高性能計算においてである[57]。Guix は再現可能な計算環境を共有する方法を提供する。つまり、特定の科学的ソフトウェア/環境のためのレシピを使用する Guix は、そのソフトウェアをビルドして実行するための依存関係ツリーを一意に記述するために必要なすべての情報を提供することができる[58]。これは例えば、各プログラミング言語ごとにパッケージマネージャーがあるようなシステムでは簡単に実現することができない。ただし、これは科学的ワークフローが再現可能であるための必要条件を提供するだけで、十分条件ではない。データの収集と処理をワークフローに組み込む必要があるため、これを Guix レシピの一部として追加したときに、厳格な再現性要件を満たすことができる。
歴史
リリース
固定のリリーススケジュールはなく、これまで約6か月ごとにリリースされてきた。
1.4.0 リリースから2年以上の間が空いているが、今後 1.5.0 リリースが予定されている[62]。
| バージョン | 発表 | アーキテクチャ | パッケージの数 |
|---|---|---|---|
| 0.1 (alpha) | 2013年1月[63] | i686, x86_64 | ~150 |
| 0.2 (alpha) | 2013年5月[64] | ~400 | |
| 0.3 | 2013年7月[65] | ~430 | |
| 0.4 | 2013年9月[66] | ~490 | |
| 0.5 | 2013年12月[67] | ~600 | |
| 0.6 | 2014年4月[68] | ~691 | |
| 0.7 | 2014年7月[69] | ~825 | |
| 0.8 | 2014年11月[70] | i686, x86_64, mips64el | ~987 |
| 0.8.1 | 2015年1月[71] | i686, x86_64, mips64el, armv7 | ~1151 |
| 0.8.2 | 2015年5月[72] | ~1869 | |
| 0.8.3 | 2015年07月[73] | ~2048 | |
| 0.9.0 | 2015年11月[74] | ~2591 | |
| 0.10.0 | 2016年5月[75] | ~3230 | |
| 0.11.0 | 2016年8月[76] | ~3714 | |
| 0.12.0 | 2016年12月[77] | ~4567 | |
| 0.13.0 | 2017年5月[78] | i686, x86_64, mips64el, armv7, aarch64 | ~5407 |
| 0.14.0 | 2017年12月[79] | ~6618 | |
| 0.15.0 | 2018年7月[80] | ~7857 | |
| 0.16.0 | 2018年12月[81] | ~8715 | |
| 1.0.0 | 2018年5月[82] | ~9712 | |
| 1.0.1 | 2019年5月[83] | ~9771 | |
| 1.1.0 | 2020年4月[84] | i686, x86_64, armv7, aarch64 | ~13161 |
| 1.2.0 | 2020年11月[85] | ~15333 | |
| 1.3.0 | 2021年5月[86] | i686, x86_64, powerpc64le, armv7, aarch64 | ~17262 |
| 1.4.0 | 2022年12月[87] | i686, x86_64, powerpc64le, armv7, aarch64 | ~22000 |