学科システムにはsingularityというコンテナサービスを導入している。動かしているpodmanと比較するとこのあたりが便利と思っています。
- ceph fs上でも結構高速に動作
- root権限がいらない
- podmanもrootlessではあるが、ceph FS上だと遅い...
singularity shell
で気軽にコンテナのシェルを立ち上げられる- 科学計算向きなのでスパコンなどでの利用実績がある
- ホームディレクトリなどがattachしたタイミングで自動的にコンテナにマウントされる
とはいえ良い事ばかりではなくツラミポイントもあります。 例えばDockerを使っている場合は構成をDockerfileで書きたくなりますが、singularityで同様のビルドファイルを作ろうとした場合、各コマンドのキャッシュが効きません。
dockerの場合は行単位でキャッシュが効いていたのですが、singularity build
的な感じでファイルからビルドしようとすると、失敗した場合最初からになるため、本筋ではないapt update
などで莫大な時間を浪費します。
しかしsingularityはdockerと違い、--sandbox
で実行するといかにもchrootやlinux namespaceみがあるディレクトリを作成し、この上で様々な構築をインタラクティブにしたあとにシングルバイナリのsifに固めるという技があるので、dockerファイルの様なファイル形式でなく、インタラクティブに構築する方法が適していそうです。
今回はRustコンパイラのデバッグ環境をsingularityで作るのを通して、インタラクティブな構築方法を見てみます。
インタラクティブに構築する場合は、--sandbox
と --writable
を使ってビルド及び環境構築を行います。
sandbox環境の作成
とりあえずaptのupdateだけするファイルrust-debug.def
を生成します。
BootStrap: docker From: ubuntu:20.04 %post apt-get -y update apt-get -y upgrade
sandbox環境のビルド
$singularity build --sandbox --fakeroot rust-debug rust-debug.def
sandbox環境にシェルログインして環境を作る
$singularity shell --fakeroot --writable rust-debug
こうするとシェルログインが出来ます。
--fakeroot
はホストOS側でroot権限がないユーザーでも、コンテナの中でrootとして振る舞う事ができるオプションです。
Rustコンパイラのデバッグ環境の構築
さてシェルログインできたら、Rustcompilerのデバッグビルドに必要そうなものをインストールします。 なにが必要かはGitHubリポジトリに書いてあるので読んでみます。
Singularity> apt install -y cmake python3 clang ninja-build lldb gdb curl git
とりあえず必要そうなものをinstall
無事にインストールされたら、singularityコンテナの中でpythonと入力するとpython3が起動するように仕込みます。
update-alternatives --install /usr/bin/python python /usr/bin/python3 10
参考 Unable to set default python version to python3 in ubuntu
/root
にRustのリポジトリを起きたいところですが、ここは実行ユーザーの$HOMEとマウントされるので適当なディレクトリをつくります
$mkdir /rust
$cd /rust
Rustコンパイラのデバッグビルド
rustのリポジトリをcloneします
- $git clone https://github.com/rust-lang/rust.git
Rustはビルドの設定をTOMLで記述します。exampleをもとにするのが良いらしいので、copyします。
$cp config.toml.example config.toml
aptでvimをinstallし、設定を書き換えていきます。 まずdebugビルドするので、デバッグオプションを有効化します。 ビルド時にninjaを使いたいのでninjaを有効にし、趣味でinstall先のprefixを変えておきます。
まとめると次のような変更をします。
#debug = false
をdebug = true
#ninja = false
をninja = true
#prefix = "/usr/local"
をprefix = "/usr/local"
Rustのビルドとインストール
RustはビルドスクリプトはPythonで書かれたx.py
ですので、これを実行します
./x.py build && ./x.py install
今回は/rust/rust
がリポジトリで、ここでビルドを実行しました。
そのため生成されたRustのバイナリは/rust/rust/build/x86_64-unknown-linux-gnu/
以下に配置されています。
例えばLLDBでデバッグする場合はrust-lldb /rust/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc
とするとデバッグ可能です。
ビルドした結果をsifに変換する
sandbox環境で無事ビルドできたので、これを配布可能なsif形式に固めます。
固めるときはbuild
で、def
ファイルでなくディレクトリを指定します。
$singularity build --fakeroot debugging-rust-compiler.sif rust-debug
この結果、debugging-rust-compiler.sifが生成されており、以降はこれを使います。
設定したsifに接続する
作成したsifにシェルログインしてみます
$singularity shell debugging-rust-compiler.sif