TUI の Feed Viewer を自宅の Raspbery Pi で 公開するまで

272 Views

October 10, 24

スライド概要

Nix で Rust の開発環境から CI,Deploy まで管理する

profile-image

engineer wannabe 🦀

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

TUI の Feed Viewer を自宅の Raspbery Pi で 公開するまで Nix で Rust の開発環境から CI,Deploy まで管理する 山口 裕太 · 2024‑03‑05

2.

自己紹介 [speaker] name = "Yamaguchi Yuta" github = "https://github.com/ymgyt" blog = "https://blog.ymgyt.io/"

3.

会社紹介 [company] name tech_blog = "FRAIM Inc." = "https://zenn.dev/p/fraim"

4.

作成したツールのライフサイクルについて 話すこと • TUI の Feed Viewer を作った • Nix で開発環境,CI,Deploy を管理した • Release では cargo‑release と cargo‑dist を利 用した • Trace,Metrics,Logs は OpenTelemetry を利用し た

5.

Rust で TUI Feed の Entry 一覧

6.

Rust で TUI Feed の一覧

7.

Rust の TUI library 1. crossterm(cross platform terminal library) 2. ratatui(tui widgets library)

8.

Rust の TUI library Netflix が公開した eBPF の tui tool でも ratatui が使われている

9.

let (header, widths, rows) = self.entry_rows(cx); ratatui let entries = Table::new(rows, widths) .header(header.style(cx.theme.entries.header)) .column_spacing(2) .style(cx.theme.entries.background) .highlight_symbol(ui::TABLE_HIGHLIGHT_SYMBOL) .highlight_style(cx.theme.entries.selected_entry) .highlight_spacing(HighlightSpacing::WhenSelected); Table や List 等の基本的な widget が用意されている

10.
[beta]
crossterm

async fn event_loop<S>(&mut self, input: &mut S)
where
S: Stream<Item = io::Result<CrosstermEvent>> +
Unpin,
{
loop {
tokio::select! {
biased;
Some(event) = input.next() => { }
_ = self.background_jobs => { }
};
}

複数の入力も async で書ける

11.
[beta]
crossterm

fn handle_terminal_event(&mut self, event:
std::io::Result<CrosstermEvent>) {
match event.unwrap() {
CrosstermEvent::Resize(columns, rows) => { }
CrosstermEvent::Key(key) => match key.code {
KeyCode::Tab => { },
KeyCode::Char('j') => { },
}
}
}

Key 入力の処理も簡単

12.

Nix による開発 環境の管理 この Rust の project を Nix で管理しました

13.

そもそも Nix とは Nix による開発 環境の管理 > A build tool, package manager, and programming language https://zero‑to‑nix.com/concepts/nix

14.

Nix で管理する と何がうれし いのか • 開発環境を Nix で管理できる

15.
[beta]
{

Nix による開発
環境の管理

inputs.nixpkgs.url = "github:NixOS/nixpkgs/
release-23.11";
outputs = { self, nixpkgs, ... }:
let dev_packages = with pkgs; [
graphql-client
git-cliff
cargo-release
cargo-dist
oranda
];
in { devShells.default = craneLib.devShell {
packages = dev_packages;
};
});
}

project root の flake.nix で開発時の依存を宣言

16.

nix develop nix develop を実行すると宣言した package が PATH に入った状態で開発環境(shell)が立ち上が る

17.

Nix で管理する と何がうれし いのか • 開発環境を Nix で管理できる • CI を Nix で管理できる

18.

CI でも nix develop name: CI jobs: tests: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: nix develop .#ci --acceptflake-config --command just check • install action が不要 • 開発環境と同一 version

19.

Nix で管理する と何がうれし いのか • 開発環境を Nix で管理できる • CI を Nix で管理できる • Cache を Nix で管理できる

20.

Nix で管理する と何がうれし いのか /nix/store/3sn5pij1hjvdlnq468c0m8vz8nibhrdccargo-release-0.25.0/bin/cargo-release の 3sn5pij1hjvdlnq468c0m8vz8nibhrdc が入力に対 応する hash となっており、cache があれば build せずに binary を取得できる

21.

Nix で管理する と何がうれし いのか cache から取得

22.

Nix で管理する と何がうれし いのか name: CI jobs: tests: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: cachix/install-nix-action@v25 with: github_access_token: ${{ secrets.GITHUB_TOKEN }} - uses: cachix/cachix-action@v14 with: name: syndicationd authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - run: nix develop .#ci --accept-flake-config -command just check cache を設定した最終的な CI の workflow local と CI で同じ cache の仕組みを利用できる

23.

Nix で管理する と何がうれし いのか • 開発環境を Nix で管理できる • CI を Nix で管理できる • Cache を Nix で管理できる • Install を Nix で管理できる

24.

Nix で管理する と何がうれし いのか nix run で一時的に実行したり nix profile で install もできる Mac と Linux で同じ package 管理ができる

25.

Nix で管理する と何がうれし いのか • 開発環境を Nix で管理できる • CI を Nix で管理できる • Cache を Nix で管理できる • Install を Nix で管理できる • Deploy を Nix で管理できる

26.
[beta]
Nix で systemd
service を宣言

{ config, pkgs, syndicationd, ... }:
let
syndPkg = syndicationd.packages."${pkgs.system}".syndapi;
in {
config = {
systemd.services.synd-api = {
description = "Syndicationd api";
wantedBy = [ "multi-user.target" ];
environment = {
SYND_LOG = "INFO";
};
serviceConfig = {
ExecStart = "${syndPkg}/bin/synd-api"
};
};
};
}

https://github.com/ymgyt/mynix/blob/main/homeserver/
modules/syndicationd/default.nix

27.

Nix で Deploy deploy‑rs で NixOS が入った RaspberryPi に deploy

28.

Nix で管理する と何がうれし いのか • 開発環境を Nix で管理できる • CI を Nix で管理できる • Cache を Nix で管理できる • Install を Nix で管理できる • Deploy を Nix で管理できる

29.

cargo でも公開 したい とはいえ、cargo install もしたい

30.

cargo publish するには以下が必要 cargo でも公開 したい • Cargo.toml の package.version の bump • Workspace 内に依存 package がある場合は合 わせて bump • CHANGELOG の生成 • git の tagging これを workspace の member crate ごとに実施 する必要がある

31.

cargo でも公開 したい cargo‑release が全て面倒をみてくれる

32.

cargo release --package foo patch を実行する cargo でも公開 したい と • foo package の Cargo.toml package.version を bump(v0.1.2 ‑> v0.1.3) • foo に依存している workspace 内の package の dependencies.foo.version を bump • 設定に定義した replace 処理を実施 (CHANGELOG の[unreleased] ‑> [v0.1.3]) • git の commit, tagging, push • cargo publish

33.

homebrew で も公開したい brew install もしたい

34.

専用の repository(homebrew-syndicationd)に以下 のような記述が必要 homebrew で も公開したい class Synd < Formula desc "terminal feed viewer" version "0.1.6" on_macos do on_arm do url "https://github.com/ymgyt/syndicationd/releases/download/syndterm-v0.1.6/synd-term-aarch64-apple-darwin.tar.gz" sha256 "c02751ba979720a2a24be09e82d6647a6283f28290bbe9c2fb79c03cb6dbb979" end on_intel do url "https://github.com/ymgyt/syndicationd/releases/download/syndterm-v0.1.6/synd-term-x86_64-apple-darwin.tar.gz" sha256 "3be81f95c68bde17ead0972df258c1094b28fd3d2a96c1a05261dba2326f31d8" end end

35.

homebrew で も公開したい cargo‑dist が全て面倒をみてくれる

36.

cargo dist init を実行して質問に答えると cargo‑dist が やってくれる • Cargo.toml の[workspace.metadata.dist]に設 定が追加 • .github/workflows/release.yml を生成

37.

cargo dist init を実行して質問に答えると cargo‑dist が やってくれる • Cargo.toml の[workspace.metadata.dist]に設 定が追加 • .github/workflows/release.yml を生成 この状態で cargo‑release で git tag を push する と

38.

cargo‑dist が やってくれる Github release と各種 installer が作成される

39.

cargo‑dist が やってくれる cargo‑dist が以下をやってくれる(設定次第) • 各種 platform(aarch64,x86 の darwin,windows, linux gnu,musl)向けの binary 生成 • shell,powershell の install script 作成 • homebrew 用 repository の更新(push 権限を渡 す必要あり)

40.

cargo‑dist が やってくれる cargo dist plan を実行すると CI で実行される 内容を確認できる workflow yaml にベタ書きされているのではな く、cargo dist plan の出力を参照するように なっている

41.

cargo‑dist が やってくれる cargo‑release と一緒に使うことが想定されてお り cargo publish と git の tag push までが cargo‑ release それ以降の配布処理が cargo‑dist という役割分 担がよかったので使ってみた

42.

監視もしたい Deploy と Release ができたので次に監視がした い

43.

監視もしたい Deploy と Release ができたので次に監視がした い OpenTelemetry を使う

44.

Rust で OpenTelemetry Rust で tracing を使っている場合 tracing-opentelemetry と opentelemetry_sdk を 使うと Logs, Traces, Metrics を取得できる

45.

Rust で OpenTelemetry 公開している Grafana dashboard

46.

Rust で OpenTelemetry Entry 取得時の Trace

47.

まとめ Nix,cargo‑{release,dist},OpenTelemetry で 楽しいツール開発