gitprep の docker 化

前略
クラウド(ようやく)始めました。

「そうだ、Gitprep 入れてみよう!」
→ セットアップでエラー
→ いろいろ試してもエラー
…サーバ引っ越しの度にこんなエラー地獄では耐えられません。

「そうだ、Docker 使おう!」
→ perl イメージある
→ mojolicious イメージある
→ ソースコード足せば動く?

(3時間経過)

「や、やっと動いた…」
→ 他にも同じ苦労をする人がいるかも…(← いません)
→ 公開しなきゃ
→ ウェブログに投稿だ!

(1時間経過)

「記事書けたけど Dockerfile より短い…何故?」 ← 今ここ
作ったファイルはこちら

Putty 経由の Emacs で C-M-S-v が入らない件(未解決)

今回は Emacs です。
以前から使ってはいたのですが、ここを参考に設定しなおしてみようかと思いまして。

とりあえず Ubuntu Linux の仮想マシンを用意して Putty でログインして Emacs をいじっていました。
で、サンプルの通りにキーバインド「C-,」を割り当てて使ってみると動きません。
現在の割り当てを調べる「C-h c C-,」を使ったところ、どうも「C-,」が Linux に入っていないようでした。

この問題については最終的にこのサイトを参考にして解決できました。

該当ページ中から「xterm風定義」リンクを辿ると他のキー一覧もあります。
その中でカンマを示す「VKey188」の行ですが、以下(4番目が \033[27;6;60~)が正しいのではないかと思います。
VKey188=\054,<,\033[27;5;44~,\033[27;6;60~,\033\054,\033<,\033[27;13;44~,\033[27;14;60~

引き続いて「C-M-v」の別ウィンドウスクロールの逆方向版を「C-M-S-v」(Shift を追加する)に割り当てようとしましたが、こちらは解決できませんでした。
「C-,」と同様に「VKey…」を追加すればいいかと思って下のように色々試したのですがダメでした。

試した内容

  • VKey86=,,,,,,,\033[27;14;118~
  • VKey86=,,,,,,,\033[27;14;86~
  • VKey86=,,,,,,,\033[27;14;v~
  • VKey86=,,,,,,,\033[27;14;V~
  • VKey86=,,,,,,,\033[27;5;118~
  • VKey86=,,,,,,,\033[27;5;86~
  • VKey86=,,,,,,,\033[27;5;v~
  • VKey86=,,,,,,,\033[27;5;V~

カンマ区切りのキーコード出力部の内容は 「\033[27;≪修飾コード≫;≪キーコード≫~」だろうと思っています。
この中にある「27」は多分 Escape キーの VKey コードでしょう。

どれも思うようにいかなかったので、現在はエスケープシーケンスの規則を調査中です。
参考サイトに書いてある気もしますが、英語を読むのが面倒なので Try&Error で頑張ります。

参考サイト

ちなみに「C-,」問題は nadoka で「key C-Comma = &SendText("\e[27;5;44~")」でも解決できましたが、対象文字列を入れる時に一文字ずつ(少しだけ)ウェイトがかかって微妙な気分になるので止めました…

暗号化とか署名とかハッシュとか

まずは、ざっくりとした一覧です。

こうしてまとめてみると、思っていたよりも色々ありますね。

特に Windows に certutil コマンドがあって、エンコードとハッシュ計算ができるのには驚きました。

それと、暗号化ファイルを元に戻す時には(大抵の場合)同じソフトが必要になります。 渡す相手には何のソフトで暗号化したか伝えておきましょう。

バッチの find | xargs では -r オプションを付けること > 未来の自分

今回は短いです。ライトニングな感じです。

xargs なんですが、結構 find と組み合わせて使いますね?
…使いますよね?
…ここは空気読んでウソでも「使う」って言う所ですよ?

で、パイプした find の出力が空だった場合でも xargs の部分が実行されてしまうんですよ。
衝撃の事実ですね。ええ、インパクトありますよ。rm -rf とか食わせてると特に…
まあ、今回はテストで echo 付けてあったので死なずに済みましたが。

というわけで、crontab とかのバッチ処理の時は xargs -r の使用を考慮しましょう。
こうすると、入力が空の時には xargs に食わせたコマンドが実行されません。
バッチ利用(大抵は cron)の時は付けた方がいいと思います。

PostgreSQL の UPDATE トリガで時刻を自動設定できなかった話

今回はいつになく簡易版でお送りします。

ようは下のようなトリガを書いても期待通りに動かなかった話です。

該当カラムの定義は updatedAt TIMESTAMP DEFAULT current_timestamp NOT NULL です。
MySQL の時は updatedAt DATETIME DEFAULT current_timestamp ON UPDATE current_timestamp NOT NULL と書けばトリガ不要で自動更新してくれますね。

-- UPDATE 文の実行時に updatedAt カラムを
-- 現在時刻に設定してくれるトリガ(PostgreSQL 用)
-- 動作不良版
create or replace function set_updated_at() returns trigger as $function$
begin
if new.updatedAt is null then
new.updatedAt := current_timestamp;
end if;
return new;
end;
$function$ language plpgsql;

create trigger auto_set_updated_at before update on SomeTable for each row
execute procedure set_updated_at();

これで SomeTable の UPDATE 文実行時に updatedAt カラムをその時の時刻で更新してくれるはずでした。
ところが、どうやら SET 句に updatedAt カラムを指定しない場合でも new.updatedAt が NULL になってくれないようです。(例えば UPDATE SomeTable SET OtherCol = 1)

で、色々試して、とりあえず動いたのが次のバージョンです。
ちなみに、明示的に SET 句で値を指定した時(updatedAt = ‘2016-06-06 12:00’ 等)は、そちらを使います。

-- UPDATE 文の実行時に updatedAt カラムを
-- 現在時刻に設定してくれるトリガ(PostgreSQL 用)
-- いちおう動作版
create or replace function set_updated_at() returns trigger as $function$
begin
-- 次の行の条件を変更
if new.updatedAt is null OR new.updatedAt = old.updatedAt then
new.updatedAt := current_timestamp;
end if;
return new;
end;
$function$ language plpgsql;

動いたのはいいんですが、なぜ new.updatedAt が NULL じゃないのか気になって仕方ありません。
どなたか理由をご存知でしたら、ぜひともご教示ください。

VirtualBox に CentOS 6.7 を入れた後で NAT にした時の設定

例によって忘れた時用のメモです。

タイトル通りなんですが、VirtualBox で CentOS 6.7 を使った時に困った話です。
状況としては下のようになります。

  1. ネットワーク設定で最初に NAT以外(ホストオンリー等)のネットワークアダプタを選んだ
  2. そのアダプタを後から NAT にした

この場合、VM を起動しても NAT からインターネットへのアクセスができません。
とりあえず下のように設定したら NAT を通って外へ出られました。

  • /etc/sysconfig/network ファイル
    • GATEWAY の行をコメントアウト(先頭に「#」を追加)する
  • /etc/sysconfig/network-scripts/ifcfg-eth0 を下の内容にする(NIC の数によっては eth0 の「0」を別の数字に読み替えます)
    DEVICE=eth0
    ONBOOT=yes
    BOOTPROTO=dhcp

ちなみに、NAT が動いた時の IP が「10.0.5.15」で、デフォルトルートは「10.0.5.2」でした。
このパラメータを利用して手動設定ができるかもしれません。どなたか試したら教えてください。

今回は短い(当社比)ですが、以上です。

phpMyAdminの環境保管領域が完全に設定されていない… エラー

おひさしぶりです。
不定期開催の今回のネタは phpMyAdmin on Ubuntu 14.04 LTS です。

とりあえずパッケージ入れてみたんですよ。
そしたら、ログインすると「phpMyAdmin 環境保管領域が完全に設定されていないため、いくつかの拡張機能が無効になっています。理由についてはこちらをご覧ください。」と表示されたわけです。
コマンドラインから見てみると、環境保管領域に使われる phpmyadmin データベースが無かったので CREATE TABLE して…ダメ。
中身を入れればいいのかと /usr/share/doc/phpmyadmin/examples/create_tables.sql.gz を流し込んでみても…ダメ。
権限の問題かと CREATE USER と GRANT を駆使しても…ダメ。

…結局、/etc/phpmyadmin/config.inc.php の中身で環境保管領域用のテーブル名を定義している部分で「_」(下線、アンダースコア)が一つ不足していたのが原因でした。
直接そのファイルを直すかわりに /etc/phpmyadmin/conf.d/env-storage.php を以下の内容で作りました。
ほとんどは /usr/share/doc/phpmyadmin/example/config.example.inc.php からコピーしたものです。


<?php // ここから

$i = 1; // インデックスを 1 に戻して(1-ベースなので最初が 1)
/* Storage database and tables */
$cfg['Servers'][$i]['bookmarktable'] = 'pma__bookmark';
$cfg['Servers'][$i]['relation'] = 'pma__relation';
$cfg['Servers'][$i]['table_info'] = 'pma__table_info';
$cfg['Servers'][$i]['table_coords'] = 'pma__table_coords';
$cfg['Servers'][$i]['pdf_pages'] = 'pma__pdf_pages';
$cfg['Servers'][$i]['column_info'] = 'pma__column_info';
$cfg['Servers'][$i]['history'] = 'pma__history';
$cfg['Servers'][$i]['table_uiprefs'] = 'pma__table_uiprefs';
$cfg['Servers'][$i]['tracking'] = 'pma__tracking';
$cfg['Servers'][$i]['designer_coords'] = 'pma__designer_coords';
$cfg['Servers'][$i]['userconfig'] = 'pma__userconfig';
$cfg['Servers'][$i]['recent'] = 'pma__recent';
/* Contrib / Swekey authentication */
// $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey-pma.conf';
?> // ここまで

それから、試行錯誤している時に /etc/phpmyadmin/config.inc.php を見ていたところ、設定ファイルは次のような順序で読み込まれるようでした。(後ろにある内容が優先)

  1. /var/lib/phpmyadmin/config.inc.php (phpMyAdmin/setup で変更されるファイル)
  2. /etc/phpmyadmin/config-db.php
  3. /etc/phpmyadmin/config.inc.php (今回の悪の元凶)
  4. /etc/phpmyadmin/conf.d/*.php (設定を追加した場所)

…以上で今回のレポートを終わります。

ufw によるファイアウォール

今回は ufw です。
以前からパッケージにあるのは知っていたのですが、VPS の Ubuntu 14.04 LTS に標準で入ってるのを触るまでスルーしてました。

ファイアウォールと言えば設定した途端に SSH が使えなくなって、泣きながら実マシンのコンソールまで駆け付けるハメになる、というのはよく有る話です。
今回はクラウドの VPS を使っており、何故か Web の管理画面からコンソールが見られないという、危険が危ない状態だったので細心の注意を払いました。

ドキュメントと man を読み漁り、iptables の一番上に作業マシンの IP 許可設定を突っ込み、ufw にも IP の許可と SSH の許可を設定した上でドキドキしながら「ufw enable」を実行しました。

結果的には ufw の設定だけでも十分でしたが、iptables に書いておいた設定が上に残っているのを見て、転ばぬ先の杖は大事だと実感しました。

ちなみに ufw の使い方は、設定を ufw コマンドで行い、準備ができたら「ufw enable」で有効化するという手順になります。とりあえず、次のコマンドを設定しておけば SSH が切れる心配は少ないと思います。


ufw allow 22/tcp
ufw allow from 作業マシンのIPアドレス

指定内容は「ufw status」で見られます。
詳細な形式は(私の所では) /lib/ufw/user.rules に記録されていました。

以上。いつものように備忘メモでした。

仮想 IP アドレスをフェイルオーバーする方法

お久しぶりです。
相変らず不定期更新で、作業メモばかりのブログです。

今回は (Debian系)Linux で、仮想 IP アドレスをフェイルオーバーする方法のメモです。
簡単に言うと、サーバ 2台の状態で片方がコケた時に残ってる方でサービスを継続したい時に使う手法です。って、全然簡単じゃないですね…

では下準備からです。
■材料

  • サーバ 2台(もちろん仮想マシンでも可)
  • ネットワーク 2個(つまり NIC 2枚ずつとハブ 2個)
  • クライアントマシン 1台(切り替え状況をチェックします)

■準備手順

  1. サーバに Debian系OS(最近だと Ubuntu が多いですかね)を入れます
  2. サーバに fake パッケージをインストールします(send_arp コマンドが入ります)
  3. サーバに arping パッケージをインストールします
  4. サーバを 2つのネットワークに接続する設定をします(/etc/network/interfaces ですね)
    便宜上それぞれを WAN と LAN と呼びます。また、サーバ名は srv1、srv2 とします。

    • LAN(eth0):192.168.1.0/24, srv1(192.168.1.11), srv2(192.168.1.12)
    • WAN(eth1):10.0.0.0/24, srv1(10.0.0.11), srv2(10.0.0.12)
  5. クライアントマシン(名前:cli)を WAN に接続します(IP:10.0.0.20)

それで、実際に切り替える操作です。

  • 仮想 IP アドレス($VIP)を 10.0.0.1 とします
  • WAN側デバイス($DEV = eth1)の MAC アドレス($MAC)を次だとします
    • srv1(000011110000)
    • srv2(222200002222)

■メイン側サーバ(srv1)へ仮想 IP を付けます

srv1> ip addr add $VIP/24 dev $DEV

■クライアント側からチェックします

  • IP アドレス:「cli> ping $VIP
  • ARP キャッシュ:「cli> arp」(10.0.0.1 が 000011110000 になるはずです)

■仮想 IP をフェイルオーバーするコマンドです
ここでは仮想 IP の存在チェックを繰り返して、失敗したら 仮想 IP の設定と ARP キャッシュの更新通知を行います。

  1. 仮想 IP の存在チェック:「srv2> arping -q -c 1 -I $DEV $VIP
  2. 仮想 IP の設定(srv1 の時と同様):「srv2> ip addr add $VIP/24 dev $DEV
  3. ARP キャッシュの更新通知:「srv2> send_arp $VIP $MAC 255.255.255.255 ffffffffffff $DEV $MAC ffffffffffff reply

たぶん、実際には下に書いたようなスクリプトを実行することになります。

■srv1 の仮想 IP を外します
srv1> ip addr del $VIP dev $DEV

■クライアント側からチェックします
前と同様に ping と arp を実行します。
arp の表示で 10.0.0.1 が 222200002222 に変わっているはずです。


仮想 IP フェイルオーバー用スクリプト


#!/bin/bash

VIP="10.0.0.1"
DEV="eth1"
BCAST_IP="255.255.255.255"
BCAST_MAC="ffffffffffff" # f x 12

health_check() {
arping -q -c 1 -I $DEV $VIP
return $?
}

ip_failover() {
MAC=`ip link show $DEV | egrep -o '([0-9a-f]{2}:){5}[0-9a-f]{2}' | head -1 | tr -d \:`
ip addr add $VIP/24 dev $DEV
send_arp $VIP $MAC $BCAST_IP $BCAST_MAC $DEV $MAC $BCAST_MAC reply
}

while health_check; do
echo "health check ok!"
sleep 1
done
echo "fail over!"
ip_failover

もちろん、実際に使う時には echo の部分はコメントアウトする事になるでしょう。


また、作業中に気付いた点は以下の通りです。

  • 仮想 IP のチェックは 「arping -q -c 1 -I $DEV $VIP」 の方が 「ping -c 1 $VIP >/dev/null」 よりも早くダウンに気付きました
  • Web でクライアント(実際には WAN のルータ)に 「echo 1 > /proc/sys/net/ipv4/conf/all/arp_accept」 を設定した方が良いと書いてありましたが、今回は設定値が 0 でも期待通りに動きました
  • ARP キャッシュ更新に使う send_arp コマンドですが、Web で調べた 「send_arp $VIP $MAC $BCAST_IP $BCAST_MAC $DEV」 では期待する ARP Reply ではなく ARP Request になってしまいました

virtualbox のゲスト Debian で nat ネットワークがつながらなかった件

掲題の通り、virtualbox で nat に設定したネットワークアダプタを用意してインストールすると、再起動後に外部ネットワークに接続できない状態になっていたので、開通させるまでの手順をメモ。

結論から言うと以下の 4手順で完了。

  1. ifconfig eth0 10.0.2.15 netmask 255.255.255.0
  2. route add default gw 10.0.2.2
  3. apt-get install ifupdown
  4. /etc/network/interfaces を編集
    • iface eth0 inet dhcp をコメントアウト
    • iface eth0 inet static
    • address 10.0.2.15
    • netmask 255.255.255.0
    • up route add default gw 10.0.2.2
    • down route del default gw 10.0.2.2

ここに行き着くまでに /etc/default/network をいじったり、何度も /etc/network/interfaces を書き直したり、手動で ip コマンドを叩きまくったりと大変だった…
特に /etc/network/interfaces を有効にするには ifupdown パッケージが入ってないとダメだと分かるまでに、だいぶかかってしまった。