sakura.io HAT for Raspberry PiをRaspberry Pi 3で動かすまで

sakura.io HAT for Raspberry Piを使い、Raspberry Pi 3上でさくらの通信モジュールを動かす手順の備忘録です。

通信モジュールの準備と登録

リファレンスを参照して、通信モジュールをプロジェクトに登録しておいてください。この際、サービス連携としてWebSocketを作っておくと、モジュールから送信された値をWebブラウザーからリアルタイムに確認できるため、便利です。

OSの準備

ドキュメントRaspbian Jessie 2017-03-02とOSバージョンの指定があるので、それに従いました。2017-03-02版のRaspbianはこちらからダウンロードできます。

実際はOSのバージョンというよりもカーネルのバージョンの問題のようで、カーネル4.4.50-v7+以降だとI2Cが動作しないようです。ためしに2017-11-29-raspbian-stretch-lite.imgで試してみた所、記載の通り

OSError: [Errno 121] Remote I/O error

が発生して動作しませんでした。

zipを展開した後、ddでmicroSDカードにイメージを書き込みます。

$ unzip 2017-03-02-raspbian-jessie-lite.zip
$ sudo dd if=2017-03-02-raspbian-jessie-lite.img of=/dev/(microSDのデバイス名) bs=1M
$ sync

最近のRaspbianはセキュリティ上の理由から、デフォルトでSSHサーバーが無効になっています。SSHサーバーを自動的に有効にしたいのであれば、/bootパーティションssh(ないしはssh.txt)という名前の空ファイルを作成します。このあたりの処理は本筋から外れるので省略します。もしも気になるのであれば、/lib/systemd/system/sshswitch.serviceを見てみるとよいでしょう。

I2Cの有効化

Raspberry PiのI2Cはデフォルトで無効になっているため、raspi-configコマンドでこれを有効にします。
raspi-configコマンドを実行すると対話的なメニューが表示されますので、[5 Interfacing Options] → [P5 I2C] → [Yes]とメニューを辿ってください。

なおraspi-configコマンドは、引数にnonintを指定すると内部の関数をコマンドラインから直接呼び出せます。do_i2c関数に引数0を渡すとI2Cを有効化できるため、以下のコマンドを実行するのもお手軽でおすすめです。

$ sudo raspi-config nonint do_i2c 0

パッケージとライブラリのインストール

このバージョンのRaspbianにはPython2のみがプリインストールされているため、敢えてPython3をインストールすることはせず、Python2をそのまま使うことにします。

以下のコマンドを実行します。

$ sudo apt update
$ sudo apt install python-pip python-smbus
$ sudo pip install sakuraio

面倒なのでsudoでpipを実行してしまっていますが、ユーザーディレクトリに環境を構築したい場合は--userを使う等して、各自よしなにしてください。

サンプルスクリプトの作成

Pythonスクリプトを作成して、プラットフォームに値を送信してみましょう。以下のスクリプトをsample.pyとして保存し、実行してください。チャンネル0にintの0が送信されます。

#!/usr/bin/python

from sakuraio.hardware.rpi import SakuraIOSMBus

sakuraio = SakuraIOSMBus()

print(sakuraio.get_unique_id())
print(sakuraio.get_firmware_version())
print(sakuraio.get_connection_status())

onlinestatus = sakuraio.get_is_online()

if onlinestatus == True:
    sakuraio.enqueue_tx_raw(0, "i", [0])
    sakuraio.send()

実行例

16AXXXXXXX
v1.0.0-161109-c566dba
128

今回はI2Cを使うので、SakuraIOSMBusをimportしています。
get_unique_id()でモジュールのシリアル番号、get_firmware_version()でモジュールのファームウェアバージョンを取得できます。

get_connection_status()で現在の接続状態を取得できます。接続状態は8ビットで表され、最上位ビットが接続状態(0=オフライン/1=オンライン)で、残りの7ビットがエラーコードとなっています(オンラインかつエラーなし=128)。

get_is_online()は内部でget_connection_status()を呼んでおり、0x80で最上位ビット以外をマスクした結果をbool値として返しているだけです。このあたりのデータ構造について、詳しくはデータシートを参照してください。

enqueue_tx_raw()で送信チャンネルとデータタイプ、送信データを送信キューにキューイングします。send()でキューの内容をプラットフォームへ送信します。

ハードウェアAPIについて、詳しくはドキュメントを参照してください。

まとめ

sakura.ioは、公式ドキュメントAPIリファレンス製品データシートGitHubのドキュメント、ライブラリのソース内コメントなど、必要な情報は一通り揃っているのですが、それらがあちこちに散らばっています。そのためファーストステップを踏み出すまでのハードルが必要以上に高く感じてしまうため、誰かが入門記事を書いてくれると嬉しいですね。

sakura.io HAT for Raspberry Piを使えばLinux上のPythonでプログラミングができるので、Arduinoに比べると幾分とっつきやすいのではないでしょうか。

屈辱の松屋なう 〜 俺とだく盛りと松屋

これは松屋Advent Calendar 20日目の記事です。昨日はみんなのアニキ、kazken3の「松屋を支える技術」でした。

私はもともと牛丼と言えば吉野家派であり、松屋は好きではありません。私は二ヶ月前まで京都の四条壬生川という所に住んでいたのですが、その近辺で吉野家へ行こうとすると、西院という所まで行く必要がありました。
西院というのは大宮から阪急電車で一駅なのですが、夜中に一駅ぶん歩くのもいやなものですよね。家の前にはなか卯があったのですが、当時のなか卯は「和風」を謳い牛丼にシイタケを混入するなどという暴挙に出ており、あまつさえその後は牛丼を廃止してエリンギを入れてくる始末。
なか卯がだめ、吉野家は遠いとなると、残された選択肢は松屋しかありません。そして私は行きたくもない松屋四条大宮駅前店で「屈辱の松屋なう」することになるのでした。しかし、真の屈辱はその後にやってくるのです。

だく盛りなどという客に媚びたサービスなど存在しなかった当時、飯が吸い切れぬタレを丼の底に残すことは、職人の恥であった。
挑戦であった。

牛魔王とその眷属たちは、予知野家の誇るシステムに対し、全胃袋をかけて、戦いを挑んでいた。

「腹ぁくくれ。……戦争だ」


立喰師列伝. 押井守. Production I.G, 2006.

「つゆだく」
私がはじめてその名前を聞いたのは、20世紀が終わろうとしていた頃だったと記憶しています。それから10年以上。こんなオーダーも一般的になったようです。
そもそも牛めしとは何でしょうか。ラーメンの主役が麺であるように、牛めしとは白い米を食べる食べ物です。牛肉や玉葱など、所詮はうどんにおける天かすであり、あくまでも主役は適度にタレを吸った米でなければなりません。しかも牛めしは雑炊ではありません。タレの中で泳ぎ、ふやけてお茶漬けの様相を呈した白い物体は、もはや私の期待する牛めしではないのです。
食べ方など個人の自由。だく盛りも大いに結構。これが時流なのかもしれません。お店としてはサービスのつもりなのかもしれません。しかし何も言っていないのに、デフォルトで米が海水浴をしている丼を出すのはいただけません。Linuxサーバーだって、minimalでインストールしてから必要に応じてパッケージを足すのが基本。フルインストールした状態から不要なものを抜いていく人はいませんよね。「注醤、鍋に返らず」という中国の故事にある通り、一度丼に入れすぎてしまったタレを抜くことはできないのです。ああ、昭和の牛丼職人の魂はどこへ行ってしまったのでしょうか。望むらくは、2015年は牛めしのタレが少なくあることを。

さて。そんな理由から松屋では「つゆ抜き」を注文するわけですが、時にはもう一味欲しくなる時があるかもしれません。そこで登場するのがサイドメニュー。中でも一番最初に思いつくのが生卵ではないでしょうか。すき焼きは溶き卵につけて食べるのが定番。タレで煮込まれた牛肉と生卵の相性は保証つきですし、卵かけご飯というのも魅力的かもしれません。しかし。

男の挙動には、無銭飲食に特有の後ろめたさがまったく感じられなかった。
目線が店の者を追うこともなく、むしろ傍若無人とも、尊大とも形容しうる自信が漲っていた。
大盛りも、口直しの御新香も、味噌汁も求めない。

「やつは……玄人だ」

生卵を頼まない、という事実が決め手だった。
(中略)
生卵は確かに牛丼に馴染むし、熱い飯の温度を緩和して素早く嚥下することを可能にするが、生卵をかきまぜることは、牛丼本来の味わい、タレの染み込んだ熱い飯の香りを決定的に損なう。
男が玄人であることに関しては、一点の疑問もない。


立喰師列伝. 押井守. Production I.G, 2006.

溶き卵で米を水没させてしまっては、せっかくつゆ抜きを注文した意味がありません。卵はどんな味とも調和しますが、それは同時に、個々の食材の尖った味わいを損ってしまうことも意味するのです。牛皿とライスではなく、あくまで牛めしをオーダーした以上、その調和のとれた味わいを損なうような行為は、厳に慎むべきと考えます。
そこで半熟卵をオーダーします。適度にとろみのついた半熟卵であれば、不必要に米や牛肉を侵食することもなく、白飯にワンポイントの彩りを加えることができるというものです。肉を半分ほど食した後、丼の中央部の米を穴を開けるように食べてから、そこに卵を投入するのが味の変化を楽しむ意味でもベストです。
並、つゆ抜き、半熟卵。これこそが松屋の、松屋ならではの食べ方と言えるのではないでしょうか。

吉野家にも半熟卵ありますよ?」

ぎゃふん

立喰師列伝 通常版 [DVD]

立喰師列伝 通常版 [DVD]

Cubox-i4proにDebianをインストールする

Cubox-i用のインストール済みイメージは割とあちこちで見かけるのですが、デスクトップ環境一式が入っていたりと色々気に入らない部分があるので、自分で作ることにした際の備忘録です。ビルド作業はVirtualBox上のUbuntu 14.04 LTS(64bit)で、SDカードのフォーマットや書き込みは手元のUbuntu 14.04 LTSで行っています。

基本的にカーネルブートローダーのビルドは
http://www.solid-run.com/wiki/index.php?title=Building_the_kernel_and_u-boot_for_the_CuBox-i_and_the_HummingBoard
に従います。

micro SDカードの用意

micro SDカードにパーティションを切っておきます。/dev/sdX1がカーネルを置くパーティションで、/dev/sdX2がrootfsを置くパーティションになります。今回は1GBのswapパーティションも作ってみました。メモリ2GB搭載しているCubox-i4でスワップ使う状態になったら負けのような気もしますが念の為。ファイルシステムext4にします。


u-bootのビルドと書き込み

必要なパッケージをインストールします。また環境変数ARCHとCROSS_COMPILEをセットしておきます。

$ sudo apt-get install gcc-arm-linux-gnueabi u-boot-tools lzop build-essential
$ export ARCH=arm
$ export CROSS_COMPILE=/usr/bin/arm-linux-gnueabi-

SolidRunのリポジトリからu-bootをクローンしてmakeします。

$ git clone https://github.com/SolidRun/u-boot-imx6.git
$ cd u-boot-imx6
$ make mx6_cubox-i_config
$ make

SPLというファイルとu-boot.imgというファイルが作られているので、これをmicro SDへ書き込みます。手元のPCへ引っ張ってくるのはscpなりrsyncなりで適当に。

$ sudo dd if=SPL of=/dev/sdX bs=1K seek=1
$ sudo dd if=u-boot.img of=/dev/sdX bs=1K seek=42

カーネルのビルド

SolidRunのリポジトリから、3.14のツリーをクローンしてmakeします。最終的に必要なファイルは、arch/arm/boot/zImageとarch/arm/boot/dts/imx6q-cubox-i.dtb、それにmodulesディレクトリ以下にインストールしたモジュール一式です。makeが終わったらこれも手元のPCへrsyncなりしておきます。

$ git clone https://github.com/SolidRun/linux-imx6-3.14
$ cd linux-imx6-3.14
$ make imx_v7_cbi_hb_defconfig
$ make zImage imx6q-cubox-i.dtb imx6dl-cubox-i.dtb imx6dl-hummingboard.dtb imx6q-hummingboard.dtb
$ make modules
$ mkdir ../modules
$ make modules_install INSTALL_MOD_PATH=../modules

rootfsの作成

debootstrapでWheezyの環境を作成します。必要なパッケージはincludeに入れてしまうのがいいでしょう。特にopenssh-server。

$ sudo apt-get install debootstrap
$ sudo debootstrap --verbose --foreign --arch=armel --variant=minbase --include=module-init-tools,locales,udev,aptitude,dialog,ifupdown,procps,iproute,iputils-ping,pump,nano,wget,netbase,openssh-server wheezy rootfs http://ftp.jp.debian.org/debian

chroot内でarmelの環境を動かすため、qemu-arm-staticを使います。qemu-user-staticパッケージをインストールした後、qemu-arm-staticをchroot内のツリーに配置すれば動作します。そうしたら実際にchrootして、debootstrapのsecond-stageを実行してパッケージを展開します。その後はrootのパスワードやAPTラインなど、必要な設定を行っておきましょう。ネットワークの設定やシリアルコンソールの設定はここでやっておかないと。
chroot環境からexitしたら、qemu-arm-staticは削除しておきましょう。

$ sudo apt-get install qemu-user-static
$ sudo cp /usr/bin/qemu-arm-static rootfs/usr/bin/
$ sudo chroot rootfs
# ./debootstrap/debootstrap --second-stage

# dpkg-reconfigure tzdata
# dpkg-reconfigure locales
# passwd

# cat > /etc/apt/sources.list
deb http://ftp.jp.debian.org/debian/ wheezy main contrib non-free

# cat >> /etc/network/interfaces
auto eth0
allow-hotplug eth0
iface eth0 inet dhcp

# cat >> /etc/inittab
T0:23:respawn:/sbin/getty -L ttymxc0 115200 vt100

# exit
$ sudo rm rootfs/usr/bin/qemu-arm-static

カーネルとrootfsのコピー

zImageとimx6q-cubox-i.dtbは/dev/sdX1にコピーします。作成したrootfsはまるごと/dev/sdX2にコピーします。その後、/dev/sdX2の/lib以下に、modules/lib/{firmware,modules}をコピーします。
あとはこのmicro SDを実機に挿入すれば、こんな感じで上がってきます。うまくいけば。

あ、swapを作ったならば、fstabなんかも書いておきましょう。またhostnameがdebootstrapしたマシンと同じになっていると思いますので、そのへんの調整なども適宜。

LXCでWebサービスを分離してみた

少し前ですが、ownCloud 7.0.2がDebian sid/Ubuntu 14.10に入りました。私はもともとさくらのVPSにインストールしたUbuntu 14.04 LTS上に、universeからowncloudやtt-rssパッケージをインストールして自分用として使っていたのですが、あわしろいくや氏がownCloud 7.0.2の14.04 LTS向けパッケージをPPAに用意したと聞き、アップデートを行いました。
ownCloud自体のアップデートは問題なく終わったのですが、tt-rssの設定画面を開くとdojo.jsのエラーで止まるという現象が起きていることに気づきました。詳しく調べたわけではありませんがエラーメッセージから察するに、libjs-dojo-{core,dijit}あたりのバージョンが上がってしまったことが原因だと思います*1。Utopicにあるtt-rssの1.13を持ってこれば解決しそうですが、14.04 LTSでは依存関係が満たせないので少し手間がかかりそうと判断し、tt-rssパッケージの利用はやめてソースを手で入れてしまいました*2
というのが、先月末の話。LTSのOSを長く使いたいけど、進化の早いアプリケーションは最新版を使いたいというジレンマはよくある話ですが、標準で提供されている組み合わせを外れて勝手にアプリを入れると、そりゃこういう問題も起こりうるわけです。そこでVPSにLXCを導入して、機能ごとに直交性を持たせてメンテナンス性を上げることにしました(ここまで前フリ)。

VPSの初期化とLXCのインストール

せっかくなのでVPSはOSからインストールし直します。といっても、現在進行形で動いているサーバーをいきなり消すのはよろしくありません。こういう場合、新しいサーバーを別途用意し、並行稼動させながらデータを移すのがセオリーでしょう。しかしそのためにVPSをもう一台契約するのはあまりにも無駄なので、現行のサーバーは一旦クラウドへ退避させることにします。さくらのクラウドには、同一アカウントで稼働中のVPSのディスクイメージをクラウド上のアーカイブにコピーし、そこからインスタンスを起動するマイグレーション機能が用意されています。稼働中のVPSのコピーが保存できる上に、コストは日割、時間割でとてもお得なわけです*3
OSのインストールや基本的な設定は先のRecipe通りなので省略。LXCは以下のコマンドでインストールします。

$ sudo apt-get install lxc

コンテナの作成と初期設定

UbuntuのLXCのコンテナには10.0.3.2から10.0.3.254までのIPアドレスが動的に割り当てられるのですが、固定IPアドレスが使いたいので、まずはLXCの設定を変更します*4

$ sudo sed -i 's/LXC_DHCP_RANGE="10.0.3.2,10.0.3.254"/LXC_DHCP_RANGE="10.0.3.2,10.0.3.127"/' /etc/default/lxc-net
$ sudo sed -i 's/LXC_DHCP_MAX="253"/LXC_DHCP_MAX="126"/' /etc/default/lxc-net
$ sudo stop lxc
$ sudo start lxc

lxc-createコマンドでコンテナを作成します。ubuntuテンプレート、バージョンは14.04 LTS、archはamd64を指定します。

$ sudo lxc-create -t ubuntu -n owncloud -- -r trusty -a amd64

作成したコンテナの設定とrootfsは、/var/lib/lxc/(コンテナ名)以下に作成されています。固定IPアドレスの付与やコンテナの自動起動を設定したいので、/var/lib/lxc/(コンテナ名)/configを編集します。

lxc.network.ipv4 = 10.0.3.200/24
lxc.network.ipv4.gateway = 10.0.3.1
lxc.start.auto = 1

コンテナをdaemonとして起動します*5。デフォルトでSSHサーバーが起動しているのでSSH接続も可能ですが、lxc-attachコマンドでrootのシェルを取ることもできます。コンテナのデフォルトユーザー名/パスワードはubuntu/ubuntuなので、lxc-attachでrootログインし、usermod/groupmod等をしておきました。

$ sudo lxc-start -n owncloud --daemon
$ sudo lxc-attach -n owncloud

genericな設定ができたら、このコンテナのバックアップを取っておきます。lxc-stopでコンテナを停止した状態で、lxc-cloneしました*6。新しいコンテナを作る際は、lxc-createではなく設定済みのバックアップからlxc-cloneする方向で。本当はChefとかを使った方がいいのかもしれないけど。

$ sudo lxc-stop -n owncloud
$ sudo lxc-clone -o owncloud -n backup

各コンテナへのtt-rssやらowncloudやらのインストールについては省略。

リバースプロキシとmod_rpafの設定

各コンテナへアクセスを振り分けるため、ホストにリバースプロキシとしてNginxをインストールします。「Nginxはcurrentこそがstable」とかいう話も聞きますが、せっかく14.04 LTSからはmain入りしているので、Ubuntuのパッケージを使うことにします。どうせリバースプロキシとしてしか使わんしね。

$ sudo apt-get install nginx

UbuntuのNginxの設定はApacheと同様に、バーチャルホストごとの設定を/etc/nginx/sites-availableに作成し、有効にしたいホストは/etc/nginx/sites-enabledにシンボリックリンクを張るという方式になっています。defaultという設定が最初から用意されているので、適宜書き換えるなどします。UbuntuのパッケージからインストールしたownCloudの場合、本体は/usr/share/owncloud以下にインストールされ、/owncloudにAliasが設定される*7という作りになっていますので、そのようなproxy_passを設定します。

location /owncloud {
    proxy_pass http://10.0.3.200/owncloud;
}

バックエンドサーバーへリクエストを転送する際、いくつかのHTTPヘッダを設定する必要があります。たとえばリバースプロキシはHostヘッダをproxy_passに指定した値、この場合はコンテナに割り当てられたローカルIPアドレスへ変更した上でバックエンドへリクエストを投げますが、ownCloudはconfig.php内のtrusted_domainsに設定されていないドメイン名でアクセスされた場合に警告を発します。アクセスされたホスト名は/usr/share/owncloud/lib/private/request.php内のserverHost関数でチェックしており、ここでX-Forwarded-Hostの値も見ているので、X-Forwarded-HostにオリジナルのHostを設定してあげる必要があるわけです。

proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;

またこれだけだと、バックエンドのApacheアクセスログに、リバースプロキシのローカルIPアドレスが記録されてしまいます。これをX-Forwarded-Forに記録されたオリジナルのクライアントIPアドレスに変更するため、コンテナ内にmod_rpafをインストールします。

$ sudo apt-get install libapache2-mod-rpaf

/etc/apache2/mods-enabled/rpaf.confにリバースプロキシのIPアドレスを設定し、Apacheをリロードします。

RPAFproxy_ips 10.0.3.1

POST時のボディサイズ制限にハマる

ownCloudでは、アップロードできるファイルサイズを自由に制限することができ、デフォルトでは512MBになっています。これはownCloudのWeb画面から自由に変更することができるのですが、間にリバースプロキシを挟んでいるため、Nginx側の制限を越えることができません。具体的にはNginxのデフォルト設定でclient_max_body_sizeが1MBになっているため、1MBを越えるファイルのPOST時に413 Request Entity Too Largeが返されます。ownCloud側の設定に合わせて、大きくしておきましょう。私は2GBにしてみました*8

client_max_body_size 2G;

ownCloudクライアントのアクティビティに413が記録されていたら、Nginxの設定変更後に「同期を再実行」を実行しておきましょう。

こんな感じで、ownCloud、tt-rss、Munin、普段の雑用環境などをコンテナに分離してみました。不要になったらコンテナごと削除すればよいし、他所の環境は汚さないし、だいぶすっきりできた気がします*9。リバースプロキシを挟むことで構成が少し変化しましたが、特にトラブルも起きていないし、しばらくこのまま様子を見ようと思います。

*1:tt-rssdojoを内包しているのですが、Debianでは共有ライブラリのパッケージが提供されているので、そちらを使っています。tt-rss_1.12+dfsg-1では、それを理由にtt-rssパッケージ内からdojoが除去されているようです。

*2:makeして/usr/local以下に入れるようなアプリケーションであれば、頑張ってパッケージを作ったでしょうが、Webのコンテンツ領域に展開すればそれだけで動くPHPのアプリなので、あまりこだわっていません。なお設定はすべてDBに持っているので、インストール時に既存のDBを指定して初期化処理をスキップすればデータはそのまま引き継げます。ただし一度admin権限でログインして、DBをアップデートする必要アリ。

*3:昨年の石狩データセンターツアーで貰った2万円クーポンがまだ残っているので、実際には無料で使えてたりします。なおここでクラウド上に作成した複製サーバーのIPアドレスを付け替えたり、DNSの向き先を変えるといった話は省略。

*4:http://gihyo.jp/admin/serial/01/ubuntu-recipe/0329 参照

*5:--daemonを忘れるとコンテナの標準出力が現在のターミナルに繋がれて、そこから抜ける方法がわからなかった……。

*6:もちろんこの状態だと、バックアップしたコンテナにも同じIPアドレスが設定されている上に自動起動してしまうので、このへんは手動で変更しておきます。

*7:という設定がconf-availableに追加され、conf-enabledからリンクされる。tt-rssやMuninなども同様。

*8:0にするとサイズのチェックをしなくなるらしい。

*9:LXCははじめて使ったので、何か間違ってる可能性は否定できませんが……。

Ubuntuではじめる! Linux入門キット 14.04対応

2年に一度、LTSのリリース後には恒例となりつつある、Ubuntu入門キットの最新版が本日発売されました。

Ubuntuではじめる!Linux入門キット14.04対応

Ubuntuではじめる!Linux入門キット14.04対応

今までの入門キットは頭から通して読み進めていく構成だったのですが、「あんまり文章が最初から並んでると取っつきにくい」という編集さんからの意見もあり、「こんなことができるよ」という使用例をまず見てもらうことを目指した構成としました。2章にいきなりTwitterFacebookへの繋ぎ方が書かれているのは、そういう意図です*1
初心者向けに1から解説する場合、「まだ説明していない機能や言葉が説明に使えない」という縛りが割ときついのですが*2、どこから読んでもいいという構成にし、○○については○章を見ろ、と割り切れたのは楽でした。
実は冒頭にあるLinuxUbuntuの説明部分も、初心者にいきなり読ませるには適さないのではということで、順序の入れ換えの提案もありました。しかしこれを冒頭に置かないと(中の人が書いている)入門キットの意味がなくなってしまうと思い*3、ここだけは我侭を通させてもらいました。
そんな構成の変更もあって、12.04からほぼ全面にわたって書き換えました。スクリーンショットは570枚ほど新規に撮影し、すべてGIMPで手を入れています。リリース直後のアップデートでFirefoxの見た目が変わったのも、今となってはいい思い出です。……いや嘘かな。
本書の対象読者は、(PCそのものの初心者も含む)はじめてUbuntuにふれる人なので、おそらくこの記事を読んでいる人には不要かもしれませんが、14.04のガイドブックとしてお手元に置いて頂けたら幸いです。
なお日本語Remixのリリースが4/28、本書を脱稿したのが5/7でした。開発版ではなく、リリースされた正式版できちんと確認を取っている書籍としては、(リリースから二ヶ月近く経過してしまっているとはいえ)最速に近いタイミングなんじゃないかなーと思います。

*1:編集部からの案では1章に位置してたんですが、さすがに基本操作くらいは最初に書かせてくれよ、ということで2章になっています。

*2:コマンドライン入門とか、かなりきつかったです

*3:言い方は悪いですが、単なるハウツー本と同じになってしまうと思い

UbuntuでさくらのBASE Storageを試す

さくらのBASE Storageという、Amazon S3互換のインターフェイスを備えたオブジェクトストレージのベータサービスが開始されました。さっそくUbuntuから利用してみましょう。

サービスアカウントを開設する

BASE Storageには専用のサービスアカウントが必要です。既にさくらのVPSさくらのクラウドを利用している人であっても、まずは新規にサービスアカウントを作りましょう。
ログイン画面からさくらインターネット会員IDでログインし、任意の名前でアカウントを作成します。

ネームスペースを作成する

作成したサービスアカウントでBASE Storageサービスへログインすると、まずはネームスペースの作成画面に遷移します。

ネームスペース名が、S3でいうバケット名に相当します。現時点ではネームスペースは1つしか作成できないようです。

ネームスペース作成時、このようにエラーが出る場合があります。これはネームスペース名に英大文字を含めた時のエラーですが、メッセージからそれを察するのは難しいですね。
ちなみにネームスペース名はサービス全体でユニークでなければならないため、既に他のユーザーに使用されている名前を指定した時も同じエラーが表示されます……されました。昨日は。
こちらのエラーは、今日になって「Duplicate」と表示されるようになったので、このあたりは日々改善されていくと思います。

ネームスペースの作成が成功すると、このような画面に遷移します。「アクセストークン」の欄に表示されている「ユーザ名」がS3のAccess Key、「トークン」がSecret Access Keyに相当します。また下部に「https://(ネームスペース名).b.storage.sakura.ad.jp/」というURLが表示されているところからわかると思いますが、「http(s)://b.storage.sakura.ad.jp」がエンドポイントになります。
ネームスペース名とトークンを控えたら、サーバー側の準備は完了です。

s3fsをインストールする

次に、ストレージをマウントするサーバーを用意しましょう。今回はさくらのクラウドと、Amazon EC2の東京リージョン、それぞれにサーバーを用意してみましたが、インターネットに接続されていればどこでも構いません。
OSはUbuntu 13.10を使用しました。EC2を使っている場合は、このへんから起動すると便利です。
s3fsはDebianパッケージが存在しないので*1、ソースからビルドします。
面倒な解説は省略しますが、以下の手順でビルドできるはずです。

$ sudo apt-get install build-essential libfuse-dev libcurl4-openssl-dev libxml2-dev mime-support
$ wget http://s3fs.googlecode.com/files/s3fs-1.74.tar.gz
$ tar zxvf s3fs-1.74.tar.gz
$ cd s3fs-1.74
$ ./configure
$ make
$ sudo make install

passwd-s3fsファイルを用意する

s3fsでS3バケットをマウントするには、Access KeyとSecret Access Keyが必要です。キーを設定する方法はいくつかあるのですが、一番簡単なのがホームディレクトリの.passwd-s3fsというファイルにコロンで区切って書いておく方法です。

$ echo 'ユーザ名:アクセストークン' > ~/.passwd-s3fs
$ chmod 600 ~/.passwd-s3fs

他にも/etc/passwd-s3fsに置く、passwd_fileオプションで任意のファイルを指定する、環境変数に設定する、などの手段がありますが今回は省略します。

マウントする

s3fsコマンドをsudoで実行して、S3バケットをマウントします。

$ sudo mkdir /mnt/s3
$ sudo s3fs (ネームスペース名) /mnt/s3 -o url=http://b.storage.sakura.ad.jp -o allow_other,default_acl=public-read

s3fsはデフォルトでhttp://s3.amazonaws.comにアクセスしようとします。urlオプションで、接続先を明示的に指定してください。
またマウントした以外のユーザーでのアクセスを許可するため、allow_other、パーミッションを指定するためdefault_acl=public-readを指定しています。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1      7.8G  960M  6.4G  13% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
udev            285M  8.0K  285M   1% /dev
tmpfs            59M  188K   59M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            295M     0  295M   0% /run/shm
none            100M     0  100M   0% /run/user
s3fs            256T     0  256T   0% /mnt/s3

このように、dfコマンドから256TBの領域が見えていれば、マウントは成功しています。
ベータ期間中は無料で容量無制限ということなので、色々とデータを置いてみましょう。ベンチマークを取ったわけではないですが、体感ではS3よりだいぶ早く感じます。

SSLを使う

urlオプションにhttpを指定していたことから、はてな? と思われた方もいると思います。
スキーマhttpsに変更してみると、以下のようなエラーが出ます*2

s3fs_init(2595): init
s3fs_check_service(2894): check services.
    CheckBucket(2228): check a bucket.
LocateBundle(597): s3fs: /etc/pki/tls/certs/ca-bundle.crt is not readable

どうやらデフォルトではRHEL/CentOSのCA証明書のパスを見に行ってしまうようです。ソースコードcurl.cppを見てみます。

  ///////////////////////////////////////////
  // from curl's (7.21.2) acinclude.m4 file
  ///////////////////////////////////////////
  // dnl CURL_CHECK_CA_BUNDLE
  // dnl -------------------------------------------------
  // dnl Check if a default ca-bundle should be used
  // dnl
  // dnl regarding the paths this will scan:
  // dnl /etc/ssl/certs/ca-certificates.crt Debian systems
  // dnl /etc/pki/tls/certs/ca-bundle.crt Redhat and Mandriva
  // dnl /usr/share/ssl/certs/ca-bundle.crt old(er) Redhat
  // dnl /usr/local/share/certs/ca-root.crt FreeBSD
  // dnl /etc/ssl/cert.pem OpenBSD
  // dnl /etc/ssl/certs/ (ca path) SUSE
  ifstream BF("/etc/pki/tls/certs/ca-bundle.crt");
  if(BF.good()){
     BF.close();
     S3fsCurl::curl_ca_bundle.assign("/etc/pki/tls/certs/ca-bundle.crt");
  }else{
    DPRN("%s: /etc/pki/tls/certs/ca-bundle.crt is not readable", program_name.c_str());
    return false;
  }
  return true;

なるほど、見に行くファイルがハードコードされているんですね。ここをコメント通りに書き換えてコンパイルしてもいいのですが、この直前に以下のようなコードがあります。

  char *CURL_CA_BUNDLE;

  if(0 == S3fsCurl::curl_ca_bundle.size()){
    CURL_CA_BUNDLE = getenv("CURL_CA_BUNDLE");
    printf("hoge: %s\n", CURL_CA_BUNDLE);
    if(CURL_CA_BUNDLE != NULL)  {
      // check for existance and readability of the file
      ifstream BF(CURL_CA_BUNDLE);
      if(!BF.good()){
        DPRN("%s: file specified by CURL_CA_BUNDLE environment variable is not readable", program_name.c_str());
        return false;
      }
      BF.close();
      S3fsCurl::curl_ca_bundle.assign(CURL_CA_BUNDLE);
      return true;
    }
  }

環境変数CURL_CA_BUNDLEに証明書のパスを格納しておけばよさそうです。というわけで、環境変数を設定してみます*3

$ export CURL_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt"

これでhttpsでマウントしようとすると……

s3fs_init(2595): init
s3fs_check_service(2894): check services.
    CheckBucket(2229): check a bucket.
    RequestPerform(1618): ### retrying...
    RemakeHandle(1289): Retry request. [type=5][url=https://0vdet9e.b.storage.sakura.ad.jp/][path=/]
RequestPerform(1574): curlCode: 60  msg: Peer certificate cannot be authenticated with given CA certificates

証明書は読んでくれたようですが、うまく検証できません。ナンデ? というところで今日はここまで。

*1:s3fs自体はGNU GPLv2ですが、OpenSSLにリンクする都合上、バイナリの再配布ができません。

*2:これはs3fsに-fオプションをつけて、フロントエンドモードで実行させて確認しています。

*3:Ubuntuのデフォルトではsudo時に環境変数が引き継がれないため、必要であればsudoersにkeep_envを設定してください。

Ubuntu Magazine Japan 2013 Summer 発売!

11冊目の Ubuntu Magazine が発売になりました。今回から

  • 編集Sさんの卒業にともない、編集さんが変わりました。
  • 表紙のロゴが変更されました*1
  • 号数が通し番号から西暦に変更されました。
  • 電子書籍版が販売されます。Kindle 版は 800 円と超お得です。

といった変更があります。
付録 DVD には 64bit の日本語 Remix がついていたり*2、といった部分は他の人が紹介しているので、自分の記事について少し補足しておきます。

今回は、以下の 3 つ、合計 20 ページを担当しました。

つまり、レギュラー連載以外は Steam しか書いてないってことですね!
本誌にも書いていますが、Steam の記事はマウスコンピューターの試作機をお借りして書きました。実はマウスの G-Tune シリーズは、個人的に 1 台持っていて、現在もファンタシースターオンライン 2 を遊ぶのに使っています。このマシンは FF14 の CBT に当選した時に購入したのですが、マザーボードに問題があったり、グラボで不良を引いたり、ケースの中身がいじりづらかったりと、あまりいい印象がありません。ところが今回お借りしたマシンは、ケース開けやすいし、内部はすっきりしているし、Ubuntu での動作にも問題はないしで、だいぶマウスの印象が変わりました。OS レスのゲーム PC を手っ取り早く確保したいという人には、悪くない選択かもしれません。でも SSD は欲しいところですね。

コマンドライン再入門は……実は原稿のドラフトの段階では 1.5 倍、12 ページあったんですよ。それをかなり削り、圧縮し、であんな感じになりました。ちょっと詰め込みすぎ、駆け足すぎな感はありますが、半年後まで続きはおあずけ、というのは絶対いやだったので。
lesspipe や lessfilter って、意外と知らない人がいるんじゃないかなーと思いますし、シェルスクリプト入門としては、いい感じで着地できたんじゃないかと自画自賛しています。
ちなみに削った部分は、次号で補完する予定です。

最近のロードテストはもう何でもありの無法地帯になっているので*3、色々好き放題やらせてもらっています。ただ刊行ペースの問題で、対象機種がどんどん陳腐化してしまうのが悩みの種ですね。

最後に。
電子書籍版が発売になりましたが、CC-BY-NC での PDF 公開は継続します。ですが無料で公開できるということは、誰がその分のコストを支払っているのかということを考えて頂けるとよいのではないでしょうか。また仮に電子版がバカ売れしたとしても、紙の書籍が売れないと、雑誌の刊行そのものがピンチになってしまうという問題もあるようです。ゴロ寝しながらダラダラとページをめくるような場合はタブレットより紙の方が快適ですし、紙の書籍も買って頂けると嬉しいですね。

*1:個人的には前の方がよかったなあ

*2:うぶまが限定で、Webでの公開は予定されていません。ですがもちろん自由にコピーできるので、安心して使ってください。

*3:事実誤認