WindowsでVagrantでPageant使ってSSHエージェント転送

なんかはてなブログの下書きの仕様が変わったのか、書いてたの途中で消えちゃったので面倒なので適当に。

WindowsVagrantでPageant使ってSSHエージェント転送するのは簡単だよという話。provisionでGitとか叩くときとかに必要になるアレ。

  • GIT_SSHplink.exeのパスを。
  • Vagrantfileにconfig.ssh.forward_agent = trueを。
  • もちろんPageantにキー突っ込んでおく。

だけで行ける。簡単。

ただこれだけだと、provisionerからroot以外にsuとかsudoするとかした場合にそのままだと行けない。ので、

  • provisionerでSSHする前に、Defaults env_keep += "SSH_AUTH_SOCK"とかをsudoersに突っ込んで、環境変数を渡しつつ、
  • setfacl -R -m u::rwx "${SSH_AUTH_SOCK%/*}"なりして、権限も与える。

とやる。

SSH Agent-Forwarding works, but what about sudo -u username no shell/ permissions? composer - Unix & Linux Stack Exchange

その他数ヶ所参考にしたんだが、どこだったやら……。

vagrant-cachierはvagrant-vbguestと競合するっぽい

WindowsVagrant 1.9.1にcachier, vbguestのプラグインを入れた状態で、

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.synced_folder ".", "/vagrant", type: "virtualbox"

  config.vm.provision "shell", inline: "sudo yum update -y kernel"

  config.cache.scope = :box
end

みたいなVagrantfileを用意。vagrant upして、続いてvagrand reloadすると、

$ vagrant reload
==> default: Attempting graceful shutdown of VM...
==> default: Checking if box 'centos/7' is up to date...
==> default: Clearing any previously set forwarded ports...
==> default: Fixed port collision for 22 => 2222. Now on port 2200.
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 (guest) => 2200 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2200
    default: SSH username: vagrant
    default: SSH auth method: private key
==> default: Machine booted and ready!
[default] No installation found.
Loaded plugins: fastestmirror


Error making cache directory: /var/cache/yum/x86_64/7/base error was: [Errno 2] No such file or directory: '/var/cache/yum/x86_64'

==> default: Checking for guest additions in VM...
    default: No guest additions were detected on the base box for this VM! Guest
    default: additions are required for forwarded ports, shared folders, host only
    default: networking, and more. If SSH fails on this machine, please install
    default: the guest additions and repackage the box to continue.
    default:
    default: This is not an error message; everything may continue to work properly,
    default: in which case you may ignore this message.
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

yum install -y kernel-devel-`uname -r` gcc binutils make perl bzip2

Stdout from the command:

Loaded plugins: fastestmirror


Stderr from the command:



Error making cache directory: /var/cache/yum/x86_64/7/base error was: [Errno 2] No such file or directory: '/var/cache/yum/x86_64'

こんな感じのログを吐いて失敗する。

vagrant reloadでなく、vagrant haltしてからvagrant upだったり、あるいはcachierプラグインが入っていなかったりする場合は問題ない。

(なお、もう一つVMが立ち上がっているためポートが競合しているが、そこは本題とは関係ない)

かなり調べても原因が確定できなかったのだが、とにかくvagrant reloadの場合、GuestAdditionsインストールのためのyum update前にcachierのディレクトリが用意できないとか、その辺の理由で失敗しているようだ。

この問題自体もやっかいだが、この問題を調べている途中に気付いた以下の点がさらに酷いと感じている。Vagrantは正直、仕事で使いたいと思わない。

  1. 公式ドキュメントに書いてある"The equivalent of running a halt followed by an up."が思い切り嘘であること。
  2. プラグインを一時的に無効にすることなどが不可能なこと。
  3. 同じVagrantfileでもインストールされているプラグイン次第で挙動が変わること。

つらい。

追記。

追試しやすいようVagrantfileを最小限にしたからアレな感じになったけど、yum updateでぜんぶ更新、とかやると(カーネルを更新しないよう除外していなければ)同じようになる。

じっさい、Ansibleでyum: name='*' state=latestしてはまった。

composer updateでよくわからないエラーメッセージが出たが、指定したブランチがないだけだった

あるアプリケーションが依存している Git リポジトリがあったのだが、master 以外のブランチを参照することになった。ので、composer.json を更新して composer update したら、

The requested package <VENDOR>/<REPO> <BRANCH> exists as <VENDOR>/<REPO>[dev-master] but these are rejected by your constraint.

というよくわからないエラーが出た。

指定したブランチが別名で(というか master として)存在しているがあなたの制約でリジェクトされた、ってどういうこと?

いろいろ調べたがけっきょくわからず、もしやと思って依存リポジトリの方を確認したらけっきょく、参照したいブランチがリモートに push されていなかっただけだった。

master はあるけど指定されたブランチはないよ、master はあなたが指定していないから使わないよ、と言いたかったのだろうか。わからんって。

Vagrantのsynced_folderにはあまり期待してはいけない

そもそもなにがしたかったか

Vagrant + VirtualBoxで開発環境を作ろうとしていて、デフォルトのvagrantユーザで作業するのもアレなんでprovision(今回はansible_local)でユーザを作って、そのユーザのホームディレクトリをホストOSと共有したかった。

試したことと当たった問題

  1. config.vm.synced_folderowner, groupにユーザ名・グループ名を普通に指定。
    • id: magai: no such user
    • フォルダの同期→provisioningの順番なのか。
  2. provisioner側でmountする。
    • mounting failed with the error: Protocol errorとか言われる。
    • どうも、ホストOS側からVirtualBoxに指示(GUIなどから?)しないとホストOS側のパスが見えない? ちょっとここ原因が最後までわからなかった。
  3. 仕方ないので、synced_folderで、uid, gidで直接指定しつつ、provisioner側で、uid, gid指定でユーザ、グループを作成。
    • mount_optionsがおかしいのか、これも動かない。普通にvagrant:vagrantのままになっていた。

そして、解決しないままいろいろ試していて気付いたのだが、ホームディレクトリを共有するとなると、~/.ssh/なども共有することになるが、ご存知の通りこの辺パーミッションが厳密でないと動作しない。

なのにsynced_folderではディレクトリ・ファイルのパーミッションを1つ設定するだけで、細かいことはできないし、そもそもホームディレクトリを共有しても問題ばかりで駄目かなと。

あきらめた。

おまけ: 関連して引っかかった細かい問題

  1. Ansibleのmountモジュールのpathパラメータが、今回使ったバージョンのAnsibleではまだnameだった。
  2. Ansibleのsudo: yesがbecome: yesになっていた。
  3. Ansibleのuserモジュールにgidパラメータがなかった。issueは立っているので、今後修正されるかもだが、今はいちいちgidを指定してgroupを作ってから……と二度手間になる。

今後確認すること

  1. ユーザが存在する場合のみsynced_folderを設定する、ということはできないか?
  2. VirtualBoxの共有機能のパーミッション周りにはどれくらい制限があるか。

plenvでバージョン指定して実行できるやつを作った

Perlで書いたWebアプリケーションのデプロイにはCinnamon使っているのだけど、これはPerl 5.14以上が必要。Perl 5.10 でやらなきゃならない案件があって、plenv local 5.10.1とかしているので、Cinnamonが使えない。さあ困ったとなった。

回避策として考えられたのは、

  • PATH="$PLENV_ROOT/versions/5.18.0/bin:$PATH" cinnamon ...みたいに実行する。plenv-execのヘルプに書いてあるやり方。
    • ダーティだし忘れそう。
  • $SHELL -lc 'plenv shell 5.18.0; cinnamon ...'みたいにplenv shellでアレする。
    • 上のよりはわかりやすいけど、ハックっぽいし補完効かないし。

ということで素直に作ることにした。plenv execほぼそのままで、plenv exec-withというのを書いてみた。

github.com

せっかくなのでGitHubにアップしてみた。GitHubリポジトリ作るの初めてだってのは自分でもおどろき。

今後はもうちょっとGitHub活していきたい。いい仕事欲しいしね。

SQL::Translator の罠

今までデータベースのマイグレーション

DBIx::Migration - Seamless DB schema up- and downgrades - metacpan.org

を使っていた。スキーマを変えるためのクエリをそのまま保存すれば migrate できるので非常にお手軽。ではあったものの、変更の数があまり多くなると現在のスキーマを確認するのが面倒臭くなってきたので、別の方法を探していたところ、

papix.hatenablog.com

などを見つけた。が、 Anego も GitDDL も、ちょっと求めているものとは違う感じなので、 SQL::Translator を生で使おうかといろいろ試したのだが、これがまあ酷い品質だった。

本当はもっときっちりまとめたかったが、数が数なんで箇条書きで。なお GitHub で一応開発は続いているようで、このうちの1つ2つは直っているっぽい。ちゃんと確認はしていないが。

  • ファイルの読み込みで encode してくれないので、非 ASCII 文字は化ける。 filename() は使わず自前で読み込んで、 data() に渡せばおけ。
  • SQL::Translator::Schema::Table->options にデータを追加する方法がわかりづらい。 ListAttr という独自の Moo::Role を使っている上、 options を読み込む SQL::Translator::Producer::MySQL 側のコードもわかりづらい。
    • $table->options({ $key => $value }, { ... }, ...)の形か、追加モードなので options() を複数回実効してもいい、模様。
  • SQL::Translator::Parser::DBI::MySQL からスキーマを持って来ると、 AUTO_INCREMENT の初期値まで入るので鬱陶しいが、その初期値を SQL::Translator::Schema::Table->options から削除するのがまたやっかい。
  • DBI->connect の第4引数が固定。つまり mysql_enable_utf8 とか使えない……。 dbh を生で渡せるので、自前で用意して渡す。ただし、 SQL::Translator::Parser::DBI 側のデフォルトの第4引数に追加する形にしないと問題が出うる。
  • ほとんどのメソッドが die せず戻り値が偽であることによってエラーを表現している。ぜんぶチェックするのは大変なので、 new() か translate() あたりにぜんぶパラメータ突っ込んで、まとめて対応するのがよさそう。
  • filters() 周りの挙動が、ドキュメントと実装でかなり異なっている。
  • SQL::Translator::Filter::DefaultExtra がどうも完全に壊れている。十分に検証はできていないが。
  • SQL::Translator::Parser::MySQL でコメント周りのパースがおかしく、コメントの位置によっては落ちる。
  • これは MySQL の仕様的なところもあるが、 BOOL などはデータベースから引いてくると tinyint(1) になるがその辺を吸収してくれない。

どうにもコードが汚くて読むのが本当につらかった。これ Moo ベースなんだけど、せめて Moo なしだったならもうちょっと読みやすかったんじゃないだろうか。

あと、自分の使い方的には INSERT も見て欲しいんだけどそこは無視される。まあ仕方ないけど、どうしたもんだろう。

機能的には便利なので、これベースで簡単なスクリプト書いて DBIx::Migration の代わりにするつもり。

PHPカンファレンス関西2016に行ってきた 前編: トーク感想

先週土曜日、PHPカンファレンス関西2016に行ってきた。PHPカンファレンスは初めて。と いうか、カンファレンスとか勉強会とかに行くこと自体初めて。

前々から興味はあったが、なかなか機会がなかった。今回もだいぶ前から行こうと決めて なかったら行けてなかったと思う。前日もだいぶ気分落ち込んでたし。

行ってみたらとても楽しかったので行ってよかった。まあこの辺の話は後編に譲り、今回 はトークの感想。

タイムテーブルはこちら。

タイムテーブル PHPカンファレンス関西2016

スライド一覧を作ってくれてる方がいる。これは便利。

PHPカンファレンス関西2016 スライドリンク集 #phpkansai - お?意外といけるやん!

10:30-11:15 Composerを速くするために必要だったもの

基調講演。Compoerの通信周りをハックして高速化した話。前からこのプラグインのこと は知っていたが、試そうと思って試せてなかった。今の仕事でComposer使えてないのも あって……。

Compoerの使い方とか、思想とか、そういう基本的なところもきっちり抑えた上、その辺 が最後の伏線になったりしていてトークとしてレベルが高過ぎた。笑いも入ってるし。

物理的距離と糞実装に起因するレイテンシをどうするか、みたいな技術的な話の部分もも ちろん面白かったが、やはり最終部が最高だった。「問題と向き合うこと」大事。

PerlユーザとしてはCPANとかcpanmのこととかいろいろ考えながら聞いていた。cpanmが重 いのは、テストがいちばんのネックな気がするのでそのまま適用はできないだろうけど、 こっちも速くなれば・できればいいなあ。最近Perlもあまり書いてないけど。

スライドにも出てくるPRはこれ。後で試すなりして、いいねつけたい。でも先にプラグイ ンからかな……。

https://github.com/composer/composer/pull/5293

11:30-12:00 PHP開発とクラウド

今回のトークでこれだけはちょっと残念だった。ブース併設の部屋だったので、ちょっと うるさく聞き取りづらかったのがまず。

内容的にもふわふわしていた。よく考えるとタイトルからしてちょっとふわふわ感あった か。

13:00-13:30 ORMユーザー対談 〜Laravel/Doctrine/CakePHP3〜

アスペクト指向によるアプリケーション拡張」と迷ったんだが、昼食後メインホールに さっさと座ってしまったせいでけっきょくそのまま見た。

話自体は十分に面白かったんだが、濃い内容・三人の話者を30分でまとめきれるはずも なく、駆け足になってしまっていたのが残念。

Eloquent (Laravel), Doctorine (Symfony), CakePHP ORMそれぞれの特徴・差異がわ かったのはよかった。特にEloquentは個人的な好みに合いそう。それぞれのコードも今度 ちょっと読んでみたい。

それにしてもやっぱりアスペクト指向~の方見たかった気持ちが残ってしまって。後でス ライドちょっと見ても、やっぱりかなり楽しそうな内容だったっぽいし。

懇親会に参加しなかったことに次いで今回2つ目の後悔。

13:45-14:15 ビューのソースコードコンフリクトから解放される、PHPerのための次世代Webアプリケーション開発への道。

立ち見ならぬ座り見が出るほどの人気。みんな興味ある分野なんだなあ、とか思った。

タイトルにある「コンフリクト」周りを期待していたがちょっと違って、事実上Web Componentsの話だった。面白かったからいいけど。

Web Componentsさっぱりだったが、割と具体的な説明があって、Web Componentsがなんな のか、の基本的なところは理解できた気がする。ちょっと眠くて途中ちゃんと聞けてない ところもあったんだけど……w

フロントエンドはさっぱりだしあまり興味もないけど、今後手を出す必要が出てくるのは 確実だと思うんで、そのときまでにWeb Componentsくらいはちゃんと勉強しておきたい。

14:30-15:00 Laravel と DIコンテナ、コンポーネントの設計

DIとDIコンテナとその他の話。DIとDIコンテナの違い、このトーク聞いて初めて理解し た。というか今までは2つの違いにそもそも特に気を留めていなかった。

なお依存性を外部から突っ込むことの便利さを知りたければ、他人の書いていまいちな コードをテストするのがいいと思う。自分はそれで依存性の扱いに気を使うように なった。

コンストラクタでの注入も、名前ベースで持って来るようなのも、引数でやるのも、プロ パティやグローバル変数(!)でやるようなのも、大体一通り経験あるけど、どれがよくて どれがあまりよくないか、についてはそこまで深く考えたことがなかったが、このトーク を聞いた感じコンストラクタで突っ込めればそれがいちばんかなとか、名前ベースで引く のは便利だけどいろいろデメリットもありそうとか、ちょっと考えた。

あと、Laravelほんとやりたい。仕事でな

趣味でちょっとくらい触っても、やっぱり理解できないと思うんだよね。それに単純にや る気も出ないし。

15:15-15:45 PHPerに知ってほしいDB設計の話

この時間帯は最初にタイムテーブル見たときは特に決めてなかったと思うが、カンファレ ンス直前くらいから酷いDB設計に酷い目に遭わされてたせいで当日は即決。

MySQLのインデックス一つしか使わないとか、EXPLAINとか、基本的な内容なのかと思った ら意外と突っ込んだ話に展開して楽しかった。MySQLの進化とか、PostgreSQLの強さと か、どうせすぐには無理だろうけどいつかは味わいたい。

ちょうどSQLアンチパターン読み始めたところで、その関係ネタもあってよかった。

RDBの知識は長持ちする、みたいなところも考えさせられた。それじゃなくても経験値足 りてないんで、なにか一つくらい得意分野持たないととずっと思っているので。得意分野 にするならセキュリティかなと思ってたけど、RDBも楽しいかも。

16:00-16:45 LT

ここは一部だけ。

PHP7で脱!モッキングフレームワーク

PHPのコア機能で手軽に? モックオブジェクトを作ろうみたいな話。PHP 5でもリフレク ションとかあるけど、PHP 7の匿名クラスとか使うともっと手軽っぽい。いいな。

しかしPHP 5.3から抜け出すのに何年かかるという状況なので、PHP 7なんていつになった ら使えるやら……。

SwiftMailer アップデート

本題とは関係ないけどMailCatcherの話が出てきて、お、っとなった。アレなんか好きな んだよ。

PHPで作成されているOSSのソフトウェアとライセンスについて

これまた本題とは関係ないけど、スライドの長さは考えないと駄目だなー、と。ネタ的な 意味では面白かったが、ちゃんと本題を聞きたかった。

github.ioでブログを公開しよう

PHPみたいな言語は学生さんとかには人気なさそうと思ってたけど、そうでもないんだな と。

いろいろ初めてなのに、なんかライブコーディングみたいなことまで始めちゃってほんと すごい。

でもいちばんすごいのはじっさいにいいコード書いてることだよね。GitHubでちょっと見 てみたけど、普通にかなり書けてる。

こういうの見る度に今いる自分みたいな半端プログラマや、そんな自分以下のプログラマ とか、もう5年もすれば絶滅するんじゃないかと思うけど、じっさいそうでもないんだろ うな。そこ永遠の謎。

ロングポーリング(Comet)の話

興味あるネタなのでもうちょっと詳しく聞きたかった。というか記憶が曖昧だしスライド もないみたいなんであれなんだけど、これも最後までしゃべりきれなかったんだっけ?

Cometとか自分が職業プログラマになる前の話だし、ほんと懐しさ。

まとめ?

全体的に想像以上だった。また行きたい。

どうでもいいけどブログが軽く半年振りだ……。