1.4K Views
October 26, 24
スライド概要
Nixのprofileをdeployできるdeploy-rsの使い方や仕組みについて
deploy‑rs で Nix を deploy ymgyt · 2024‑10‑26
自己紹介 [speaker] name = "Yamaguchi Yuta" github = "ymgyt" blog = "https://blog.ymgyt.io/"
概要 • deploy‑rs の使い方 • deploy‑rs の仕組み
Deploy Tools Tool nixops deploy-rs colmena morph comin bento krops Lang python rust rust go go shell nix Star 1,842 1,366 1,193 812 368 240 137
deploy‑rs とは > A Simple, multi‑profile Nix‑flake deploy tool
deploy‑rs とは > A Simple, multi‑profile Nix‑flake deploy tool ‑ multi‑profile: profile 単位で deploy
deploy‑rs とは > A Simple, multi‑profile Nix‑flake deploy tool ‑ multi‑profile: profile 単位で deploy ‑ Nix‑flake: 設定は flake.nix に定義
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
deploy-rs.url = "github:serokell/deploy-rs";
};
outputs = { self, nixpkgs, deploy-rs }:
{
nixosConfigurations.myhost =
nixpkgs.lib.nixosSystem { system = "aarch64-linux"; };
deploy = {
user = "root";
autoRollback = true;
magicRollback = true;
remoteBuild = false;
flake.nix
nodes = {
myhost = {
hostname = "myhost";
profiles.system.path =
deploy-rs.lib.aarch64-linux.activate.nixos
self.nixosConfigurations.myhost;
};
};
};
};
}
# 全 node の deploy deploy . # node の指定 deploy .#myhost # profile の指定 deploy .#myhost.foo deploy の実行
Rollback 2 種類の Rollback がある • Auto Rollback • Magic Rollback
Auto Rollback Auto rollback は profile の activate が失敗した場 合に前の profile を再度有効にする nix-env -p <path> --rollback nix-env -p <path> --delete-generations <id>
Magic Rollback Magic rollback は profile の activate に成功した 場合でもなんらかの理由で network(ssh)の疎通 がとれなくなった場合に rollback する
Magic Rollback • profile の activate は deploy‑rs が提供する activate command が行う • activate は profile 有効後に canary file を作成 して待機する • activate は一定時間内に canary file が削除され ない場合、失敗とみなして rollback する
Magic Rollback • ssh 越しの rm canary が失敗 • activate が profile の deactivate を実行
deploy‑rs の仕 組み deploy‑rs はどうやって Nix の profile を deploy しているのか
{
outputs = { self, nixpkgs, deploy-rs }:
{
nixosConfigurations.myhost = /* ... */
deploy = {
# Node 共通の設定
autoRollback = true;
magicRollback = true;
deploy 対象の
取得
nodes = {
myhost = {
hostname = "myhost";
profiles.system.path =
deploy-rs.lib.aarch64-linux.activate.nixos
self.nixosConfigurations.myhost;
};
};};};
}
• deploy の設定は flake.nix に定義されている
• nix eval --json .#deploy で取得
deploy 対象の 取得
deploy 対象の 取得 node や profile の指定は--apply で nix の関数を 適用することで実現
profile の deploy nix の build を local で行うか、deploy 対象の remote で行うか選択できる
remote build の場合 profile の deploy nix copy -s --to ssh-ng://${ssh_user}@${hostname} --derivation /nix/store/abc...xyzactivatable-nixos-system-host-xyz.drv^out nix build /nix/store/abc...xyz-activatable-nixossystem-host-xyz.drv^out --eval-store auto --store ssh-ng://${ssh_user}@${hostname}
local build の場合 profile の deploy nix build /nix/store/abc...xyz-activatablenixos-system-host-xyz.drv^out --no-link nix copy --substitute-on-destination --to ssh://${ssh_user}@${hostname} /nix/store/abc...xyz-activatable-nixossystem-host-xyz
deploy‑rs.lib deploy‑rs の機能は deploy-rs.lib の形で提供さ れている
deploy‑rs.lib { nodes = { myhost = { hostname = "myhost"; profiles.system.path = deploy-rs.lib.aarch64linux.activate.nixos self.nixosConfigurations.myhost; }; } deploy-rs.lib.activate.nixos は引数の nixosConfiguration に対して activate command を追加する
deploy‑rs.lib
activate = rec {
custom = {
__functor =
customSelf: base: activate:
final.buildEnv {
name = ("activatable-" + base.name);
paths = [
base
(final.writeTextFile {
name = base.name + "-activate-path";
text = ''
# ...
${activate}
'';
executable = true;
destination = "/deploy-rs-activate";
})
(final.writeTextFile {
name = base.name + "-activate-rs";
text = ''
#!${final.runtimeShell}
exec ${final.deploy-rs.deploy-rs}/bin/activate "$@"
'';
executable = true;
destination = "/activate-rs";
})
];
};
};
flake.nix に定義した outputs.deploy に対する check も提供されている check checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
check
deployChecks =
deploy:
builtins.mapAttrs (_: check: check deploy) {
deploy-schema =
deploy:
final.runCommand "jsonschema-deploy-system" { } ''
${final.check-jsonschema}/bin/check-jsonschema --schemafile ${./
interface.json} ${final.writeText "deploy.json" (builtins.toJSON deploy)} &&
touch $out
'';
ユーザの deploy 定義を json に変換して、jsonschema に違反していないかチェックし
ている
まとめ • deploy‑rs で簡単に NixOS configuration を複数 host に deploy できた • deploy や rollback は nix の機能を利用してい ることがわかった • NixOS の設定の切り替えの仕組みを理解して いきたい ‣ switch‑to‑configuration ‣ config.system.build.toplevel
参考 • deploy‑rs • Our New Nix Deployment Tool: deploy‑rs • Deployment tools: evaluating NixOps, deploy‑ rs, and vanilla nix‑rebuild • serokell example • Remote Deployments with nixos‑rebuild