解せぬ日記

雑な話をする

sudoers.pacnewを適用するぞ on Arch Linux

Arch Linuxはパッケージの更新をするときに、設定ファイルとかをxxx.conf.pacnewのような形で配置する。 例えば、mirrorlistとかsudoersとかってファイルが.pacnewになる。 これは勝手に上書きされないようにするための配慮だと思う。

んで、sudoersを更新するときにやらかしたので、一応メモしておく。

sudoersの更新

sudoのための設定ファイルであり、rootで管理されてて、visudoを使って更新するのが安全なんだけど、.pacnewの適用方法を間違うと悲惨なことになる。

好きなeditorを使ってvisudoを起動し、差分を見ながら更新するのが良さそう。

$ sudo EDITOR=vim visudo

# 差分をとる準備
:diffthis
# 新しいWindowを開く(水平)
:vnew
# .pacnewファイルを開く
:e /etc/sudoers.pacnew
# 差分を見ながら必要なものを取り込む
:diffthis

やらかした方法

mvとかボケて使うと詰む。 所有者はrootなので当たり前。

$ sudo mv /etc/sudoers /etc/sudoers.20141001
# エラーを見て、できるわけがない事に気付き、sudoが使えないので何もできなくなる
$ sudo mv /etc/sudoers.pacnew /etc/sudoers

やらかしたときの復旧方法

USBブートを行って、arch-chrootでファイルを復旧する。

$ mount /dev/sda6 /mnt
$ arch-chroot /mnt
$ mv /etc/sudoers.20141001 /etc/sudoers

まとめ

頭が悪すぎて辛い。

Hubotでこの後めちゃくちゃデプロイした話

背景

僕のチームはGithubを使ってて、HipChatからHubotでHerokuへデプロイさせてる。

Github時代のデプロイ戦略を読んで便利最高と思ったので、僕もプルリクエスト形式のデプロイを本番へ速攻導入した。 何をデプロイするかということが可視化されて、すごいいい。

困ってたこと

プルリクエスト形式のデプロイは便利最高なんだけど、検証環境の分までdeploymentブランチを用意するか悩ましいところだった。 検証環境は作業が同時進行しているため、複数あったほうがよくて、特にHerokuとかを使ってるなら用意しない手はない感じだったりするからだ。

企画への確認はfeatureブランチをそのまま見せたかったりするので、ガンガン検証環境へデプロイしたい。 特にUIの改善だったりってところは出来るだけイメージを共有したいので、早めにレビューするのがいいと思ってて、実装してこの後めちゃくちゃデプロイしたというストーリーが最高だと思う。

そうしたときに、どの検証環境にどのブランチが乗ってるのか分からないので、人間が確認しあう状況に置かれてた。 xxx-edge1ってデプロイしていい?とか会話が発生することになる。 僕は頭悪いので、どこに何がデプロイされてるか全く覚えてられないから、Hubotが覚えてるのがいいと思った。

解決策

terut/hubot-smartdeploy · GitHub というnpmモジュールを作った。

非開発者もGitHub Flowに巻き込んでみんなハッピーになった話 にもあったように、同じブランチは同じ検証環境にデプロイされるのに加え、新しいブランチの場合は以前にデプロイされてから時間がたってる検証環境にデプロイする。 ステータスコマンドで現在の検証環境の状態が確認できる。

f:id:terut:20140820155210g:plain

f:id:terut:20140820155620p:plain

無能なのでcapistranoとかには対応してない。 自分で作ってる社内ツールcapistranoなので、その辺でcapistranoにも対応させたい感じがしてる。

デプロイするといってはいるが、内部はdeploymentsイベントをキックするか、プルリクエストを作って、必要なら自動マージするという実装になっている。 この辺りは atmos/hubot-deploy · GitHub を大いに参考にさせてもらったのだけど、勉強になった。

じゃあ実際、デプロイは誰がやってるんだっていう話だけど、それは atmos/heaven · GitHub のような存在がいて、そいつががんばってる。 hubot-deployとheavenの関係と一緒だ。

雑に作って、チームに導入して、ある程度仕様も固まって来たからテストを書き始めようと思ってるんだけど、jasmine 2.0が最高なんですか? jasmine-nodeが開発鈍いように思えたので、結局mocha + chaiで書き始めようとしてる。 教えてエロい人。

ホワイトデー納品物語

昨日になるけど、世間はホワイトデーだった。 コンビニでフラン買って職場の人にお返しをしたのだけど、そんな雑なことしてんの僕ぐらいだったっぽい。 みんなのやつは僕のやつと袋が違った。

挙げ句の果てにはフランが足りなくなって、窮地に追い込まれた。 僕はお菓子とか作れないし、だいぶ困ったので、とりあえずなんかコード書いて、それをプレゼントすることにした。

女の子はイケメンが好きだろうから、すべてのWebサイトの画像がイケメンになるユーザスクリプトを書いてChromeなりFirefox(Scriptishとかいるけど)に入れられるようにして、コードを納品した。

なんかFacebookとかGoogleとか全部イケメンになって、すごく喜んでた(もしかしたら気を使ってる可能性が多分にある)。 思いの外、喜んでたので、他の同僚とかにもあげたら、Googleで検索したりして遊んでた。

f:id:terut:20140315040017p:plain

エンジニアだとホワイトデーのお返しもコードをプレゼントできて便利〜。

// ==UserScript==
// @name whitedayのお返し
// @namespace
// @description イケメン画像をお返しする
// @include *
// @exclude 
// ==/UserScript==

var imgs = document.getElementsByTagName('img');

for (var i in imgs) {
  var num = Math.floor(Math.random() * 100 + 1);
  var numStr = ("00"+num).slice(-3);
  imgs[i].src = "http://www.example.com/img_".concat(numStr).concat(".jpg");
}

Railsで静的なページを動的にしたくない話

http://terut.github.io/staticman/

staticmanというlayoutやviewを再利用して、静的ページを吐き出すgemを書いた。

Railsで使うことを想定してる。

使い方

設定ファイルをgenerateして、設定ファイルを書き換える。

$ bundle exec rails g staticman:config
  create config/staticman.rb

$ vim config/staticman.rb

設定ファイルは、静的ページのlayoutとviewを設定しておく。

# config/staticman.rb
Staticman.configure do |config|
  config.static_pages = [
    { file: 'statics/about', layout: 'application' },
    { file: 'statics/404', layout: 'application' }
  ]
  # config.static_dir = 'public'
  config.host = 'staticman.github.com'
  # config.controller_context_class = nil
end

あとは設定した静的ページのviewを編集して、準備ができたら出力する。

$ bundle exec rake staticman:build
  create public/about.html
  create public/404.html

Railsでのviewとなんら変わりなく書けるし、テンプレートエンジンもそのまま使える。

仕組み

RailsのApplicationControllerを継承したProxyのControllerとRequestを用意して、あとはRailsレンダリングの機構にまかせてる。

実に単純で、ちょっと泥臭いけど、ActionViewのみでレンダリングしようと思ったらControllerのhelper_methodの仕組みがControllerインスタンスにdelegateしてるので、なかなか辛いことが分かり、こうなってる。

もし、viewの中でメソッドが見つからない場合は、ActionView::Baseを継承した無名クラスにmethod_missingを持ったモジュールをincludeしてあるので、メソッド見つからなかったよってWarningだして、nilを返してレンダリングを続ける。

あくまで開発時にのみ使うツールかなと思ったので、本体のクラスに影響がないようにしたつもり。

継承せずに特異メソッドを使ってもよいのかもしれないけど、とりあえずこうした。

問題点

現状、2つプロジェクトに導入してみて、一応うまく動いてる。

けど、以下の点がめんどくさいなと思った。

  • Rails.envをproductionで吐きたい(むしろassetsのdigest考えるとそっちのほうが多い気がする)場合、別途envを用意しなきゃいけなくね?
  • URL helperの*_urlを解決するためにhostを設定として用意するのが微妙にDRYじゃない

このブログを見て、ナルホディウスですぞと思ったそこのあなた、Pull Requestお待ちしてます。

静的ページの管理の問題

以前から、Railsとかにおける静的なページ、いわゆるsorry.htmlだとか、404.htmlとかをどうやって管理したらいいんだぜ?と思ってた。

まず最初に思いつくのが、ユー動的にしちゃいなよということ。

high_voltageとかはRailsにマウントするタイプなので、動的にページをレンダリングしてるように見えて、Railsに組み込む方針をとってるっぽい。

動的な要素(例えばセッション状態を見てログインユーザを表示したいとか)がある場合、layoutやviewを使い回せて、とても有益。

ただ現状関わっているいくつかのプロジェクトに関して、そんな要件はないので、静的なページは個人的にRailsのレイヤより前のWebサーバからresponseを返したいなと思った。

んで、動的に作らない場合、問題になってくるのが修正漏れ(少なくとも僕の職場では何回かあった)で、静的なページを配信する残念リリースをする。

静的なページで同じようなマークアップがすべてのファイルにあったりして、テストとかも書いてないので、目grep力たった5か、ゴミめという僕にとって気づくのは難しい。

ということで、動的に静的なページを生成すればlayoutとviewを使い回せて幸せになれるんやで工藤!というところに行き着いた。

それがhigh_voltageで出来るならそっちを使ったほうがいいし、別にもっとよいライブラリがあればそれを使いましょう。

ついでに気が向いたら@terutにリプライで教えてください。

思ったこと

実際にRailsがどうやってレンダリングしてんだろーなと思って色々と潜ってみたけど、勉強になった反面、僕には才能なんてなかった。

もっといい方法があれば、ぜひ教えてほしいし、この方法が良さそうなら、どんどんよくしてもっと楽したい。

自分のライブラリに自分でissueを書くのはとても趣があり、いいんだけど、僕の英語がクソすぎて何言ってんのか分からなくなった。

最後にstaticmanというのはstaticおじさんということであり、静的なページを書き続けてくれるおじさんの意である。

使い方はREADMEに一通り書いておいたつもりなので、興味あれば読むといいと思う。

Capybaraが実行対象にしてるHTMLをコンソールに表示する

みんなー、Capybaraおじさんだよー。

嘘です、すいません。

TDDがデファクトになっている昨今、こんな告白をするのは非常に勇気がいることなのだけど、僕はCapybaraをまともに書いたことがなかった。

PHPの保守おじさんだったり、Objective-Cおじさんだったりをやっていて、時間ある時はRubyでツールを書いたりしてたのでRSpecのみだった。

んで、Capybaraおじさんになる機会が巡ってきたので、書いてたのだけど、エラーが非常に分かりにくかったりした。

実行対象になってるHTMLは puts page.body とかで見れるし、実行したHTMLを吐いておいて失敗したらブラウザで対象のHTMLを起動したりするGemなんかもあったんだけど、もうちょっと軽く見たい欲があった。

Capybaraをガンガン書いてる同僚に聞いても知らないというし、find とかで Capybara::Element を取り出して、対象のInner HTMLを眺められたりしないかなーとか思ってちょっと書いてみた。

find('div.foo1'){|x| puts x }
=> <div class="bar">
     <p>unkode<p>
   <div>

そして native には Nokogiri のオブジェクトが来ないことがあって、これじゃダメなケースがあることが分かり、ウヘヘとなってるのが今。

どうやら js: true の場合に Driver が変わる?のか native へは Nokogiri のオブジェクトが来ないように見えるんだけど、正しく把握するためにもソースを追ってみたい。

またクソみたいなコードをインターネット上に吐き出したワケだけど、ただまあ大体の場合には使える感じなので、とりあえずよしとして、また後で考えようと思う。

Capybaraをガシガシ書いてる人はHTML吐き出して確認してるのかしら?

それとも慣れてるから、hamlなり、erbなりのコード見りゃ余裕で書けるってことなのかな?

追記(2013/04/19)

とのこと。

CapybaraのREADMEにも書いてあるDebuggingの項目でやるのがなんだかんだでいいのかもしれない。

スクリーンショット(save_screenshot)だったりHTMLを吐き出す(save_and_open_page)だったり、pryだったり。

カジュアルな画像のアップロードの話

僕は思い出した。

そういえば以前、画像のアップロードの話をして、ブログ書いてなかった。

去年の10月頃の話なので、もうちょっと変わってるかも。

本当に基本的なことだけど、僕は正直知らなかったことだったので、誰かの役に立てばうれしいなと思う。

間違ってることあったら、教えろください。

Developers Summit 2013に行ってきた(2日目)

2日目も参加してきたので、まとめとく。

AmazonのDevOpsを支えるAWSクラウド

Amazon.comでは11秒に1回デプロイしてて、1時間で1079回もデプロイしたことがあるらしい。 そんな回数になるとほとんどのことが自動化されてるんだろうけど、UIの崩れとかはどうやって検知してんだろか。

リソースを調達するのに待ち時間が発生するのはナンセンスだと言ってたけど、確かにそれはそうかもと思う。

Webが生み出し始めた世界

インターネットの物理モデルとかを科学技術館がどっかに作った人の話だった。 色々と宣伝してたけど、ニコニコ学会は超面白そうだなーと思った。

最後のほうの話はちょっと抽象度が高すぎて咀嚼しきれてない。 Webとかインターネットとかではなく、デバイスの話になってたような気もするし、これからは音声に回帰していくんではないかとのこと?(ちょっと自信ない)だった。 他の方のブログみて僕も勉強したい。

単に僕の頭が悪いってことだと思う。

モバイルファースト再考

モバイルファーストをもう一度考えましょうとのこと。 スマートフォンでしかサービスをやらないとかそういうことがモバイルファーストなのではなく、モバイル端末を起点としたサービス戦略や理論がモバイルファーストであると。

モバイルでしかできないことや、モバイルの特性を活かすのが前提で、日々の生活で人々がどんな行動をとっているのかをよく観察することが大事だと言ってた。

端末を色々触らんと理解できないことも多いと思うし、Nexus7買ってよかった。 iOSとAndroidではやっぱ色々と感覚が違うことも多い。

モバイルを使い倒していきましょうとのこと。

SQLアンチパターン

例の本の話。

よさそうな本だった。 あくまでアンチパターンだけでなく解決方法や、アンチパターンを使ってもよい例外的な条件なども載ってるらしい。

これは買いな気がする。

ワンクリックデプロイ

単純にワンクリックデプロイといっても、そこまでにやることは大量にある。 ほとんどすべてのことを自動化していかないと無理。

データベースへの大きな変更が入る(切り戻しができなくなる)場合は、切り戻しできるような工夫、例えば削除するカラムは残しておいて、しばらく運用してから削除するとかが必要そう。 自分に当てはめてみると見た目の部分のテストをどんだけ自動化していくかが課題のような。

アジャイルサムライ

どの現場でも試行錯誤で自分たちなりに色々試してるんだなと言う感じ。

新しいことを始める場合は、まず始めちゃおうということ。 始めて、成果をだして、困ったことがあったらアウトプットとして出して学び合おうよということだった。

一緒に始める人いなかったから一人でペアプロしたと言ってたけど、そのぐらい頭おかしくいきたいですね。

同僚の人とあったんだけど、改善したいと鼻息荒く言ってたのがうれしかった。

とまあ2日目のまとめはこんな感じ。