Communicate on IPv6 from home

2022-10-12 23:59:50 +0900

家のネットワークからインターネットへ出るとき IPoE を使ってたけど、家庭内 LAN のネットワークは IPv6 を off にしていた。 この LAN 内 IPv6 化していなかった理由としては、昔 Linux (だけじゃないかも)が IPv6 が利用できる状態だと 先に IPv6 で繋ぎにいこうとして IPv6 で通信できなかったら IPv4 にフォールバックするという挙動で、すごくストレスフルだった。 この挙動の対処として、カーネルレベルで IPv6 を off にしてました。 そうこうしているうちに契約している ISP が IPv6 オプションなしで IPoE を利用できるようになったので、 とりあえず IPoE だけを利用できるようにして、家庭内の LAN はそのままという状態にしていました。 いいかげんこの家庭内 LAN のネットワークを IPv6 化し、インターネットと IPv6 で通信できるようにした顛末をのこす。のこします。

家庭内 LAN 環境

  • ゲートウェイ: NEC IP38X/1210 (YAMAHA RTX1200)
  • PC: 6.0.0-gentoo

IPoE 化と家庭内 LAN の IPv6 化

設定は YAMAHA の設定例集に載ってあるのでそれを参考にします。 IPoE 化はこの設定例でいけるのですが、どうも設定したときにミスったらしく、 LAN の IP アドレスが IPv4 ではインターネットへ出ることができるが、 IPv6 ではインターネットへ出ることができない状態になってしまいました。

旧設定

どのような設定だったかは以下に

ip route default gateway tunnel 1
ipv6 prefix 1 ra-prefix@lan2::/64
ipv6 lan1 address ra-prefix@lan2::1/64
ipv6 lan1 prefix ra-prefix@lan2::/64
ipv6 lan1 rtadv send 1
ipv6 lan1 dhcp service server
ipv6 lan2 address auto
ipv6 lan2 secure filter in 1010 1011 1012 2000
ipv6 lan2 secure filter out 3000 dynamic 100 101 102 103 104 105 106
ipv6 lan2 dhcp service client ir=on
ngn type lan2 ntt
tunnel select 1
 tunnel encapsulation ipip
 tunnel endpoint address 2404:8e00::feed:100
 tunnel enable 1
ipv6 filter 1010 pass * * icmp6 * *
ipv6 filter 1011 pass * * tcp * ident
ipv6 filter 1012 pass * * udp * 546
ipv6 filter 2000 reject * * * * *
ipv6 filter 3000 pass * * * * *
ipv6 filter dynamic 100 * * ftp
ipv6 filter dynamic 101 * * domain
ipv6 filter dynamic 102 * * www
ipv6 filter dynamic 103 * * smtp
ipv6 filter dynamic 104 * * pop3
ipv6 filter dynamic 105 * * tcp
ipv6 filter dynamic 106 * * udp

この設定ではインターネットとは IPv4 でしか通信できていない状態でした。 でこのトラブルシュートとして知人(@n_kane, @paina) のちからを借りてどこまで通じてどこから通じないかを確認しました。

troubleshooting

とりあえず ping6traceroute6 で通じていないことを確認します。

$ ping6 -c 3 google.com

PING  google.com(nrt13s55-in-x0e.1e100.net (2404:6800:4004:824::200e)) 56 データ長(byte)

--- google.com ping 統計 ---
送信パケット数 3, 受信パケット数 0, パケット損失 100%, 時間 2067ミリ秒

$ traceroute6 google.com
traceroute to google.com, 30 hops max, 80 byte packets
 1  * * *
 2  * * *
 3  * * *
 4  * * *
 5  * * *
 6  * * *
 7  * * *
 8  * * *
 9  * * *
10  * * *
11  * * *
12  * * *
13  * * *
14  * * *
15  * * *
16  * * *
17  * * *
18  * * *
19  * * *
20  * * *
21  * * *
22  * * *
23  * * *
24  * * *
25  * * *
26  * * *
27  * * *
28  * * *
29  * * *
30  * * *

通ってないですね。 先述したように PC は IPv6 を on にしたばかりなのでクライアント側の設定でブロックしていないかを確認します。 まずクライアント側で考えられるのは iptables でのパケットフィルタリングですね。 ルーターの下にある PC なので、ここでブロックすることは低いのですが、確認します。

# ip6tables --list
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

なにもフィルタリングしていないですね。 ということで、クライアント側には問題なさそうですね。 どこまで通じてどこまで通じていないのか別のエンドポイントで確認します。

まず、手元と相手で tcpdump 利用してパケットが送っているか届いているかを確認します。

# tcpdump -nei enp8s0f0 icmp6
dropped privs to pcap
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on enp8s0f0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
22:35:41.158558 00:a0:de:69:40:9d > 33:33:ff:51:5e:63, ethertype IPv6 (0x86dd), length 86: fe80::212:e2ff:fe70:6144 > ff02::1:ff51:5e63: ICMP6, neighbor solicitation, who has 2409:10:a5c0:1f00:d903:ddb5:851:5e63, length 32
22:35:58.765783 ee:60:51:38:43:9c > 33:33:ff:00:00:01, ethertype IPv6 (0x86dd), length 86: 2409:10:a5c0:1f00:5ce3:afcb:9bb2:5c1b > ff02::1:ff00:1: ICMP6, neighbor solicitation, who has 2409:10:a5c0:1f00::1, length 32
22:36:09.249427 ee:60:51:38:43:9c > 33:33:ff:00:00:01, ethertype IPv6 (0x86dd), length 86: 2409:10:a5c0:1f00:5ce3:afcb:9bb2:5c1b > ff02::1:ff00:1: ICMP6, neighbor solicitation, who has 2409:10:a5c0:1f00::1, length 32

送れてはいるようで対向側にも届いていたらしく戻りのパケットは送ってたようですが、手元では戻ってくるパケットは見えていないですね。

ということはやはりルーターの設定が悪そうということが推察されますね。 設定のどこが悪いのかあやしいところを見ていきます。

最初に怪しいとおもったのはルーターのフィルターまわりです。一旦、no ipv6 interface secure filer in で全部無効化しましょう。しかしとくに変りはないです。これはフィルターが原因ではなさそうですね。

次にあやしい点は以下2つの設定

  1. ipv6 interface address
  2. ipv6 interface prefix

上のコマンドは ISP から自動で振ってきている IP を割り当てる設定で、下のコマンドは ISP から振ってきた IPv6 のプレフィックスを付けるようにするための設定となります。 どうもこの下のコマンドが邪魔なようです。 no ipv6 interface prefix で無効化できるので一旦外してみましょう。 すると

$ ping6 -c 3 google.com
PING google.com(nrt20s18-in-x0e.1e100.net (2404:6800:4004:81c::200e)) 56 データ長(byte)
64 バイト応答 送信元 nrt20s18-in-x0e.1e100.net (2404:6800:4004:81c::200e): icmp_seq=1 ttl=57 時間=6.53ミリ秒
64 バイト応答 送信元 nrt20s18-in-x0e.1e100.net (2404:6800:4004:81c::200e): icmp_seq=2 ttl=57 時間=2.73ミリ秒
64 バイト応答 送信元 nrt20s18-in-x0e.1e100.net (2404:6800:4004:81c::200e): icmp_seq=3 ttl=57 時間=2.81ミリ秒

--- google.com ping 統計 ---
送信パケット数 3, 受信パケット数 3, パケット損失 0%, 時間 2002ミリ秒
rtt 最小/平均/最大/mdev = 2.731/4.023/6.532/1.773ミリ秒

のように通りました!勝ったッ!第三部完!

おわり

以前中途半端に設定したおかげで IPv6 有効化に時間が掛ってしまった顛末をまとめました。 これで家のネットワークから IPv6 で通信できるようになりました。 ありがとうございました!

次回 katsyoshi.org お名前.COM やめるってよ

RubyKaigi 最高!

2022-09-11 23:59:50 +0900

RubyKaigi 2022 に行ってきました! ので感想を

DAY 0

今回も やんちゃハウス に楽をして泊まることにしてたのでなにも気にせず宿へ。 着いて他メンバーが来るまで宿で待機してたが、最寄り駅の周りが思った以上になにもなく、途方に暮れてました。

夕飯

もうひとり宿に着いたので入れ変わりで夕飯へ出かけたが、そもそも最寄り駅前にはなにもないので伊勢駅まで出ることにした。

この判断が間違えてたようで、伊勢駅に出てもとくに変らなかった。しかし幸い伊勢駅前に担々麺屋があったのでそこで食料摂取した。

DAY 1

この日の聞いたセトリと感想は以下のとおり

Ruby meets WebAssembly: presentation

この日のキーノートは Rubywasm 対応の話で wasi を通じてブラウザで Ruby が動かすまでのたのしいことをしゃべってたようです。 おなかいたくてトイレ行ってたら面白いところ聞き逃がしてしまった。

ランチ

適当に幕の内弁当を最初に選択。

Making *MaNy* threads on Ruby: presentation

笹田さんの発表で如何に Ruby で CPU をフルに使えるようにするかの話。 Ruby での Thread のはなしから Ractor を利用してフルフルに CPU 利用するための書きかたとかの話していました。

Building a Lightweight IR and Backend for YJIT: presentation

Ruby 3.1YJIT が入って Ruby 3.2 でサポートされる CPU アーキテクチャが増えたはなし。RubyVM(?) に YJITRuby IR を作成して JIT を実行するという話。 聞いてて疑問になった点としては、 Ruby IR では直接機械語に翻訳しているようだったが、このバックエンドに LLVM を利用していないのはなんでなんだろう。聞き逃がしているという話はあるので、詳しいひと教えて。

Tools for Providing rich user experience in debugger: presentation

debug.gemVS Code だけじゃなく、 Chrome のリモートデバッグ機能を利用したデバッグの話でした。 この機能自体はすごく便利だと思うのですが、そもそも両方とも宗教上の理由で利用できない体なので聞くだけでした。

TRICK 2022 (Returns): repos

いつも通り 変な エキセントリックなプログラムしか出てこなかったし、いつもの面子が賞もらってたのですごいなーという感想。

夕飯

この日は津駅があまりなさそうだったので、駅近くで飲むのではなく、宿寄りの場所松坂駅で飲むことにした。 ここで、津の夜情報を聞き込んだり、朝ごはん情報自体を仕入れてました。

DAY 2

2日目は、ネットワークが不安定になったりしてこちらの集中力が切れたりしたのであまり覚えていない。

朝ごはん

前日の夕飯に教えてもらった市場の人向け食堂が松坂駅前にあり、その食堂で食事をした。

Matz Keynote: presentation

Do Pure Ruby Dream of Encrypted Binary Protocol?: presentation

ノーコメント。

ランチ

この日も一番に弁当を取得。弁当はみんな大好き松坂牛ローストビーフ丼にした。感想としては、もう肉はいいかな。

自キKaigi

誘われたので参加しました。iPad で活動しようと思い corne 持っていってたので参加してた。

Ruby x BPF in Action: How important observability is: presentation

Hunting Production Memory Leaks with Heap Sampling: presentation

このあたりネットワークが不安定になり、セッションが中断されたりしたためあまり覚えていない。

立ち話

久し振りの対面での参加だったのでセッションあまり聞かずに受け付け前で立ち話している人たちがいたので、その立ち話に参加した。 たまたま、最近読んでる本の翻訳者がいたのでこれからの話などを聞いたりしていた。

Caching With MessagePack: presentation

Ruby Committers vs The World

夕飯

夕飯は、駅近くのお店でかるく3人で。

こんなリプライがきてたようなので一緒にいたひとにまかせた。ギリギリまで粘ってたので帰宿後すぐ就寝。

DAY 3

3日目はそもそも前2日の疲れが出たりしたのかほとんど覚えていない。あと ruby puzzle をやっていてセッションをあまり聞けていない。

朝ごはん

Megaruby - Running mruby/c programs on Sega Mega Drive: presentation

これに間に合うように出たはずだったが、間に合わず聞いていた。メガドライブすげえ。

Automatically Find Memory Leaks in Native Gems: presentation

Fast data processing with Ruby and Apache Arrow: presentation

Fixing Assignment Evaluation Order: presentation

Stories from developing YJIT: presentation

まとめ

3年ぶりの現地開催だったので参加してきました。対面での参加はやはりよいもので新しい出会いや、疑問を本人、解っている人に直接聞くことができてすばらしい体験でした。

三重について

三重県の酒のイメージは、行く前は「作」「 而今」「伊勢角谷屋麦酒」というイメージでした。 とくに日本酒は美味しいイメージがあり、知らない日本酒もあったりするんだろうなあと思っていました。 行ってみると日本酒はイメージと変わらないのですが、だいたい似た味の傾向で飽きるというかなんというか 美味しいんだけど、好きじゃないという感想になってしまった。 ビールについては瓶ビールしか飲まなかったので感想はなしで。

三重は大きな街が比較的分散しているようで、津も松坂も伊勢も鳥羽も駅前が小さく感じました。 とくに0日目の食事が大変で、調達が難しかった。

Ruby gem で Rust をつかって爆速にしたい!!!!!!11

2022-08-12 13:59:59 +0900

Ruby GemsRustNative として利用可能になった のでとりあえず UUIDv4 を生成してみた。

リポジトリ

katsyoshi/rust_uuid - GitHub

準備

Ruby 側の gem に Rust を利用する準備として rb_sysrake-compiler を利用します。この二つの gem は native compile するためにインストールしておきます。 Rust 側から Ruby へ関数を公開するために rb-sysmagnus を利用します。

gem install

とりあえず cargo で Rust のパッケージを作って Rust を書いてみます。

> bundle gem rust_uuid --mit --ext rust_uuid # --ext を指定してnative build する gem を作成
> cd rust_uuid # 作成した gem のディレクトリへ移動
> cd ext/rust_uuid # ビルドするディレクトリへ移動
> cargo init . --lib # cargo を初期化
> rm -f *.c *.h # C のファイルが生成されるので削除
> cargo add rb-sys rb-allocator
> cargo add magnus --features rb-sys-interop
> cargo add uuid --features v4 # uuid v4 を指定

ext/rust_uuid/extconf.rb を以下のように編集します。

@@ -1,5 +1,6 @@
 # frozen_string_literal: true
 
 require "mkmf"
+require "rb_sys/mkmf"
 
-create_makefile("rust_uuid/rust_uuid")
+create_rust_makefile("rust_uuid/rust_uuid")

次に ext/rust_uuid/src/lib.rs を以下の様に変更します。

use magnus::{define_module, function, prelude::*, Error};
use rb_allocator::ruby_global_allocator;
use uuid::Uuid;

ruby_global_allocator!();

// UUIDv4 を文字列として公開
fn v4() -> String {
    Uuid::new_v4().to_string()
}

#[magnus::init]
fn init() -> Result<(), Error> {
    let module = define_module("RustUUID")?;
    // RustUUID.v4 と利用するようにシングルトンメソッドを定義
    module.define_singleton_method("v4", function!(v4, 0))?;
    Ok(())
}

これまでできたら一旦 Rust をコンパイルしましょう。

> cd ext/rust_uuid
> cargo build
> git add .
> rake build
.... # install cargo dependencies and packages
cp: '/home/katsyoshi/Program/Ruby/rust_uuid/tmp/x86_64-linux/rust_uuid/3.1.2/target/release/librust_uuid.so'stat できません: そのようなファイルやディレクトリはありません
gmake: *** [Makefile:551: foo_bar.so] エラー 1
rake aborted!
Command failed with status (2): [/usr/bin/gmake...]

Tasks: TOP => build => compile => compile:x86_64-linux => compile:foo_bar:x86_64-linux => copy:rust_uuid:x86_64-linux:3.1.2 => tmp/x86_64-linux/rust_uuid/3.1.2/rust_uuid.so

とエラーになります。 これは ext/rust_uuid/Cargo.toml の設定が足りていません。そこで以下を追加してみてください。

[lib]
crate-type = ["cdylib"]

追加したら gem をビルド&&インストール&&試してみましょう!

> rake install
....
> ruby -rrust_uuid -e 'puts RustUUID.v4'
2be6f4d2-200b-4d08-9a1a-11fa523b316b

べんちまーく

以下、 SecureRandom.uuid との比較用のベンチマークコードを示します。

require "benchmark/ips"
require "securerandom"
require "rust_uuid"

Benchmark.ips do |x|
  x.report("standard") { SecureRandom.uuid }
  x.report("rust lib") { RustUUID.v4 }
  x.compare!
end

結果発表〜

Rust を利用することでだいたい 5 倍ほど速くなっています。

> ruby bentimark.rb
Warming up --------------------------------------
            standard    36.437k i/100ms
            rust lib   177.585k i/100ms
Calculating -------------------------------------
            standard    365.407k (± 1.4%) i/s -      1.858M in   5.086491s
            rust lib      1.793M (± 1.8%) i/s -      9.057M in   5.053179s

Comparison:
            rust lib:  1792925.9 i/s
            standard:   365407.3 i/s - 4.91x  (± 0.00) slower

ruby bentimark.rb  9.88s user 4.30s system 99% cpu 14.175 total

TOO HAYAI

まとめ

簡単に Rust を利用して速くしてみました。 思った以上に速くなっていたので重い処理をする場合に CC++ 以外でも簡単に利用できるようになって 選択肢が増えたのはよいことでした。

実はこの uuid crate の features に fast-rng を追加すると 10 倍速くなるんですが、 ruby 側の終了時に SEGV してしまうので載せていないです。 SEGV しないように原因を調査などはまた今度。

Hello, Wezterm

2022-03-19 18:00:00 +0900

tmux + Allacritty が疲れてきたのではてぶで流れてきた weztermsixel を利用できてよさそうだったので試してみることにした。

設定

設定ファイルが lua でカスタマイズがいろいろとできるのでまずは色を代えてみます。

local wezterm = require 'wezterm'
return {
  color_scheme = "Dracula",
}

プログラミング言語でカスタマイズができるので以下のようにアクティブなタブへの移動のキーバインドのカスタマイズができます。

local wezterm = require 'wezterm'
local move_keys = {}

for i = 1, 9 do
   table.insert(move_keys, {
      key = tostring(i),
      mods = "CTRL",
      action = wezterm.action{ ActivateTab = i - 1, },
   })
end

return {
   color_scheme = "Dracula",
   disable_default_key_bindings = true, -- 初期のキーバインドは利用しない場合
   keys = move_keys,
}

こんな感じで設定できるので便利です。

このキーバインドは任意のイベントも設定でき、任意のイベントを利用してアクションを定義できます。以下の例では、Paneを開い監視用のプログラムを開きます。

local wezterm = require 'wezterm'
wezterm.on("open-nvtop-and-ytop", function(win, pane)
   win:perform_action(wezterm.action{ SplitHorizontal = { domain = "CurrentPaneDomain", args = { "nvtop", }, }, }, pane)
   win:perform_action(wezterm.action{ SplitVertical = { domain = "CurrentPaneDomain", args = { "ytop", "-ps", }, }, }, pane)
end)

return {
   keys = { { key = "r", mods = "CTRL", action = wezterm.action{ EmitEvent = "open-nvtop-and-ytop", }, }, },
}

とすると以下のようになります。 便利!

こんな便利なものということで systemd でデーモン化しています。

[Unit]
Description=GUI Accellarated terminal
Documentation=

[Service]
Type=forking
ExecStart=/usr/local/bin/wezterm-mux-server --daemonize
Restart=on-failure

[Install]
WantedBy=default.target

で起動しておいています

問題点

と設定ファイルの例書いてみたのですが、とても大きな問題点にブチあたったので書いておきます。

wezterm には wezterm-mux-server というマルチプレクサ(tmuxのように扱うため)のサーバーモードプログラムがあるのですが、こいつがどうも wezterm とは挙動が異なり、前述した監視用のキーバインドが微妙に異なった挙動となってしまっています。サーバーモードに接続した場合の挙動は以下のようになります。

1つ目はpaneの位置が期待したとおりになっていない。2つ目は ytop が起動していないというので2つ目の方は気にしなければいいのでまあいいかと思っている。1つ目の問題は許容できていないので一旦はこのキーバインドは封印となっています。

おわり

長年利用してた tmux を捨てて wezterm を利用しはじめた。 設定が lua で書けるのが体験的にとても良いのでこれからも利用するかなと。 weztermsixel 利用した画像表示ができるようになったのが便利なので「よしっ!」

冬やすみ

2022-01-03 23:59:59 +0900

冬やすみの間、やりたいこと、やっといたほうがいいやつをやってました。 ひとつは xremap の設定ともうひとつは CO2-mini から CO2 を見える ようにした。

今回は、 mackerel で見えるようになった CO2 の値を Slack へ定期的に投げるようにします。今回も Rust を利用しています。

準備

準備として、 mackerel 1Slack 2 両アプリケーションの投稿 API 用 Token をそれぞれ用意します。 各公式ページにあるように生成、取得するだけでよいです。

mackerel 側は ホストメトリック API を利用します。 Slack 側は chat.postMessage API を利用します。 各 API に対して取得した API Token を用いて curl で確認しておきます。

実装

今回は対話式の bot ではないので、 RTM を利用せずに、HTTP クライアントだけで構成しています3RustHTTP クライアントとして hyper4 を利用します。 TLShyper_tls を利用しています。

実装とは言っても対象の mackerel の APIを叩き値を取得して、 その値を元に Slack へポストするだけです。

mackerel での値取得時に気をつける点としては、ホストメトリック API では host名 ではなく、 host id がパラメーターとなっていますので注意が必要です。 まずレスポンスを入れる構造体を定義します。

#[derive(Deserialize)]
pub struct Metric {
    pub time: i64,
    pub value: i16, // 今回は co2 の値なので i16 としている
}

#[derive(Deserialize)]
pub struct ResponseMetrics {
    pub metrics: Vec<Metric>,
}

つぎに以下のようにしてリクエストを組みたてて、値を取得しています。

let https = HttpsConnector::new();
let req = hyper::Request::builder()
    .method(hyper::Method::GET)
    .uri(url)
    .header("X-Api-Key", api_key)
    .body(hyper::Body::empty())?;
// https として request する
let client = hyper::Client::builder().build::<_, hyper::Body>(https);
let res = client.request(req).await?;
let body = hyper::body::aggregate(res).await?;
let json: ResponseMetrics = serde_json::from_reader(body.reader())?;
let metrics = json.metrics;

値を取得したら、今度は同じように Slack の方も構造体を定義します。

// リクエスト用構造体
#[derive(Serialize)]
pub struct SlackMessage {
    pub channel: String,
    pub sub_type: String,
    pub text: String,
    pub username: String,
    pub as_user: bool,
}
// レスポンス用構造体
#[derive(Deserialize)]
pub struct PostMessage {
    #[allow(unused)]
    channel: String,
}

リクエストを組みたてて、POSTします。 見てわかると思いますが、ほとんど mackerel と変わらないです。

// リクエスト body を json に変換
let json = serde_json::to_string(&SlackMessage {
    channel: "channel".to_string(),
    sub_type: "bot_message".to_string(),
    text: "message".to_string(),
    username: "botname".to_string(),
    as_user: true,
})?;

let https = hyper_tls::HttpsConnector::new();
let req = hyper::Request::builder()
    .method(hyper::Method::POST)
    .uri(url)
    .header("Content-Type", "application/json")
    .header("Authorization", format!("Bearer {}", get_env("SLACK_API_KEY")))
    .body(hyper::Body::from(json))?;

let client = hyper::Client::builder().build::<_, hyper::Body>(https);
let res = client.request(req).await?;
let body = hyper::body::aggregate(res).await?;
let _json: PostMessage = serde_json::from_reader(body.reader())?;

ポストするメッセージを作る際に2つのことをしています。 まずは timeUNIX EPOCH TIME からローカルの時間を表示するようにしています。 それと CO2 の値に依って絵文字を追加するかどうかを入れています。 -1 とか予定していない値が入ってきた場合は panic! するようにしています。

// chrono を利用して unix time からローカルの文字列へ変換
let t = chrono::Local.timestamp(time);
let v = match value {
    0..=700 => ":large_green_circle:",
    701..=1000 => ":large_yellow_circle:",
    1001.. => ":red_circle:", // なんで slack は :large_red_circle: を用意していないんだろうか
    _ => panic!("unexpected number!!"),
};

こうやってポストされたメッセージは以下のようになります。

絵文字つきでポストされましたね。

まとめ

Rustbot を作ってみました。 と言ってもただの HTTP クライアントbot なだけですけど。 一旦 Slack でも見えるようになったので今度は Nature Remo と連携して気温や湿度での自動化ができたらいいな。


  1. https://mackerel.io/ja/api-docs/ 

  2. https://slack.com/intl/ja-jp/help/articles/215770388-API-%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%81%AE%E7%94%9F%E6%88%90%E3%81%A8%E5%86%8D%E7%94%9F%E6%88%90 

  3. slack-rs という便利ライブラリがあるのですが、ちょっと触ってみたこれは必要なんだっけ?となってやめました。 

  4. 公式の README にあるようにこの場合は reqwest を利用するほうがよかったかもしれない。TLS は直接 hyper が対応していなかったりしてすこし面倒です。 

今年飲んだコーヒー豆の種類 2021

2021-12-31 23:59:59 +0900

今年もコロナでどこにも行くにしても行きにくかったし、 店もどこもあまりやってなかったようだったので今年も酒ではないまとめを。

苦いコーヒーすこし飽きてきたなーとか、あんまり大量にのむのはなーと思ってたところ1に スペシャルティコーヒー専門店が近所にできていて、そこで飲んで教えてもらったコーヒーが 気に入りよく通うように。

普段の飲む量を1日1杯のみに抑えるために多少高くてもおいしい豆で1杯で満足できる豆を買うことにした。

買ったというのがわかっている豆。

  • HAMBELA WAMENA, HEIRLOOM, Natural, エチオピア
  • Carmo De Minas Santuario Sul, Yellow Bourbon, Citrus Sweetness, ブラジル
  • NYERI KARATINA, SL28SL32RUIRU11, Fully Washed, ケニア
  • KAKAMEGA ISULU, SL28SL32RUIRU11, Natural Anaerobic, ケニア
  • WEST ARSI GORA KONE, HEIRLOOM, Washed, エチオピア
  • GEDEB WORKA, HEIRLOOM, Special Process Natural, エチオピア
  • EL PARAISO RED FRUITS, CASTILLO, DOUBLE ANAEROBIC WASHED, コロンビア
  • EL PARAISO LYCHEE, CASTILLO, DOUBLE ANAEROBIC WASHED, コロンビア
  • NYERI MAGANJO, SL28SL32RUIRU11, Fully Washed, ケニア
  • Fazenda Guariroba, Yellow Catuai, Double Fermentation Black Honey, ブラジル

感想

を書くつもりが、そもそも感想メモをほとんど残していなかった。いくつか残しているのでそれを。

  • EL PARAISO RED FRUITS: 別ロットはピーチティのような感じであったが、今回はかなりフルーティな味でライチな感じです。
  • Fazenda Guariroba: 香りが柑橘系というかレモンの香りがする。味はスッキリしてて口に含んだ酸味は少なく、後味としての酸味が強くのこって美味しい。

まとめ

1年くらい前に社内 Slack にコーヒーの感想をまとめるためのチャンネル作ったけど、 まったく活用していなくて感想がほとんど残っていない。 おいしいこと以外は思いだせるわけもなく……


  1. ここ1,2年コーヒー飲みすぎると胃が痛くなるのに気がついた。 

custom CO2-mini で CO2 を見えるようにしよう

2021-12-30 16:59:59 +0900

コロナになって結構前に custom CO2-mini話題になった ので買って放置してあったの1 を活用しようと思いたった。 とりあえず値は取得はできているので mackerel との連携をしてグラフに表示できるようにします。 あと mercker-pluginRust で書いてみたいとおもったので、やってみることにしました。

以下のリポジトリにコードはあります。

katsyoshi/mackerel-plugin-co2mon - GitHub

mackerel plugin として作る

mackerel に投稿する前にこの custom CO2-miniRust で読めるのかを調査してみましたら、co2mon がピンズドな感じでありました。 確認としてセンサーの読み込みは co2monREADME の通り にやることで読みとることができます。

センサーの値が読み込めるようになったら、今度は mackerel へ投げれるようにします。 と言ってもやることは 公式にあるよう に以下のフォーマットで標準出力に出すだけのようです。

{metric name}\t{metric value}\t{unix epoch time}

ということなので適当に metric nameCO2MINI.co2/temp.living 2 にして出力しています。 mackerel-plugin として動かすために、 mackerel-agent.conf に以下のような設定を追加し、再起動することでグラフが追加できます。

[plugin.metrics.CO2MINI]
command = ["/path/to/build/bin/mackerel-plugin-co2mon"]

グラフは以下のように表示されました!やったね!

おわり

ずっとやろうやろうと思ってた Rustmackerel のプラグイン作成、 面倒で先延しにしてたのですが、チョットやってみたらすぐにできたのでよかったです。 今後としては CO2 の値に応じて窓開けたりできるようにしたいなあと思っています3


  1. Amazon で確認したら買ったの 2020/03 だった…… 

  2. mackerel のグラフ表示部分のタイトルが custom.CO2MINI.co2.living となり、メーカー名も入っていいじゃんとなった。 

  3. 窓開閉する道具もないのでそこから仕入れる必要がありいつになるか不明です。 

いんとろでぅーす xremap

2021-12-26 13:59:59 +0900

仕事で利用したりしている Slack などのキーボードでの操作が面倒になってきたので、 emacs keybind が利用できるようにするため xremap を利用することにした。

この記事はその利用するまでの顛末をメモとして残す。

導入

これは、さくっと cargo install xremap でインストールできます。 rust をまだ導入していない方は 公式ページのインストール を参考にインストールしてください。

起動!!!

これも簡単で以下のコマンドで起動します。

xremap /path/to/your/xremap/config.yml

エラーに遭遇

起動してみると以下のようなメッセージが出て起動ができませんでした。

Selecting devices from the following list:
------------------------------------------------------------------------------
/dev/input/event0 : Power Button
/dev/input/event1 : Power Button
/dev/input/event2 : HDA NVidia HDMI/DP,pcm=3
/dev/input/event3 : HDA NVidia HDMI/DP,pcm=7
/dev/input/event4 : HDA NVidia HDMI/DP,pcm=8
/dev/input/event5 : HDA NVidia HDMI/DP,pcm=9
/dev/input/event6 : HDA NVidia HDMI/DP,pcm=10
/dev/input/event7 : HDA NVidia HDMI/DP,pcm=11
/dev/input/event8 : Pekaso The Fortitude60 Keyboard
/dev/input/event9 : Pekaso The Fortitude60 Keyboard Mouse
/dev/input/event10: Pekaso The Fortitude60 Keyboard System Control
/dev/input/event11: Pekaso The Fortitude60 Keyboard Consumer Control
/dev/input/event12: Kensington Kensington Slimblade Trackball
/dev/input/event13: Burr-Brown from TI               USB Audio CODEC
/dev/input/event14: HD Web Camera: HD Web Camera
------------------------------------------------------------------------------
Selected keyboards automatically since --device options weren't specified:
------------------------------------------------------------------------------
/dev/input/event8 : Pekaso The Fortitude60 Keyboard
------------------------------------------------------------------------------
Error: Failed to build an output device: no such file or directory (os error 2)

で、答えは出てるので設定ファイル、対象となる入力デバイスなどを見ますが、 これらのファイルはあるのでわからんとなります。

しかたないのでソースをダウンロードして手元でデバッグしてみます。 rust というか cargo は便利で、cargo run でソースをいじったあとすぐにコンパイルして利用することができます。 今回はメンドウなので怪しいところに println 文を挿入して実行してみます。 そうすると、どうやら src/output.rs の 39 行目の VirtualDeviceBuilder に問題がありそう ということがわかりました。

この行のどこに問題あるんだ?と思い利用しているこのライブラリ evdev を見ることにしました1。 そうすると /dev/uinput が必要 ということがわかります。 それで /dev/uinput があるかどうか ls で見ますが、当然無いので無いです。 なぜ無いのかというと INPUT_UINPUT でドライバーを入れていなかったようです。 なのでカーネルのビルトインとしてビルドして再起動。

Defined at drivers/input/misc/Kconfig:513
     Prompt: User level driver support
     Depends on: INPUT [=y] && INPUT_MISC [=y]
     Location:
       -> Device Drivers
         -> Input device support
           -> Generic input layer (needed for keyboard, mouse, ...) (INPUT [=y])
             -> Miscellaneous devices (INPUT_MISC [=y])
               -> User level driver support

再起動したら、確認を行ないます。

$ xremap ~/.config/xremap/config.yml
Selecting devices from the following list:
------------------------------------------------------------------------------
/dev/input/event0 : Power Button
/dev/input/event1 : Power Button
/dev/input/event2 : HDA NVidia HDMI/DP,pcm=3
/dev/input/event3 : HDA NVidia HDMI/DP,pcm=7
/dev/input/event4 : HDA NVidia HDMI/DP,pcm=8
/dev/input/event5 : HDA NVidia HDMI/DP,pcm=9
/dev/input/event6 : HDA NVidia HDMI/DP,pcm=10
/dev/input/event7 : HDA NVidia HDMI/DP,pcm=11
/dev/input/event8 : Pekaso The Fortitude60 Keyboard
/dev/input/event9 : Pekaso The Fortitude60 Keyboard Mouse
/dev/input/event10: Pekaso The Fortitude60 Keyboard System Control
/dev/input/event11: Pekaso The Fortitude60 Keyboard Consumer Control
/dev/input/event12: Kensington Kensington Slimblade Trackball
/dev/input/event13: Burr-Brown from TI               USB Audio CODEC
/dev/input/event14: HD Web Camera: HD Web Camera
------------------------------------------------------------------------------
Selected keyboards automatically since --device options weren't specified:
------------------------------------------------------------------------------
/dev/input/event8 : Pekaso The Fortitude60 Keyboard
------------------------------------------------------------------------------

yatta 起動できた! あとは、アプリでキーバインドが効いているかどうかを確認して、 Window Manager である i3 の起動時に xremap が起動するようにしたりしています。

おわり

最近、 Mac との行き来をしていると emacs keybind が使えないときにちょっといらっとしますので使えるようにキーバインドを変更してみました。 設定ファイルの動的読み込みに対応していないのがちょっと面倒なのですが2、これで Slack などで C-a で行頭にもどれるようになりました。便利。


  1. はじめは似た名前のライブラリの evdev-rs を見てたのですが、対象であるはずのファイル内に宣言されていないのでちょっととまどい、このライブラリは違うやつだとなり crates.io で再検索して発見しています。 

  2. どうせ1回確認できたら再起動する必要はないので問題ないといえば問題ないけど、ちょっと面倒。 

やんちゃクラブとRubyistと川

2021-12-06 23:59:59 +0900

おはようございます、 2021年、12月6日 のよるだったり、12月7日の朝だったりします。

これは やんちゃクラブリスナーアドベントカレンダー の6日目だったり、 Rubyist近況[1]アドベントカレンダー の7日目だったりします。

最近仕事としては Rails 6.1 にしたり、 Ruby-3.0 にしてたり、java 書いてたりしています。

コロナになり、RubyKaigi後恒例の がなくなってかなりさみしい思いをしている方もいらっしゃるとおもいますので、 東京近郊でのよい をまとめてみたいとおもいます。

  1. 荒川: 虹の広場
  2. 墨田川: 墨田公園
  3. 多摩川: 稲田堤
  4. 江戸川: 妙典公園、江戸川河川敷緑地

荒川: 虹の広場

ここは yancyaさん の地元で一緒によく行く川です。 ここの 最高 は大きな街(北千住)が近く、ふらっと行っても調達が楽なところで、たべもの、のみものなんでも楽に調達できます。 とくにのみものは国外のクラフトビールがたくさん買える場所あるので 最高 なのと、クラフトビール作ってる場所があるので 最高 なのです。 また、公園のような場所なので花火できます。バーベキューとか火を使うのは岩渕水門あたりじゃないとできないので気をつけてください。

周りに邪魔をするようなものがとくにないので、日の入りやスカイツリーが綺麗に見えます。 そばに電車(東武伊勢崎線、TX、常磐線)が通っているので電車を眺めるのもいいです。

時期としては春から秋にかけて行くのが 最高 ですね。冬はまだ行ったことないのでそのうち試してみるかもしれないです。

墨田川: 墨田公園

墨田公園といえば さくらの名所100選 に選ばれるほどの桜の名所です。 ここも浅草という大きな街が近くなので、調達が楽です。しかしながら、桜の季節は人が多いので調達は事前にして するのがよいです。

見所としてはもちろん桜です。ここも東武伊勢崎線がとおってるのと、浅草名物アサヒビールの建物、スカイツリーが見えるので桜の時期とくに映えますね。 やんちゃクラブで紹介されたように、水上バスの発着場があるので水上バスを利用するのもおもしろいと思います。

時期としては 最高 なのはもちろん桜の時期です。それ以外の時期でも場所が浅草なので、風が強い日以外はオールシーズン デキルと思います。 風が強かったら逃げれる場所たくさんあるのでよいですよ。

多摩川: 稲田堤

ここの 最高 さは、たぬきや という夏の間だけやっている(と飲み仲間に教えてもらった) 川の家があったのですが、去年あたりに終ってしまった。川辺にあるお店で、川を眺めながら飲むビールとか 最高 でした。

見所としては今説明したたぬきやです。ジェットスキーとかできるんならもっと楽しめるんじゃないんですかね。

最高 な時期としては夏だったのですが、もう行ってもね……

江戸川: 妙典公園、江戸川河川敷緑地

ここは虹の広場とは違い、バーベキュー場があり火が使えるようです。火が使えるのでスモークとかやると 最高 かと。 ただ、駅から遠いのと、街が近くないので調達は事前にやっておくとよいです。近くに大型スーパーがあるのですが、クラフトビールなどの飲みものがイマイチ(個人的感想)です。

最高 な時期は夏じゃないですかね、BBQとかはよくわからないですが……

まとめ

最高 な東京の をまとめてみました。コロナのため最近 できていないですので、みんなコロナ開けたら しような!

やんちゃクラブリスナーアドベントカレンダー の次は12/7の igaigaさん です。 Rubyist近況[1]アドベントカレンダー の次は12/10のKirika_K2さんです。

Octopress 脱出

2021-09-13 00:00:00 +0900

長年利用してた Octopress がずいぶん前にサポート外になってたので Jekyll へ変更することにした。

問題点

サポート外になったことによる問題点があり、その問題によって変更することになった。 問題点としては、 Pygments.rbCompass と利用している Ruby のバージョンが 2.3.7 というのが主であった。

変更

やったことは以下のとおり。

  1. gem の整理
    • 最初に不要な gem を削除。特に消したいのは Pygments.rbCompass それ以外にも不要なものがあるので消す。
  2. ディレクトリの整理
    • posts は元々の設定が source/_posts に入れていたが、 _posts に変更
    • 画像も同様に source/images だったものを images に変更
  3. テンプレートの整理
    • テンプレート minima を利用するにあたり _includes などの中身を整理
  4. プラグインの整理
    • そのうち theme も含めて検討したい
  5. Rake コマンド の整理
    • とりあえず octopress で利用してた Rakefile から必要最低限の変更のみ実行。

まとめ

日曜日の夜中 RubyKaigi の日記 をポストしてからこのリポジトリを jekyll にしようと 雑に 弄ってたら、 rake generateUnknown language: xml という謎の Pygments エラーが出てしまった。 このエラーを修正しようとしがんばってみたが、失敗して修正できなかったので jekyll に変更したものでデプロイした。

そんなこんなあって Octopress はやめて jekyll に変更しました。