Bitcoin CoreのAmount Compression

このエントリーをはてなブックマークに追加

Bitcoin CoreのChainstateDBの’C’レコードのamount記録時に利用されている謎の圧縮方式 Amount Compressionについてのメモ。

どこで使われているのか?

このAmount Compressionは簡単に言うと、Bitcoinで通貨量の表現に利用されているSatoshi単位の数値のデータサイズを圧縮するという目的の元に作られている。具体的には0を減らして表現するということに主眼が置かれおり大半のtxoutのamount valueが1バイトか2バイトで表現できる(とのことだ)。この奇妙な方式がいつ誰によって導入されたかというと、sipaというコミッターにより2012/6/16に下記のコメントとともにコミットされている。2018/10現在の0.16.3においてはcompressor.cpp以下に存在するが、コミット当時はmain.cppの最下部に追加されている。

Compact serialization for amounts
Special serializer/deserializer for amount values. It is optimized for values which have few non-zero digits in decimal representation. Most amounts currently in the txout set take only 1 or 2 bytes to represent.

Compact serialization for amounts · bitcoin/bitcoin@0fa593d
https://github.com/bitcoin/bitcoin/commit/0fa593d0fb3a6f731a31610e98ce6bfd6a50a96c

また、さらにこの半月後には同じくsipaにより現在のBitcoin Coreにおける内部構造の原型となったUltraprune(ウルトラプルーン)と呼ばれる一連の変更がコミットされている。Ultrapruneの全容についてはまだ理解が追いついていないので改めて書きたいと思うが簡単に言うとUTXOをブロックデータを舐めまわさずとも高速に取得できるようにするための仕組みとデータ構造、実装を含んだフレームワークであり、2012/10/21にIssue:1677がメインラインに取り込まれた。余談だが、sipaさんは本名Pieter Wuilleと言い、金融機関向けサイドチェーンを開発、提供しているBlockstreamの創業者のようだ。またSegwitの時のマージも担当している。

Topic: Ultraprune merged in mainline
I’ve just merged my “ultraprune” branch into mainline (including Mike’s LevelDB work). This is a very significant change, and all testing is certainly welcome. As a result of this, many pull requests probably don’t apply cleanly anymore. If you need help rebasing them on the new structure, ask me.

Ultraprune merged in mainline
https://bitcointalk.org/index.php?topic=119525.0

そのためBitcoin CoreのUTXO管理は

  • Ultraprune前(ver < 0.08)
    この当時はブロックやUTXOの管理にBDBをつかってたらしい
  • 初代Ultraprune(0.08 <= ver < 0.15)
    ここからブロック用、UTXO用のLevelDBの利用が始まる
  • 現行のUltraprune改(0.15 <= ver)
    これまではvoutが1レコードに複数格納されていたのがTransactionHash+voutIndexをKeyとして、Valueにはブロック高とAmount、hashが格納されることになった。多分obfuscate_keyによるvalueの難読化もここから始まってる。

と変遷していることになる。なお、このUltraprune改のドキュメントはマジで驚くほど少ない。

Amount CompressionのRuby実装と振る舞い

本題に入るとAmount Compressionは下表のような可逆圧縮を行う、基本的には1桁目が0の個数、2桁目以上が0を省いた後の数値の変換値を表現している。

uint64 Compress uint64 Compress
0 0 1 110 992
1 1 1 000 000 000 9
2 11 10 000 000 000 10
9 81 10 000 000 001 9000000001
10 2 10 000 100 000 900006
11 91 153 000 000 1377
100 3 1 530 000 000 1378
1 000 4 1 532 100 000 137886
1 100 93 1 532 123 400 137891103

直感的でなく奇妙な振る舞いをする。
基本的には9桁以下が10で割り切れる数値であれば元の数値よりバイト数を節約できる。一方でどんなに0が多くても1satoshiとかが出現すると圧縮できないどころか桁が増加してしまう。そのため将来Bitcoinがデフレ傾向が続き、マイクロペイメントが主流になった時Ultrapruneも見直しが入るかも知れない。(※まあ実際にはオフチェーンで決済させれてまとまってからオンチェーンになるだろうから心配ないかも)
実装は下記となる。基本的にはBitcoin Coreのcompressor.cppのCompressAmountとDecompressAmountをRubyへ移植しただけである。



以上がAmount CompressionのRuby実装となる。Ultraprune構造等については後日改めて触れてみたい。

ちょっとした募集

諸般の事情からこの場で詳細を書くことは出来ないが、もしこの記事を読んで、BitcoinやEthereumなどのブロックチェーンに興味があり、こいつとフルタイムで一緒に仕事するのも面白いかも知れないという奇特なソフトウェアエンジニアがいたら、aboutに書いてあるTwitterから是非私に連絡をとってみて欲しい。東京でしかるべく待遇で採用してくれるところを紹介したいと思う。

LEB128とBitcoin CoreのBase128の違い

このエントリーをはてなブックマークに追加

前回の記事でLEB128(正しくはUnsignedなのでULEB128)について書いたのだが、そもそも論としてBitcoinCoreで利用されているBase128とは微妙に結果が異なっておりこれはおかしいとBitcoin Core 0.16.3のコードを良く確認するとやはり別物であったので、各表現の整理とBitcoin CoreのBase128のRuby実装を再掲載したいと思う。

Bitcoin Core界隈での奇妙な表現の数々について

Bitcoin界隈では整数の表現について幾つかの特徴的な方法がある。まずコードを全て確認しているわけではないので(マサカリ対策として)全てを網羅していない事を断っておく、その上で現時点で私が認識しているBitcoin界隈での整数表現には下記の3つがある。

  1. BitcoinのプロトコルのVariable Length Integer
    BitcoinでVarIntと言ったら通常はこれを指し、Protocol Documentationで定義されている。トランザクションやブロック上のIntのByte表現に利用され符号なし64bit整数まで表現できる。簡単に言うと253未満の数値は1byteで表現し、それ以上は1byte目をtype表現(FD=uint16,FE=uint32,FF=uint64)として利用しlength(1,3,4,9)を決定する。つまり1byte目が0xFCなら252として扱い、0xFDなら更に後続2byte取得して16bit整数として扱い、0xFFなら更に後続8byte取得して64bit整数として扱うということだ。
  2. BitcoinCoreで利用しているVarInt
    BitcoinCoreの内部で利用されているByte表現で、ULEB128類似の方式であるが、こちらはMSBから並ぶのでBigEndianである。あえて言うならUBEB128類似(後述)と言ったところだろうか。基本的には無限のサイズの整数を表現できる方式で整数を7bit毎に分割し最下位の7bitには先頭に0付与し8bit=1byte、それ以外は先頭に1を付与し8bitにした後、8bit目から1を減算(ここが類似という理由)し1byteとしたものを配列として構成した後に結合する。
  3. BitcoinCoreで利用しているAmount Compression
    これは内部的には全てSatoshiなどで表現されるbtcの数量(uint64)を圧縮して表現するための整数変換方式であり0が多いほど返還後の桁数が小さくなる一方で0の存在しない数値は桁が大きくなる。2のVarIntと合わせて利用されることが多い。

1、2は整数をByte表現に変換する方法で3は整数を圧縮する方法である。1についてはWiki自体も分かりやすい上に、プロトコルなので結構色んな所で実装され解説されている。一方で2や3についてはBitcoinCoreの実装の話なので情報が極端に少ないのである。なお3のAmount Compressionについては別な機会に記述したいと思う。

BitcoinCoreのVarIntとULEB128について

さて前回の記事ではULEB128を稚拙なRubyで実装してドヤってしまい大変恥ずかしいのだが、よくよく実行してみると下記の様にBitcoinCoreのVarInt(Base128風)とULEB128の数値が異なっていた。

整数 Hex ULEB128 BC版VarInt
127 0x7f 7f 7f
128 0x80 8001 8000
4660 0x1234 b424 a334
65535 0xffff ffff03 82fe7f
624245 0x98765 e58e26 a58d65

この時ULEB128では下記のような処理を行っている

624485                      変換対象整数
10011000011101100101 2進数表現

MSB ------------------ LSB 10011000011101100101 2進数表記 010011000011101100101 7bitで割り切れるようにMSB側に0埋め処理 0100110 0001110 1100101 7bit単位で分割 00100110 10001110 11100101 MSB側の最初の7bitの最上位bitには0を付与
それ以外のグループの最上位bitには1を付与
11100101 10001110 00100110 バイトオーダーの反転(Little Endianへ変換) 0xE5 0x8E 0x26 16進数表記 → 0xE5 0x8E 0x26 結合

一方でBC版のVarIntでは下記の様に処理を行っている

MSB ------------------ LSB
      10011000011101100101  2進数表記
     010011000011101100101  7bitで割り切れるようにMSB側に0埋め処理
 0100110  0001110  1100101  7bit単位で分割
10100110 10001110 01100101  7bit単位でMSB側から順に最上位8bit目に
1を付与し、最後には0を付与する
10100101 10001101 01100101 LSBの最終グループ以外から1を引く 0xA5 0x8D 0x65 16進数表記 → 0xA5 0x8D 0x65 結合

いずれの方式もデコード時はMSB側から1byte毎に読み込み、最上位bitが0になるまで次の読み込みを行う。それぞれ特有の処理(LEB128ではバイトオーダーを反転、BC版VarIntでは最終byte以外に1を加算)を行う。その後双方とも各byteから下位7bitを取得し結合すれば元の値が得られるという仕組みである。
それぞれの実装は下記になる。

ULEB128のRubyによる実装

下記実装だが前回とは異なり、BitcoinCoreのコードを参考にビットシフトで実装してみた。具体的にはエンコード時は対象数値から下位7bitを取得、最上位に1bit付与(0x80をOR)して配列に追加、その後対象数値を7bit下げ最初から処理を繰り返す。なお、配列に追加後に対象数値が0x7F以下であれば(つまり最もMSB側であれば)0x80をXORして最上位bitを0にする。



Bitcoin CoreのVarIntのRubyによる実装

これはもう、BitcoinCoreのC++実装を移植しただけである。ただし7bitずつ取ってくるという処理を論理積とシフトダウンで実装しており非常にシンプルである。C++とかの本物プログラマって凄いんだね。



本当はAmount Compressionについても書きたかったんだけど疲れてしまったので今回はここまでとしたい。

ちょっとした募集

諸般の事情からこの場で詳細を書くことは出来ないが、もしこの記事を読んで、BitcoinやEthereumなどのブロックチェーンに興味があり、こいつとフルタイムで一緒に仕事するのも面白いかも知れないという奇特なソフトウェアエンジニアがいたら、aboutに書いてあるTwitterから是非私に連絡をとってみて欲しい。東京でしかるべく待遇で採用してくれるところを紹介したいと思う。

LEB128のRubyによる実装

このエントリーをはてなブックマークに追加

Bitcoin CoreのChainstateDB等で使われる可変整数フィールドにBase128 VarIntという表現がある。よく知らなかったのだがこれはLEB128(Little Endian Base 128)と呼ばれ整数をバイト配列にするときに一般的な方式らしい。ChainstateDBにおいてはvoutのインデックスやamountの数値を表現するために利用されている。
(2018/10/7修正、追記)嘘である。Chainstate記録時にBitcoinCoreが用いている方式は正しくはLEB128ではない。改めてこちらの記事に掲載した。

LEB128 – Wikipedia
https://en.wikipedia.org/wiki/LEB128

下記がエンコード処理の実際となる。簡単に言うと、整数を2進数へ変換、7bitで割り切れるように上位に0埋めし分割、さらに7bit毎に最上位に1bit追加(最上位7bitには0、それ以外は1を付与)し8bit毎に16進数に変換し、バイト配列とした後にByte OrderをLittle Endianへ変更する。

624485                      変換対象整数
10011000011101100101 2進数表現

MSB ------------------ LSB 10011000011101100101 2進数表記 010011000011101100101 7bitで割り切れるようにMSB側に0埋め処理 0100110 0001110 1100101 7bit単位で分割 00100110 10001110 11100101 MSB側の最初の7bitの最上位bitには0を付与
それ以外のグループの最上位bitには1を付与 0x26 0x8E 0xE5 16進数表記 → 0xE5 0x8E 0x26 Little Endianへ変換(バイトオーダーの反転処理)

なぜこのような紛らわしい処理をしているのかというと、デコード時の利便性を考えてあるようだ。デコード時は1byteずつ読み込みながら1bit目をチェックし0になるまで読み込み続け、0になった時点で読み込みを終了する。あとはエンコード処理を逆転させてやれば復元できる。なおこの読み込み終了判定は読み込んだbyteに0x80をビット積してやった結果が0という記述が可能である。

Rubyによる実装

GemにはLEB128(https://rubygems.org/gems/leb128/versions/0.1.0 )という物が存在しているが、メタ情報が古いのかGemのLEB128は既にGithubのリポジトリが存在しない。そのためいささか車輪の再発明めいているが、向学の意味も含めて自分で実装してみた。

下記がRubyで実装したコードとなる。
https://gist.github.com/muyesh/0e29c9e6d66e801ebe4db3b6c7957768#file-leb128-rb



BitcoinのプロトコルにおけるVarInt表現

なお、紛らわしいことに、BitcoinではTransactionでの可変整数(64bit整数表現)フィールドにも下記のような独自の表現形を持っているため区別が必要だ。

Variable length integer : Protocol documentation – Bitcoin Wiki
https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer

Value Storage length Format
< 0xFD 1 uint8_t
<= 0xFFFF 3 0xFD followed by the length as uint16_t
<= 0xFFFF FFFF 5 0xFE followed by the length as uint32_t
9 0xFF followed by the length as uint64_t

この表現は上位1byteの値からintのサイズを判定し読み込むbyte数を得る。例えば1byte目が0xFD(253)未満であれば、そのbyteの数値を採用し、0xFDの場合は2byte読み込みuint16_tとする。同様に0xFEであればuint32_tとして4byte読み込み、0xFFであればuint64_tとして8byte読み込むと言った具合だ。
最初は何言ってるのかわからなかった。

Ubuntu環境へのePass FIDO-NFCの導入メモ

このエントリーをはてなブックマークに追加

昨今、なかなか物騒な感じなので2段階認証を導入することも増えている。
ところが2段階認証アプリにはスマホを紛失した時に詰むという重大なリスクがあり日々ドキドキしていたが、Googleなどではハードウェア鍵を2段階認証アプリと併用できると聞き早速導入してみた。

購入したePass FIDO -NFC Security Key: 真ん中の扇部分が青く点滅してタッチを促す

U2F対応製品について

導入したのは飛天ジャパン(https://www.ftsafe.com/)のePass FIDO-NFCというもので、fido認証のU2Fというグローバル規格(https://fidoalliance.org/?lang=ja)に対応した製品である。親会社は中国の会社で発音としてはフェイティエンとなるがヒテンで問題ないだろうと思う。Amazonで2980円だったので1つ試しに購入してみることにした。特に問題がなければ更にバックアップ用としてもうひとつ準備する予定だ。
このFeitianという会社はそれなりの歴史と採用実績がありfido認証にも加盟しておりかなり有名な組織のため個人的には問題ないと思われるが、製造工程においてシリアル番号を控えて同一の物を複製されていたりする可能性は(この会社に限らず)否定しきれないので、中国製がどうしても嫌な人はYubico(https://www.yubico.com/)製の物を購入したほうがよいかも知れない。


 

いずれにしても、この手の鍵製品は流通経路が非常に重要となるためAmazonで購入する場合は正規代理店やオフィシャルの出品であることを確認するべきである。また動作確認や開発用のためではなく正式に会社などで導入する場合は多少値段が高くなっても正規代理店やメーカーから直接手に入れる事をお勧めする。更にプロダクトの選定にあたってfidoのサイトで商品や会社をチェックしたほうが安心だろう。

FIDO Alliance FIDO® Certified – FIDO Alliance
https://fidoalliance.org/certification/fido-certified-products/

Ubuntuへの導入方法

Windowsなどの場合は特に設定は不要と思われるが、UbuntuなどのLinuxにおいてはudevのrulesを記述しておくことが必要となる。これを記述しないとChromeなどがU2Fデバイスにアクセスできない。ただ、全部自分で記述する必要は無く、基本的にはYubicoがサイトで下記のサイトで公開している方法に従えば良い。自分の環境はUbuntu 16.04.5であるが、その他のLinuxでも大差ないと思われる。

Using Your U2F YubiKey with Linux : Yubico Support
https://support.yubico.com/support/solutions/articles/15000006449-using-your-u2f-yubikey-with-linux

簡単に言うとGithubにて公開されている下記のファイルを取得して /etc/udev/rules.d 以下に配置するだけで良い。親切なことに、YubicoだけではなくFeitianや、Google謹製(日本未発売)のGoogle Titan U2Fなどのデバイスについても記述してくれているので、メジャーな製品であれば自分でログからidVendorやidProductを確認して追加する必要はないだろう。

libu2f-host/70-u2f.rules at master · Yubico/libu2f-host
https://github.com/Yubico/libu2f-host/blob/master/70-u2f.rules

なお、Feitian ePass FIDOに対応する部分だけ抜き出すと下記の様になる。今回買った製品のidProductは0858になる。

ACTION!=”add|change”, GOTO=”u2f_end”
# Feitian ePass FIDO
KERNEL==”hidraw*”, SUBSYSTEM==”hidraw”, ATTRS{idVendor}==”096e”, ATTRS{idProduct}==”0850|0852|0853|0854|0856|0858|085a|085b”, TAG+=”uaccess”
LABEL=”u2f_end”

https://github.com/Yubico/libu2f-host/blob/master/70-u2f.rules#L31

以上、これを機にみなさんもハードウェアキーによる2要素認証を導入してみたらどうだろうか?

中国におけるレポジトリ諸問題の解決(1): Docker編

このエントリーをはてなブックマークに追加

ここは上海、イエス!チャイナ!
人民が不用意に有害な情報に接することで不愉快な思いをすることがないように国家が防いでくれるという、子離れできないやや過保護気味で歪な親の愛を体現したかのような場所である。まあProxyとかVPNとか通してもよいのだけど、Dockerはイメージも比較的大きいためできることならミラー的なものを使いたい。

はい、そんなときはDaoCloud

このDaoCloudは名前からわかる通り、Dockerイメージをデプロイできるクラウドインフラサービスなのだが、加速器という名前でDockerHubのミラーリポジトリを提供している。

使い方は簡単、まず注册からサインアップし、加速器のメニューを開く。するとDockerのレポジトリにDaoCloudのミラーサイトを設定方法が書かれている。

Linuxの場合は下記のようなワンライナーを教えてくれるが、MacやWindowsは手動で設定を追加する必要がある。要するに、ユーザーごとにサブドメインを割り振ったURLを提供してくれるので、それをミラーレポジトリとして使えということのようだ、そのため下記のワンライナーの場合はサブドメイン部分はXXXXXで伏せてあるので注意して欲しい。

curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://XXXXX.m.daocloud.io

なお、細かい設定は下記のサイトにドキュメントが公開されている、中国語で書かれているが技術ドキュメントなのでだいたいわかるだろう。

  • Docker 加速器 – DCS 文档
    http://guide.daocloud.io/dcs/daocloud-9153151.html

    • 加速地址: アクセラレーターURL、要するに生成されたミラーサイトのURL
    • 创建或修改: 作成、或いは修正
    • 配置文件: 設定ファイル

上記のミラーレポジトリの設定を変更したら、Dockerデーモンの再起動をすれば次回からDockerはDaoCloudのミラーサイトから各種イメージをダウンロードしてくれるはずである。

VagrantとDocker(1.5): Docker for Mac / Docker for Windowsという存在

このエントリーをはてなブックマークに追加

さて・・・、調査不足というか勉強不足だった。お恥ずかしい。
VagrantとDockerを組み合わせて云々という流れですすめる予定だったのだが、Dockerのドキュメントをよく読んでみると既にDocker for Mac / Win というものが存在していた。不覚である。
更に言うと、それ以前にDocker Toolboxというものが存在していたようである。Linuxしか見ていなかったため注意が及ばなかった(言い訳)

▽ Docker Toolbox

Docker Toolboxについてはまず冒頭に下記のような説明がある。既にレガシーであり、Docker for Mac、およびDocker for Windowsの必要条件を満たさない時に利用すべきであるとのこと。

Legacy desktop solution. Docker Toolbox is for older Mac and Windows systems that do not meet the requirements of Docker for Mac and Docker for Windows. We recommend updating to the newer applications, if possible.

Docker ToolBoxは下記のコンポーネントで構成されている。

  • Docker Machine
    docker-machineコマンド、複数のリモートDockerホストの管理やプロビジョンを行う
    Docker Machine Overview – Docker
    https://docs.docker.com/machine/overview/
  • Docker Engine
    dockerコマンド、Docker本体
  • Docker Compose
    docker-compose、オーケストレーションツール
  • Kitematic
    DockerのGUI
  • a shell preconfigured for a Docker command-line environment
    コマンド実行のための環境設定
  • Oracle VirtualBox
    仮想環境

つまり、Windows、あるいはMacにVirtualBox環境を構築し、そこへDockerを配置、動くようにするということらしい。

Linux版と異なるのがDockerMachineだ、Dockerホストのドライバーとして代表的なものだけでもAWS、Azure、GoogleComptuteEngine、Hyper-V、VirtualBox、VMwareなどに対応している。要するに大抵の仮想環境に対してDocker環境を構築、さらにコンテナをデプロイできるらしい。どうやらこのコマンドが後々、書こうと思っていたクラウドへのコンテナのダイレクトデプロイに関係あるようだ。
なお、MacのHyperkitについてはドライバーが存在しない。

そして注意しなければならないのがToolboxはレガシー扱いだが、DockerMachine等の各ツール群がレガシーになったわけではないことである。

▽ Docker for Mac / Windows

ではDocker for Mac / Docker for Windows、そしてレガシーとなったDocker Toolbox とは何なのだろうか?
簡単にまとめると下記のようになる

  • Docker for Mac
    1. Hyperkitという軽量hypervisorを利用
      • ただしYosemite以降
    2. Hyperkit上にてLinuxカーネルを動かす
    3. Linuxカーネル上でDockerコンテナを動かす
  • Docker for Windows
    1. hypervisorとしてHiper-Vを利用
      • ただしWindows10 Pro / Enterprise の64bit版
    2. Hyper-V上にてLinuxカーネルを動かす
      • ということは、これはProじゃないとダメなのかも
    3. Linuxカーネル上にてDockerコンテナを動かす
  • Docker Toolbox for Mac / Windows
    Yosemite以前やWin10以前の場合はこの手法になる

    1. VirtualBoxを動かす
    2. VirtualBox上にてLinuxカーネルを動かす
    3. Linuxカーネル上にてDockerコンテナを動かす

何のことはない、Docker with Vagrant方式と考え方は同じである。ただし、厳密には若干ことなる。Vagrantを用いた場合はフルセットのLinuxを準備してそこにDockerをセットアップ、そのまま開発環境としても利用してしまおうと考えていたからである。この辺は回を進めていく中で調整と検証をする予定である。

VagrantとDocker(1): Rails環境構築を目的とした場合のVagrantとDockerの関係

このエントリーをはてなブックマークに追加

かつて仮想環境が登場した時、VTやVTxで仮想環境がアクセラレートされクラウドが登場した時、非常にエキサイティングな経験をした。ランタイムではなく、マシン自体が仮想化されハードからシステムが切り離され自動的に冗長化していく、これはかつておっさんが新人だった頃(2000年前後)にIBMがオートノミックコンピューティングと呼び、オラクルがグリッドコンピューティングと呼んだ技術だ。

当時はSFだった、自律的コンピューティングなんてせいぜい2001年宇宙の旅のHALぐらいしか想像力が及ばなかった。効果な専用の管理用ラックや見たことも触れたこともない高価なハードやOSを準備しなければならなかったし、結局さほど普及したようにも見えなかった。

しかし、あれから10年、仮想環境は既に仮想であるということすら意識されずにクラウドとして利用されている。そしてクラウドは色々な技術を内包し統合するための便利なバズワードとなり、多数のサブワードを抱えている。VPS、IaaS、PaaS、BaaS、インスタンス、コンテナ、プロビジョン、ベアメタル、Stack、Lamda・・・んー困った。

とは言え自分のような凡人には全部一気に抑えて行くことは出来ないので、とりあえずようやく枯れてきた感のあるVagrantとDockerを用いてRailsの環境を構築することで学ぶことにした。

みんな大好きRuby on Railsは、賛否両論あるとは思うけどバージョンを重ねる毎に当初の目的であった一気通貫のシンプルなフルスタックではなくなり通常はGemにより肥大化している。まるでかつてJava世界において花型であったSpringとMavenのように感じる。実際、それなりに肥大化したRailsの環境構築はrubyenvやbundle、rakeの力を借りても一苦労だ。
そんな環境構築は自分の実務にとっても学習にとっても最適な事例だと思ったのである。

とは言え、全部を一度に学ぶのも、書くのもしんどいので下記の様に今回を(1)として一歩一歩進めて行くとしよう。

  • VagrantとDocker(1): Rails環境構築を目的とした場合のVagrantとDockerの関係
  • VagrantとDocker(2): VagrantによるRails環境構築
  • VagrantとDocker(3): VagrantによるDocker稼働環境の構築
  • VagrantとDocker(4): Docker on VagrantによるRails環境の構築
  • VagrantとDocker(5): Docker for Mac / Docker for Windows によるRails環境の構築 (※追記

回りくどいが「理論なくしてなんとやら」のため、今回は各要素の関係性と最終的な到達点までの説明であり、実際の構築スクリプトや実践は次回からとなるが、とりあえずVagrantfileやDockerfileなどをGithubにあげてあるので参考にしていただいても構わない。

参考

Continue Reading »

Advent Calendar 2016: 連行出社芸

このエントリーをはてなブックマークに追加

Advent Calendar書くの初めてなのと、PM2.5の猛威によるせいか風邪が治らずフラフラの頭でつらつら書いているのでとりとめのなさはご容赦いただければと。

出社芸 Advent Calendar 2016 – Adventar
http://www.adventar.org/calendars/1481

▽ はじめに

さて、現在お世話になっているStartupTechnologyはhisajuさんがエンジニアとスタートアップのために起こした会社なのだが、この会社では健全で(すいません)強靭な(ごめんなさい)精神のもとに自己を厳しく律する(痛い)ことができるエンジニアのために出社自由という制度を採用されている。(すいません、すいません><)
その一環として出社芸の披露という今回のAdventCalendarがあるわけで、決して私のような出社芸が推奨されているわけではないことを・・・

▽ サンドイッチ

あれはもうかれこれ15年ほど昔、まだプログラマーや開発者というのが今ほどクールでもおしゃれでもなかった時代の話。その頃のMacのノートパソコンと言えばホタテ形で3kgを超えるという有様で、よほどハートが強くなければスタバに持ち込むなどということはできなかった。

私は当時新人で、某大手情報斡旋会社さんのJava案件に新人として四次受けぐらいで入っていたのだが、ご多分にもれずオブジェクト指向設計に触れたこともない人達がなんとかかんとか作った(無駄に)巨大なシステムだった。当然ながらフロアはすえた臭いが漂い、みんなの目は死んでおり、朝は会議室からウォーキング・デッドの如く這い出てくるという有様である。

そんな中、運よくというか運悪くというか先輩方に腕を見込んでいただきサーバーの設定等で携わらせてもらったわけだが、そもそも当時のサーバーシステムがMVCという概念すら普及していない時期に構築されたものでまともに動くわけがない。というか新人にどうにかできるわけがない。そしていつしか自分もウォーカーになり、会議室で眠るというようなことが日常に・・・。

そんな時、疲労もピークに達した頃のある晩、PLの方が遂にカプセルホテルとやらをとってくれた。その晩(既に未明)はウキウキ(既におかしい)しながらホテルに向かい、サイバーな棺桶のような穴蔵にもぐり込み夢も見る間もなく眠りに・・・・・・。

起きた時には既にチェックアウトの時間、電話には何度も履歴が・・・。慌ててかけ直すと

「起きてるー?大丈夫ー?いま迎えをやったからw」

寝ぼけ眼のまま、フロントへ行きチェックアウトを済ませるとそこには既に連・・・もとい迎え要員2名が待ち構えており、PLへ電話にて

「確保しました!」

その時の午前中の日光に照らされる眩しいまでの笑顔と、現場へ向かう時の前後を微妙にサンドイッチされるというフォーメーションは今でも素敵な思い出である。
なお、自分はサーバーの問題がある程度解決したところで解放されたのだが、その後そのプロジェクトは行き着くところまで行き現場そばに合宿所を準備するまでになったという話を聞いた。
思えば、これが連行出社芸の始まりだったのかもしれない。

▽ 豆腐と再起動

豆腐メンタルという言葉をご存知だろうか?
要するにメンタルが弱いのである。もうとにかくメンタルが弱い。めっぽう弱い。SNSでぼそっと呟かれるともう自分のこととしか思えなくなるほど弱い。
そんな糞メンタルのため、色々と抱え込み始めると内圧を高めて自爆というより身動きが取れないというデッドロック状態になる。
デッドロック状態になると、後続ジョブが処理出来ないのでスラッシングという現象が起き、リソースを食い尽くし応答不能に・・・・。

おそらく、そういう経験をしたことがある人も居るだろうし、そういう人が回りにいる人も居るだろうと思う。もうダメ人間である。ところがデッドロックに陥ったダメ人間はダメであることも自覚をしておりオーバーフローで身動きが取れなっている。

もうこうなるとkill -HUP程度ではどうにもならない、物理再起動、つまり連行が有効に機能する。
失踪プログラマーの話はよく聞くし、自分でも何人か出会ってきた。いま思うと彼らも早い段階で連行すれば戻ってこれたのではないかと思うことしきりである。

偉そうなことを言う自分はどうなのか?もうダメである。過去15年において同僚、上司、内縁の妻的な人、果ては上場企業の社長に至るまで連行を実施させてしまうというダメっぷりである。
この場を借りて助けてくださっている皆々様に深くお礼申し上げたい。というか逆立ちしてでんぐり返っても返しきれない程の恩があるわけである。

▽ ギークハウスとオンライン出社とツール

さて、ここ数年そんな豆腐達にとって福音となる潮流がある。ギークハウス、Slackでのオンライン出社などである。

私は他人と生活するのが苦手で家族ですら一緒に生活するのはストレスがたまるというような性格のため、ギークハウスというものが理解できなかった。
ところが先日上海にリモートワークにいらした方の話を聞いていたら、ああこれはある意味で単身豆腐にとっては再起動を促してくれるような仲間がそばに居るという環境なのではないかと思うに至り、以前と比べ肯定的に変化した。おそらく、ギークハウスでの共同生活というのはある意味で擬似家族的なものであり、職場からの解放とリセット、自己存在の無条件での肯定を得られるものなのではないかなと。
そのため、豆腐にとってはデッドロックを早期に解除、あるいは回避出来る安全弁となる気がする。

また、スタテクではおなじみのSlackによるオンライン出社と自己タイムライン投稿、これも豆腐にとっては福音である。
豆腐にとってのリアル出社アクションに失敗した時にスタックされていく懺悔感というのはスラッシングを招くのに充分なほど壁が高いのだが、それをオンラインで報告をすることで壁を下げることができる。そしてメンタルが弱り切っている時の、他人の距離感というのは自分でも推し量りにくく息をするのも辛いことがあるのだが、この距離感の表現をSlackのリアクションというもので解決しており心強い。

もちろんメンタルは強いほうが良いし、連行出社芸など無い方が良いのだが、ツールやライフスタイルによってある程度のフォローが可能で理解を示してくれる時代になってきている。
どうしても出社芸を繰り出してしまうけど、プログラミングも開発も大好きだという人は一度スタテクのオフィスを見学に来てはいかがだろうか?

「起業家に機会を。エンジニアに自由を。」
株式会社スタートアップテクノロジー | サービス立ち上げ専門の開発会社
http://startup-technology.com/

DisplayLinkの液晶モニタのせいでx250がSuspendできない

このエントリーをはてなブックマークに追加

しばらく前にMB168B+買ったんですよ。
モバイルでもデュアルディスプレイしたくて、まあ最近使ってないんですけど。
https://www.asus.com/jp/Monitors/MB168BPlus/

で、何かというとドライバ入れると普通にこれLinuxで使えるんですけどなんかSuspendできなくなってて、コマンドでサスペンド(sudo pm-suspend)してログで原因調べた(/var/log/pm-suspend.log)ら、USBでデバイスが繋がれていない時はDisplayLinkのSuspendのhook処理が応答してないんですよ。で、Suspend処理ににコケる。みたいな。

x250:/etc/pm/sleep.d$ ls -lha
total 20K
drwxr-xr-x 2 root root 4.0K  4月  2 07:52 .
drwxr-xr-x 5 root root 4.0K  8月  5  2015 ..
-rwxr-xr-x 1 root root  210  6月 26  2015 10_grub-common
-rwxr-xr-x 1 root root  660 12月  7  2013 10_unattended-upgrades-hibernate
lrwxrwxrwx 1 root root   35 10月 31 20:50 displaylink.sh -> /usr/lib/displaylink/displaylink.sh
-rwxr-xr-x 1 root root 1.3K  5月 23  2012 novatel_3g_suspend

で、このdisplaylink.shを下記の様にlsusbでDisplayLinkのベンダーIDがあるときだけ(lsusb -d 17d9: > /dev/null)実行するように修正したら正常にSuspend処理が実行されました。

#!/bin/bash
# Copyright (c) 2015 DisplayLink (UK) Ltd.

suspend_dlm()
{
  # Check DisplayLink Device
  lsusb  -d 17d9: > /dev/null
  if [ $? -eq 0 ]; then
    #flush any bytes in pipe
    while read -n 1 -t 1 SUSPEND_RESULT < /usr/lib/displaylink/PmMessagesPort_out; do : ; done;

    #suspend DisplayLinkManager
    echo "S" > /usr/lib/displaylink/PmMessagesPort_in

    #wait until suspend of DisplayLinkManager finish
    read -n 1 -t 10 SUSPEND_RESULT < /usr/lib/displaylink/PmMessagesPort_out
  fi
}

resume_dlm()
{
  # Check DisplayLink Device
  lsusb  -d 17d9: > /dev/null
  if [ $? -eq 0 ]; then
    #resume DisplayLinkManager
    echo "R" > /usr/lib/displaylink/PmMessagesPort_in
  fi
}

case "$1" in
  thaw)
    resume_dlm
    ;;
  hibernate)
    suspend_dlm
    ;;
  suspend)
    suspend_dlm
    ;;
  resume)
    resume_dlm
    ;;
esac

VAIO Pro 11にUbuntu14.04を入れるときのメモ1

このエントリーをはてなブックマークに追加

購入して1年立たず液晶に縦線が入るも上海では保証がないため放置していたのだけど、先日ようやく淮海路のSony旗艦店の修理センターで修理した。なんだかんだで1,700元かかった。まあ思ったより安かった気がしなくもないけど悔しい。もうVAIOは買わない。どっちにしろ今では英語キーボードが選択できないのであれだけど

で、めでたく戻ってきたPro11にUbuntuを再インストールするにあたって知った件をいくつかメモしておく。

▽ UbuntuのみでUEFI Secure Bootを行う
14.04自体はUEFIにもセキュアブートにも対応してるのだけどインストール後に”Windowsの起動に失敗しました”と言われ、何故か起動できない。
だいぶハマったが調べてみると、VAIOのファームウェアはUEFIのブートエントリーに”Windows Boot Manager”が存在しない場合、UEFIが”Windows Boot Manager”で\EFI\Boot\bootx64.efiを勝手にエントリー処理し、更にデフォルトでWindows Boot Managerから起動を行うのである。故にubuntuで登録されたEFIエントリが起動されない。

Continue Reading »