その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

builderscon 2019見本市 (土曜12時から) で自作ガジェット展示します

id:uzulla, id:mackee_wらと共に自作のE-バッジを展示します!
というかこのブログの内容ママです!!

ここには本物があります.
ぜひお立ち寄りください!!!

ところでチップのデータシートを見ながらあれこれコードを書いて試しているんですが,どうやっても一部機能を実装することが出来ないでいます,これはなんなんだ……当日お立ち寄りの方でお詳しい向きがあれば是非教えていただきたく思います!

よろしくお願いいたします.

tcpdumpで今すぐキャプチャ内容を全部ファイルにflushしてくれ!! というとき

tcpdumpはキャプチャした内容をバッファに蓄積してバッチ的にflushするので,うっかりプロセスを即断するとキャプチャしていた内容をdrainできないことがままあります.困りますね.

www.tcpdump.org

Using the SIGUSR2 signal along with the -w flag will forcibly flush the packet buffer into the output file.

というわけでここに書いてあるとおり,SIGUSR2tcpdumpのプロセスに対して発行してあげるとその時点のバッファの内容をファイルに吐き出します (ただし -w フラグによって出力先ファイルを指定している,すなわちファイル書き出しモードにしている必要がある).

If the -w option is specified, make the saved raw packet output ``packet-buffered''; i.e., as each packet is saved, it will be written to the output file, rather than being written only when the output buffer fills.

あるいは -U (--packet-buffered) フラグを -w フラグとともに利用するというのも良いでしょう.ただ,この際はバッファをバイパスして直接ファイルに書き込むような挙動となるので,tcpdumpdaemonとして常に動かしているような環境ではパフォーマンスの問題が発生する可能性があるので注意が必要そうです.


なお,-B オプションを使ってバッファサイズを0にするとどうなのか……というとこれは

tcpdump: invalid packet buffer size 0

と出て動きません.なるほど〜,そりゃそうですね.

TypeScriptを使ってアプリケーションの設定ファイルを書く

アプリケーションの設定ファイルと言えばjsonyamlなんかで書くことが多いと思うんですが,最近はTypeScriptで設定ファイルを書いております.このような感じ:

export interface ApplicationConfig {
  readonly listenPort: number;
  readonly timeout: number;
  readonly apiBaseUrl: string;
  readonly loggerOptions: LoggerOptions;
}

こういう感じで設定のinterfaceを定義しておいて

export class ProductionConfig implements ApplicationConfig {
  readonly listenPort = 5963;
  readonly timeout = 5000;
  readonly apiBaseUrl = "http://internal-api.example.com";
  readonly loggerOptions = {
    level: 'info',
  };
}

// TypeScript (JavaScript) 内で使うなら以下のようにしておくと便利そう (例A)
const productionConfig = new ProductionConfig();
export { productionConfig };

というふうに実際の設定を記述するという感じです.


メリットとしては,

  • 「何が設定項目なのか」が定義により明らかになる
  • 設定漏れが基本的に無い
    • これはinterfaceのサポートによるもの
  • 型のサポートがある
    • 設定の構造化ができる
  • 継承が使える
    • というかTypeScriptの言語機能を使ったコードが書ける

といったあたりが挙げられると思います.

interfaceの定義によって,「どういった項目が設定されるべきなのか」が「型情報も含めて」明示できるというのは利点の一つと言って良いと思います.

また,ウェブアプリケーションだと例えば本番環境用の設定,ステージング環境用の設定,開発環境用の設定……というふうに複数の設定が存在していることがままあると思うのですが,それぞれの環境のためにinterfaceを満足した設定を記述 (実装) してあげるだけで,漏れが無い (つまりそれぞれが等価な振る舞いをする) 設定を安全に用意することができるようになります.
当然のことながら,設定の実装クラスがinterfaceを実装しきらなかった場合はコンパイルエラーが出るので堅牢です.

型のサポートが得られるというのは言うまでもないですね.安全! 型定義の無い設定を取り扱う際に苦労することがままありましたからね……
あと自分で定義したclassについてもpropertyの型にすることができるので便利です.

個人的には継承が使えるというのは便利ポイントの一つだと思っていまして,例えば「基本的な動作はまったく同じなんだけど一部の機能だけ有効 (あるいは無効) にしたい」みたいなことがあったときに継承は便利に使えるかな〜と思っています.例えばこのような感じ:

export interface ApplicationConfig {
  readonly port: number;
  readonly tcpdumpEnabled: boolean;
}

export class ProductionConfig implements ApplicationConfig {
  readonly port = 5963;
  constructor(readonly tcpdumpEnabled: boolean = false) {
  }
}

export class ProductionInspectorConfig extends ProductionConfig{
  constructor() {
    super(true);
  }
}

このようにしておくと,基本的には ProductionConfig と基本的には同じ設定でありながらも, tcpdumpEnabledtrue にした ProductionInspectorConfig をお手軽に作れることとなります.
もちろん通常のソフトウェアにおける継承と同じで,is-aとして取り扱える (に等しい) 状況以外で使うと良くないことが起きると思うしそもそも継承を使うと複雑さが容易に増すので,そこは用法用量を守って……という感じでしょう.というかこれはTypeScriptの言語機能を設定記述に使えるという話に過ぎませんね.


あとはTypeScript (JavaScript) 内で使うのならば個別の設定のインスタンスをexportしてしまうか (上記の例A),あるいはinterface側に例えば以下のようなコードを書いて,それによって得られたインスタンスをexportしてしまえば便利そうです:

export interface ApplicationConfig {
  ...
}

const appConfig: ApplicationConfig = (() => {
  const nodeEnv = process.env.NODE_ENV;
  switch (nodeEnv) {
    case 'local':
      return new LocalConfig();
    case 'staging':
      return new StagingConfig();
    case 'production':
      return new ProductionConfig();
    default:
      throw new Error('invalid NODE_ENV: ' + nodeEnv);
  }
})();
export { appConfig };

また,TypeScript以外でこの設定を利用したい,つまり単なる設定記述言語としてこれを利用したい場合は生成した設定インスタンスJSON.stringify()に食わせてしまえば他の処理系でも取り扱えるJSON形式の設定が得られるのでそのようなスクリプトを書くとポータブル.良いですね.良かった良かった.


と,このような感じでした.TypeScriptは書き味が比較的ライトなので,設定ファイル用途にも書きやすくて良いですね.

systemdで管理しているserviceがopenできるfile descriptorの上限数を増やす

systemdのバージョン

# systemd --version
systemd 237

TL;DR

ServiceLimitNOFILEを設定すると良い.他の特定のリソースについての制限もどうようにかけることが可能です.

ドキュメントは man systemd.exec で参照できます (ウェブ上はこれが正しいリソース? http://man7.org/linux/man-pages/man5/systemd.exec.5.html).

挙動の検証

現状確認

テストのためにfileを開きまくるperlのscript.ついでにprocのlimit (/proc/{PID}/limitsの中身) も出力する:

#!/usr/bin/env perl

use strict;
use warnings;
use feature qw/say/;

open my $fh, '<', "/proc/$$/limits";
say do { local $/; <$fh> };

my @fhs;
for (my $i = 0; $i <= 2000; $i++) {
    my $filename = "/tmp/test.${i}";
    open my $fh, ">", $filename or die "$filename: $!";
    push @fhs, $fh;
}

特に何も考えずにsystemdのservice fileを書いてみます.

[Unit]
Description=test

[Service]
Type=oneshot
WorkingDirectory=/tmp/test

ExecStart=/usr/bin/perl run.pl

[Install]
WantedBy=multi-user.target

で,実行してみます

Starting test...
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             3841                 3841                 processes
Max open files            1024                 1048576              files
Max locked memory         16777216             16777216             bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       3841                 3841                 signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

/tmp/test.1020: Too many open files at run.pl line 13, <$fh> line 1.
test.service: Main process exited, code=exited, status=24/n/a
test.service: Failed with result 'exit-code'.
Failed to start test.

Too many open filesで死にます.Max open filesは1024のようですね.ulimit -nで表示される現状のデフォの値っぽい.

LimitNOFILEを設定してみる
[Unit]
Description=test

[Service]
Type=oneshot
WorkingDirectory=/tmp/test

ExecStart=/usr/bin/perl run.pl

LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

LimitNOFILE=65536をserviceの設定に追加してみます.それでscriptを実行:

Starting test...
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             3841                 3841                 processes
Max open files            65536                65536                files
Max locked memory         16777216             16777216             bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       3841                 3841                 signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

Max open filesが65536になってますね.おかげで実行にも失敗しない! 良かった良かった.

Starting test...
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             3841                 3841                 processes
Max open files            10                   10                   files
Max locked memory         16777216             16777216             bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       3841                 3841                 signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us
/tmp/test.6: Too many open files at run.pl line 13, <$fh> line 1.
test.service: Main process exited, code=exited, status=24/n/a
test.service: Failed with result 'exit-code'.
Failed to start test.

試しにLimitNOFILE=10にしてみた様子.逆方向にもちゃんと絞れていることがわかります.

proxy-protocol-jsリリースした & Kyoto.js #16で喋ってきました

表題の通りproxy-protocol-jsをリリースしました.

github.com

www.npmjs.com

Kyoto.js #16の発表資料は以下です.

スライドでも簡単に説明しましたが,PROXY protocolというのはHAProxyが提唱しているTransport層 (L4) においてoriginalの送信元を維持したままproxyするためのprotocolになります.HTTPにおけるX-Forwarded-ForのL4版という感じですね.詳しくはこちら: http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt


で,このPROXY protocolをnode.jsで触りたくなったのでこの度ライブラリをこさえた次第です.主なフィーチャーとしては

という感じになっています.nodeでPROXY protocolを取り扱う人はそう多くはない気はしているのですが,もし来るべき時が来た際にはどうぞご利用ください.

「テクノロジーのイノベーションと民主化、そのはじめの一歩」というタイトルで首都大学東京で話してきました

首都大学東京は私の母校でして,当時は本当に色々なことがあったのですが,今回たまたまお話しする機会を頂いたので表題のような話をしてきました.

www.slideshare.net

このタイトルを思いついた時は酔っ払っていたのでしょうね.かなり大上段に構えたタイトルになってしまい恐縮しているのですが,

・情報通信コース・学域を卒業して,会社に入ったけど,会社ってこんなところですよ,
・会社でこんなことやってますよ.
・うちの会社にはこんな特徴がありますよ.
・会社に入るとこんなことしますよ.
・入社して,困ったことはこんなことです.
・入社して良かったことはこんなことです.
・今思うと,学生時代にこんなことやっていたらよかったかな,って思います.
・会社に入ってからの私の年表
・会社はICTイノベーションとしてこんな取り組みをしていますよ,してきましたよ.私はそれにこんな形で携わりましたよ.

というような内容をオーダーされたので,ここは一丁エモい内容でいこうと思い,打ったのがこの発表となります.趣旨としては,テクノロジーイノベーションを起こしたい,それを起こすためにはーーというのを自分なりにテクニカルな観点から発表したものになります.
大学に所属する学部生の方々のために作ったスライドなので,もしかしたらそれ以外の人にはもしかしたら刺さらないかもわかりません *1.なお中盤のスライドにある英語に対する思いは心から思っていることです.本当に苦戦を強いられている……
普段はエモい発表あんましないので (というか苦手),発表のフィードバックがどうだったのかは気になるところですが…… (結構心配)


このスライドに書かれている内容については,LINEで働いていたときに僕に本当によくしてくれた@yappoさんと@tokuhirom さんのお陰で学ばせてもらったことが本当に,本当に多くあります.なかなかこれを改まって言う機会はないのですが,平成も終わることですし,この場を借りて感謝の意を表したいと思います.ありがとうございます!!


僕は「とにかくコードを書き続けることは良いことだと思っていて,コードを書かなければ終わる,どんどん書く,書いた量が質に転換するタイミングは必ずあるのだ」という思いを持っているのでこのような内容となっています.
オリジナルのスライドの最後には "Shut the fxxk out and write some code" という一言が書かれたスライドがあり,つまりこれは「グダグタ言ってねーでコードを書けよハゲ」という意味合いでして,僕を動かす原動力の一つであった言葉なのであります.これはものすごく好きな言葉なのですが,しかし自らの良識が働いた結果,公開版のスライドからは削除しました.ということを記します.


結びとして,人の感想を記したいと思います.

f:id:moznion:20190426235321p:plain

ハハハ,ありがとうございました.

*1:学生の人に必ずしも刺さると言っているわけではない

恐怖! パスワード無しでログインを受け付けるsshd Dockerコンテナを作る

表題の通りです.
ほら,ローカルでのテスト用途でそういうコンテナが欲しくなることが月2くらいであるじゃないですか……あるんですよ……本チャンの環境で使うともちろん即死なので使ってはいけません.

gist.github.com

このようにすると test ユーザーでパスワード無しでsshログインできるコンテナを作ることができます.便利ですね.
sedで気合を入れまくっている部分を,あらかじめ書き換えておいた sshd_config との COPY に置き替えても良いでしょう.

現場からは以上です.