ryhmrt’s blog

意識低い系プログラマの雑記

VirtualBox の Guest Addition を入れ直す

事の始まり - 共有フォルダのマウントエラー

Vagrantで構成している仮想マシンを再起動したら下記のようなエラーが出て、共有フォルダがマウントされないようになってしまった。

    default: /vagrant => /Users/ryhmrt/Projects/hoge
Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3`,dmode=777,fmode=666 vagrant /vagrant
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant`,dmode=777,fmode=666 vagrant /vagrant

The error output from the last command was:

/sbin/mount.vboxsf: mounting failed with the error: No such device

/Users/ryhmrt/Projects/hoge% vagrant ssh

ググってみると、Guest Addition を入れ直せということらしい。

Guest Addition の iso ファイルを取得

http://download.virtualbox.org/virtualbox/ から辿って最新版の iso ファイルをダウンロード。

ホストの方でダウンロードしてしまったので、scpでゲストに転送するという2度手間をしてしまったが、ゲスト側でcurlでも使ってダウンロードすれば良かった。

Guest Addition インストール

vagrant ssh でゲストに入り

必要なパッケージをインストールをしておく

$ sudo yum install gcc kernel-devel

isoをマウントして

$ sudo mkdir -p /mnt/disk/
$ sudo mount -o loop VBoxGuestAdditions_5.0.8.iso /mnt/disk/

インストーラーを実行する

$ sudo /mnt/disk/VBoxLinuxAdditions.run

こんなエラーが出るけれども、Xは使わないのでそのまま無視

Building the OpenGL support module [失敗]
(Look at /var/log/vboxadd-install.log to find out what went wrong. The module is not built but the others are.)

ホスト側に戻って、 vagrant reload して共有フォルダがきちんとマウントされることを確認

Makati Shangri-La - Lobby Lounge

最近全くアウトプットが無かったので、無理にでも何かアウトプットをして習慣づけをしようかと思いました。とりあえず近所のレストランやら何やらを貼り付けてみます。

Makati Shangri-La はマカティで2番目か3番目くらいに番付けされるホテルだと思います。入り口を入って正面奥にあるラウンジはビジネス/プライベートの打ち合わせにうってつけです。

アフタヌーンティーセットと共にオーケストラの生演奏を間近に聴いていると優雅な気分に浸れます。たまに音がずれているような気もしますが。

www.shangri-la.com

写真

f:id:ryhmrt:20151107174219j:plain

予算

お茶やコーヒーは一杯200ペソ程、午後3時〜6時までは2人分のアフタヌーンティーセットが730ペソで提供されています。

ちょっとオシャレな喫茶店とそう変わらない値段で、天井の高い広々とした場所で生演奏と共にお茶ができるのでお得感があります。

参照: Menu | Lobby Lounge | Makati Shangri-La Manila Makati

場所

雑記

席数はそんなに多くありませんが、行って座れなかった記憶はありません。きれいなおねーさん方が席を探してくれますので、ふらっと入って声を掛けて席に案内してもらいましょう。

オフィシャルサイトを見るとドレスコードに Smart casual と書いてありますが、かなりカジュアルな格好でも小綺麗になっていれば浮かないはずです。

アフタヌーンティーセットはボリュームが多めに感じました。昼をしっかり食べた後だと完食できないかもしれません。

livedoor to はてな

少し前までlivedoorのブログを使っていたのですが、管理画面がなんかイケてないような気がしたのと、同じサービスばかり使っていて飽きたので、はてなに移行してみました。

こんな時に独自ドメインで運用していると、何の気兼ねもなく移れて気持ちが良いです。 個別記事へのリンクが途絶えたりなんて小さいことは気にしてはいけないのです。

ざっと触ってみた感じ、livedoorブログよりも使いやすい感じがします。 料金はlivedoorの倍以上ですが、おおむね満足です。

Gitで差分ファイルをZipに固める

いろいろなオトナの事情でお客さんのリポジトリに直接アクセスできなかったりすると、差分ファイルを作ってZipに固めて渡すとかいうことがあります、というか現在進行形でやっています。

Gitの --name-only オプションで差分ファイルの一覧を取って、Zipの -@ オプションでアーカイブするファイルを指定するのが便利だったのでメモを残しておきます。

次に差分を出すときのために差分出したらタグを打ちましょう。

$ git diff Release20150729 --name-only | zip diff.zip -@

PostgreSQL 8.2 の暗黙の型変換の罠

はじめに

PostgreSQL 8.2 を使ったプロジェクトに携わることになったのですが、他のミドルウェアのバージョンの関係で手元にできあがったのが PostgreSQL 8.4 の環境になりました。

ダウングレードするのは面倒くさいし、大してバージョンも違わないから大丈夫だろうとタカを括ったら思いの外動きませんでした。

問題点

PostgreSQL 8.2 までは暗黙の型変換でいろいろなデータが文字列型に変換されて実行されるケースがあったのですが、PostgreSQL 8.3 からはそんな汚い動作はしないようになったそうです。

そのため、PostgreSQL 8.2 までは実行できたクエリも、PostgreSQL 8.3 以降では型エラーで実行できないケースがあるとのこと。

例えば select length(1); とか実行すると、PostgreSQL 8.3 以降では以下のようなエラーが出るはず。

ERROR:  function length(integer) does not exist at character 8
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
STATEMENT:  select length(1);

解決方法

将来的にPostgreSQLのバージョンアップとかもあるかもしれないし、と思い、PostgreSQL 8.4 で動くようにすることにしました。

自動キャストの設定を追加することである程度 PostgreSQL 8.2 の動作を再現できるということなので、まずはそれを設定。

そもそも型変換する必要がない箇所もあったので、そこはクエリをちまちま修正。

見事動作致しました。

本当は型変換が頻繁に発生しているのはおかしいので、根本的にデータ構造を見直さなきゃいけないんだろうけど...

参考

CakePHP3のメッセージ定義でJavaScriptを多国語化

フィリピンでシステムを作って日本に納めるために、英語版を作って日本語化するというアプローチを取っているのだけれど、React.jsをシステムに取り入れたところJavaScriptローカライズする必要が生じて、えいやっとやってみました。

これで CakePHP と同じように __('Hoge') という感じでローカライズできるようになります。

同僚からは笑われましたが、ローカライズはお前の担当だから好きにしろとのことなのでこいつを正式採用することにします。

無駄に力を入れて、メッセージ定義ファイルから生成したJavaScriptをキャッシュしているのが個人的なネタポイントです。

ちなみに、一般公開するページと管理者用のページを分けていたりする場合は、メッセージの内容で中身を推測されてよろしくない事態が発生するかもしれないので、そんなときはメッセージ定義を分けるとかすると良いと思ったり。

app/src/Controller/JsController.php

以下のファイルを作成。

<?php
namespace App\Controller;

use App\Model\Table\StudentsTable;
use Cake\Cache\Cache;
use Cake\I18n\I18n;
use Cake\I18n\MessagesFileLoader;

class JsController extends AppController {

    public function initialize() {
        parent::initialize();
    }

    public function i18n() {
        $this->autoRender = false ;
        $this->response->type('js');
        echo $this->_getI18nJs(I18n::locale());
        echo "\n";
    }

    private function _getI18nJs($locale) {
        $cacher = Cache::engine('_cake_core_');
        $key = "js.i18n.$locale";
        $js = $cacher->read($key);
        if (!$js) {
            $js = $this->_generateI18nJs($locale);
            $cacher->write($key, $js);
        }
        return $js;
    }

    private function _generateI18nJs($locale) {
        $messages = $this->_readLocaleMessages($locale);
        $messages = array_filter($messages, function($message){ return !empty($message); });
        $messages = array_map(function($key, $message){
                return  "'" . preg_replace("/([\\\\'])/", "\\$1", $key) . "':'" . preg_replace("/([\\\\'])/", "\\$1", $message) . "'";
            }, array_keys($messages), $messages);
        return '__ = (function(messages){return function(key){ return messages[key] ? messages[key] : key; }})({' . implode(',', $messages) . '});';
    }

    private function _readLocaleMessages($locale) {
        $loader = new MessagesFileLoader('default', $locale);
        $package = $loader->__invoke();
        return $package->getMessages();
    }

}
?>

app/config/routes.php

以下の記述を追加。

Router::scope('/js', function($routes) {
  $routes->extensions(['json', 'js']);
  $routes->connect('/:action', ['controller' => 'Js', 'action' => '(:action)']);
});

app/src/Template/Layout/default.ctp (もしくは他のレイアウトファイル)

以下の記述を追加。

<?php echo $this->Html->script('i18n.js'); ?>

Git 2.4

一週間ぶりくらいにMacPortsを更新したらGitの2.4が振ってきた。

Gitは既に誕生から10年を迎えたらしい。前職から使ってたから自分が使っている期間もそこそこになる。

Atomic Pushes

複数のブランチをpushするときに、一つでもpushが失敗したら他のpushも取り下げるようなことができるようになった。--atomicオプションを使用して以下のようにpushする。

$ git push --atomic origin branch1 branch2 ...

Push-to-deploy の改善

Git 2.3 で導入されたPush-to-deployについて以下の改善が施された。

  • push-to-checkoutフックの追加により、pushされたブランチに対してサーバ側のワーキングツリーに変更があった場合の挙動を定義できるようになった。
  • コミットが一つもないブランチに対してもPush-to-deployが正常に設定できるようになった。

自分はPush-to-deployをまだ使ったことがないので、これらの改善点の嬉しさがいまいちわからない。

git log の --invert-grep オプション

git log コマンドのオプションの --grep=<pattern>, --author=<pattern>, --committer=<pattern>, --grep-reflog=<pattern> それぞれのパターンに一致しないものを検索するためのオプション --invert-grep が追加された。

例えば以下のようにして、自分以外のコミットを確認できる。

$ git log --invert-grep --author=Ryohei

該当するコミットのSHA-1ハッシュだけをリストする git rev-list コマンドをネストすることで、複雑な検索が可能になる。

以下はRyohei、Keisuke、Gissan以外のコミットを検索するコマンド。--stdin--no-walk オプションと共にパイプして、最後だけ git log にする。

$ git rev-list --no-merges --invert-grep --author=Ryohei master |
      git rev-list --stdin --no-walk --invert-grep --author=Keisuke |
      git log --stdin --no-walk --invert-grep --author=Gissan

git status -vv

git status コマンドに -v オプションを2つ付けると、コミットされていない変更差分が一緒に出力されるようになった。git status に続けて git diff --cachedgit diff が出力されてる感じ。

参照

自分は一時情報としてブログ記事 Git 2.4 — atomic pushes, push to deploy, and more を参照しました。

詳細はGit 2.4 リリースノートを参照。