うなすけとあれこれ

2018年07月16日

#railsdm と #kosenconf と #kosendj だった3連休

kosenconf in tokyo 2018

イベント3連続

2018年の7月14日はRails Developers Meetup 2018 Day 3 Extreme、 15日は高専カンファレンス in 東京 2018、 16日は高専DJ部 #19、 という非常に詰め込まれた3連休でした。

それぞれでブログを書くほどの気力がもうないので、この1本にまとめて書きます。

Rails Developers Meetup 2018 Day 3 Extreme

発表資料です。

Railsdm 2018 day 3 extreme - unasuke - Rabbit Slide Show

「Railsのissueを毎日読む方法」という題で登壇させて頂きました。

実際のところ、pixivFANBOXでのwatchは結構継続できており、ありがたいことに支援者も6名ほどおられます。

うなすけ[pixivFANBOX]

スライド内のコードの一片もなく、技術というよりは心構えに関する発表でした。その割には良いと言ってくださる方がいらっしゃったのはとても嬉しかったです。

うなすけ pic.twitter.com/hL0Rw6I4QA

— ゆーけー / Yuki AKAMATSU (@ukstudio) 2018年7月14日

#railsdm うなすけさんのAMAへのセルフ質問、最高によかったですね

— tatsuosakurai 🍺🤖 (@tatsuoSakurai) 2018年7月16日

ちなみに、Rubyはwatchしていません。mruby/mrubyはwatchしています。理由はRubyの開発の主戦場がGitHubではないからです。

高専カンファレンス in 東京 2018

発表資料です。

kosenconf in tokyo 2018 - unasuke - Rabbit Slide Show

高専カンファコミュニティと僕の関わりについて、もしくは他のコミュニティとの関わりについて僕の心構えとこれまでについて発表させて頂きました。 また、当日スタッフのような感じで、第1会場の録画を担当しました。

railsdmでもそうですが、最近はよく僕の顔写真がインターネットに出回っているので、現実空間でお会いした方に認知されていただいているので有難いです。

うなすけはこんないい話しないよ、これはうなすけのニセモノだよ

— ごさいようじょ (@tochikuji) 2018年7月15日

AMAブース開きました! #kosenconf pic.twitter.com/N66MXOizfF

— あそなす (@asonas) 2018年7月15日

うなすけさん、実在していた! #kosenconf

— 湊川あい🌱マンガでわかるUnity Web連載中 (@llminatoll) 2018年7月15日

高専DJ部 #19

これはもともとasonasさんが運営の主体だったのですが、高専カンファ in 東京 2018の運営で忙しいということもあり、前回くらいから運営のお手伝いをしています。 あと、今回はDJはしていません。

前日のカンファでも、イベントのさ中でも新規入部希望者がいらっしゃったのはとても嬉しいです。

#kosendj pic.twitter.com/8tty1mueDp

— dachiba (@dachiba) 2018年7月16日

3日間の感想

ギュッとなっていて、楽しかったですが、体力の衰えも感じました。今後もやっていきましょう。

2018年07月16日
2018年06月11日

The world of mail.gem (maybe) not you know

I am contributor of the mail.gem

RubyKaigi 2018のLTにCFPを提出しましたが、残念ながらnot acceptedとなってしまいました。

なので、その内容を先日開催された表参道.rbで発表してきたのですが、LTにする過程で端折った様々を補完するために記事にまとめました。

発表資料自体はここにあります。

https://github.com/unasuke/omotesandorb-35

mail.gemとは

mail.gemはRubyでemailを扱うためのgemであり、actionmailerの依存関係にも含まれるように、世界中で使用されているgemです。

mail | RubyGems.org | your community gem host

RailsのCI

rails/railsのCIでは、以下に示すように警告が有効になっています。

https://github.com/rails/rails/blob/fcfe29cd2641b2ce3c01bc13f39d617ec302fc8d/actionmailer/Rakefile#L11-L17

# Run the unit tests
Rake::TestTask.new { |t|
  t.libs << "test"
  t.pattern = "test/**/*_test.rb"
  t.warning = true
  t.verbose = true
  t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
}

さて、ruby-head、つまりRuby 2.6以降では、以下のようなcase-whenに対して警告が出るようになっていました。(余談を参照)

case cond
  when 1
    do_something
  when 2
    do_something_another
end

そして、Railsはruby-headでもCIを実行しています。そのなかで依存しているgemのコードに、whenが1段深いインデントをしているものが含まれていたので、CIで大量のwarning messageが出るようになってしまいました。

https://travis-ci.org/rails/rails/jobs/365773392

依存しているgemのうち、簡単に直せるものについては次のようなpull reqによって修正されています。

Address `warning: mismatched indentations at ‘when’ with ‘case’` by yahonda · Pull Request #74 · rails/rails-dom-testing

しかしmail.gemについては、そのgem単体で発生しているwarningが多く、修正の手間が大きいのではないかという懸念がありました。

そのようなことを @koicさんや@yahondaさんが #asakusarb にて話されており、偶然その近くにいた僕が興味を持ってやってみようということになりました。

よくわからない、自動生成されたコード

まずは、警告が出ているコードを見てみます。中には確かにインデントの揃っていないcase-whenがありましたが、それよりも僕は次のコードに疑問を抱きました。

https://github.com/mikel/mail/blob/fbc5d91ae9b68b3c4ad450a22055a74dfce1caf9/lib/mail/parsers/addresslistsparser.rb#L33166-L33173

    when 36 then
        begin
 local_dot_atom_pre_comment_e = p-1         end
        begin
 local_dot_atom_e = p-1         end
        begin
 address.local = '"' + qstr + '"' if address        end
        begin

Ruby では、次のような後置ifがある場合に、その条件が偽であれば前置されている式は実行されないという文法があります。

puts 'message' if false  # この場合 'message' は出力されない

このときにifにendが続いてblockになっている場合、後置ifのような動きをするのか、それとも前置の式が評価されてからif blockの中に入るのか僕は即座にはわかりませんでした。

そこでその場にいらしていた @amatsuda さんに伺ってみたところ、そもそもそのコードは何らかのツールにより生成されたもののように見える、というアドバイスを頂きました。

自動生成されたコードであるならば、その成果物に対してあれこれ修正するのは再度生成した場合に全て上書きされるので、無意味となります。生成元に対して何らかの対処をしなければなりません。

Ragel

それでは、mail.gemのRubyコードは一体何によって生成されているのでしょうか。

コードの生成といえば、何らかのスクリプト、あるいはタスクランナーによって生成されることが多いでしょう。例えば一般的にはMakeがその役目を担うでしょうし、RubyのプロジェクトであればRakeも使われます。

というわけでRakefileの中を見てみると、どうやら ragel というコマンドを呼び出して、 .rl から .rb を生成しているようです。 https://github.com/mikel/mail/blob/fbc5d91ae9b68b3c4ad450a22055a74dfce1caf9/tasks/ragel.rake#L12-L21

  # Ruby parsers depend on Ragel parser definitions
  # (remove -L to include line numbers for debugging)
  rule %r|_parser\.rb\z| => '.rl' do |t|
    sh "ragel -s -R -L -F1 -o #{t.name} #{t.source}"
  end

  # Dot files for Ragel parsers
  rule %r|_parser\.dot\z| => '.rl' do |t|
    sh "ragel -s -V -o #{t.name} #{t.source}"
  end

ragelというキーワードでGoogle検索してみると、次のようなるびまの記事が見付かりました。

Ragel 入門: 簡単な使い方から JSON パーサまで

記事によると、Ragelはステートマシンコンパイラのようです。emailのデータをパースするのに使われていそうだ、というところまでわかりました。公式サイトは以下です。

http://www.colm.net/open-source/ragel/

ひとまずRagelをcloneして、内部を眺めてみることにします。

Ragelをどうにかする

公式にもあるとおり、以下のようにしてRagelをcloneしました。

$ git clone git://colm.net/ragel.git

さてここからどうすればいいのかがわかりませんでした。READMEはありますが非常に簡素なもので、コンパイル方法がわかりません。僕は普段はRubyで開発しているので、C言語で記述されているプロダクトのビルドの作法に疎いのです。

しかしREADMEには Colm is a mandatory dependency. という記述があり、とりあえずそれが必要であることはわかりました。

なんもわからんhttps://t.co/8o5oaN7zfZ

— うなすけ (@yu_suke1994) 2018年4月12日

Colm

先程RagelをcloneしたURLにも含まれるように、Colmが同じドメイン下で公開されていました。

http://www.colm.net/open-source/colm/

公式サイトの記述に

Colm is a programming language designed for the analysis and transformation of computer languages.

とあるように、これはプログラミング言語のひとつのようです。

mail.gemを直すのに、新しくプログラミング言語を習得し、初めて使うツールの学習もしなけれならないとなると相当時間がかかる上に難易度も高いので、別の方法が無いか考えることにしました。

要はgofmtがあればよい

自動生成されたコードのスタイルがめちゃめちゃであれば、それを自動整形してくれる、gofmtのようなものがあれば解決します。

そのようなRubyの自動整形ツールとしては、有名なものであればRuboCopが挙げられるでしょう。RuboCopは -a をオプションとして渡すことで、対応しているCopについては自動で整形してくれます。

しかしRuboCopはあくまでも静的解析ツールであり、自動整形ツールではありません。自動整形の機能についても、誤動作が無いというわけではありません。

ruby-formatter/rufo

用途に合致するものがないか調べていたところ、以下のgemが見付かりました。

https://github.com/ruby-formatter/rufo

rufoはRipperという、Rubyに同梱されているRubyの構文解析器を使用してコードの整形を行ないます。なのでその整形結果に関してはある程度の信頼性があると判断してよいと考え、これを使って整形することにしました。

動かないRakefile

rufoによる自動整形を、Ragelによるコード生成の後に実行すればよいので、そのようにRakefileを書き変えると、エラーによりコード生成ができませんでした。そこでrufoを呼び出している部分を消し、変更が無い状態でもういちどrakeを実行してみましたが、同様にエラーで生成ができません。

ある時点からRakeの挙動が変わってしまい、既存のRakefileのままではコード生成ができなくなってしまっているようです。Ragelによるコード生成はそこまで頻繁に実行されるものではない(前回は2017年11月)ので、mail.gemのメンテナはこの問題に直面してないようです。

mail.gemのgemspecに記述されているrakeと、その時点でローカルで使用されているrakeの間に入ったコードのどこから挙動が変わったのかを調べる必要があります。そのきっかけとなるcommitを見付けられれば、対処法もわかるはずです。

調査したところ、v12.0.0 では成功し、 v12.1.0 では失敗することがわかりました。

https://github.com/ruby/rake/compare/v12.0.0…v12.1.0

さらに調査を進め、次のpull reqがmergeされたことにより、挙動が変わってしまったことが判明しました。

Chained extensions by pjump · Pull Request #39 · ruby/rake

これによって対象となるrlのファイル名の解決に失敗するようになったので、以下のpathmapのドキュメントを参考にして、次のpull reqを作成しました。

Set full path of the ragel source file to rake task by unasuke · Pull Request #1221 · mikel/mail

また、結果としてrake taskが正常に実行できるようになったので、前述のpull reqに依存する形で以下のpull reqを作成しました。

Reduce warnings “mismatched indentations” on ruby 2.6 by unasuke · Pull Request #1222 · mikel/mail

merge

なんとありがたいことに、それほど時間を置かずどちらのpull reqもmergeしてもらうことができました。よかったですね。

やった!!!!!! #asakusarbhttps://t.co/5tHqN7VWuS

— うなすけ (@yu_suke1994) 2018年4月13日

余談

case-whenでインデントが以下のようになっていないと警告が出る件についてですが、おそらく以下のcommitで有効になったようです。

ところがそれに対し、次のような報告が上げられています。

Bug #14674: New mismatched indentations warnings? - Ruby trunk - Ruby Issue Tracking System

I strongly believe that it is not Ruby’s parser job to warn us about styling, especially if there’s no strong reason to suspect that it’s a programmer error.

case-whenで1段深くインデントするのはよくあることだし、そのようなstyleのcheckはRubyのperserのやることではない、という反対意見ですね。

その報告によって次のようなcommitが為されており、結局のところcase-whenではwhenが1段深くインデントされていても警告は出ないようになっています。

$ ruby -v
ruby 2.6.0dev (2018-06-10 trunk 63625) [x86_64-linux]

$ cat test.rb
case true
  when true
    p 'true'
  when false
    p 'false'
end

$ ruby -w test.rb
"true"

よかったですね。

2018年06月11日
2018年06月06日

RubyKaigi 2018にhelperとして参加しました

RubyKaigi 2018 Matz's keynote

ここのところ毎年参加しているRubyKaigiですが、今回はhelperとして参加してきました。

RubyKaigi 2018では当日の運営のお手伝いをしてくださる方を募集しています! https://t.co/869qrPEr7Q #rubykaigi

— RubyKaigi (@rubykaigi) 2018年4月12日

helperとしての参加表明にも記入したのですが、当日はネットワーク班の一員として、参加者の皆様が会期中に快適にインターネットを使用することができるようがんばりました。

ネットワーク班の主な仕事内容

作業内容については、昨年のsorahの記事に詳しいのでそちらを参照するほうがよいでしょう。大体同じです。

RubyKaigi 2017 で Wi-Fi を吹いてきた #rubykaigi - diary.sorah

前日と最終日に関しては、多少は体力勝負な部分があることは否定できません。会場内を歩きまわって、ケーブルを回収したり機器を運搬するのは、結構大変です。汗だくになりました。

感想

ネットワーク班で共有されていた、APへの接続数、インターネットへのトラフィック量などのダッシュボードを見ていると、人の動きが可視化されて、見ていてとても楽しかったです。

こういうイベントのスタッフとしての参加は、普段参加しているとわからないイベントの裏側で、何が起こっているのかがわかり、そしてそのイベント自体を自分達で支えているんだという実感が得られ、何とも言えない高揚感がありました。来年もネットワーク班の募集があれば、是非力になりたいと思いますが、どうなるでしょうね。あわよくばCFPが採択されることを願っていますが……

よくない点があるとすれば、helper参加する場合はシェアハウスでの共同宿泊はやめたほうがいいかな、と感じました。スタッフは集合時間が朝早く、みんなと起床・出発する時刻がずれるためです。次回もやんちゃハウスがあるとしても、おそらく僕はそっちには参加しないでしょう。

余談

以前bugs.ruby-lang.orgに登録して停滞(?)していた、僕が投げたpatchについてコミッターであるnaruseさんに直接現状を聞いてみたところ、翌日にはmergeされていました。

Feature #14688: Net::HTTPResponse#value raises “Net::HTTPServerException” in 4xx response - Ruby trunk - Ruby Issue Tracking System

このまま何事もなければ2.6.0では僕の書いたコードが動くということになり感無量です。

RubyKaigiでは、Rubyのコミッターに直接合うことができるという非常に稀有なイベントであると思います(しかも目立つTシャツを着ている)。

これからも、やっていきです。

2018年06月06日
2018年05月24日

pixiv FANBOXを始めました

fanbox

pixiv FANBOX

なんかこう、あわよくば毎月僕にお金をくれる方がいたらな〜ということでやってみたかったのですが、 コンテンツを全く投稿しないというのもなんだか寂しいので、会社の日報に毎日書いているRailsとMastodonのactivityに 無責任にコメントしていくというのを投稿しておひねりを頂くことにしました。

うなすけ[pixivFANBOX]

ヤギヌマ新聞との違いは、こっちではissueやcloseされたpull requestも取り上げることです。

note.muでも同様のコンテンツを投稿しようと思ったのですが、note.muでは継続課金コンテンツは要審査かつ有料ということだったので、 今のところpixiv FANBOX限定になってます。

というわけで、よろしくお願いします。

うなすけ[pixivFANBOX]

2018年05月24日
2018年04月29日

高専DJ部 #18 でした

kosendj-bu #18

茶箱のエスプレッソマシーンが新しくなっていたので注文してみたラテです。美味しかったです。

セトリ

  1. Teardrops (Miroslav Vrlik Remix) - Shion Hinano
  2. Chocolate brownie - 新乃ユキヒデ
  3. ぼくのフレンド Progressive House Remix - PeTA
  4. Profiterole feat.砂糖子 - 中路もとめ
  5. Wanderer (Original Mix) - myni8hte
  6. Dreamland - Ujico*
  7. Hope (Mix 2) - CRYDITS, myni8hte
  8. Radio Happy -Progressive House Remix- - PeTA
  9. Summer Dawn (Original Mix) - Napo (JPN)

今までの僕の傾向だったEDM系からProgressive Houseに変えたので、死んだのでは説が流れました。生きてます。

R.I.P. チャラすけくん。
新たな生命おめでとう、エモすけくん。 #kosendj pic.twitter.com/hETYlT4YDS

— HolyGrail (@HolyGrail) 2018年4月21日

え、なにうなすけくん死んだの…. #kosendj

— あそなす (@asonas) 2018年4月21日
2018年04月29日
2018年04月16日

SlackのThreadは邪悪かどうか

slackのthreadがどこかわからなかった場合

SlackのThreadは便利

Slack、便利ですよね。見ない日はありません。

2017年にSlackに導入されたThread機能は、1つの話題に関する発言をまとめることができ、それが無かったころに比べて意見のふりかえりがとても容易になりました。

しかし、最近はそうでもないのかな、と思いはじめています。

Slackのthread、邪悪な気がしてきた

— うなすけ (@yu_suke1994) 2018年4月11日

理由その1 中でどのような会話がされているのかわからない

ほぼこれに尽きます。

SlackのThreadは、それが存在することを見逃しやすいです。また内部でどのような会話がされているかを知るには、そのスレッド内で発言していないと(通知が来る状態になっていないと)わかりません。

あるThreadにどれだけ有用な情報が投稿されていようと、知っていたなら数秒で答えられるような問題に対して何十分も議論が続けられていようと、それが自分の気づいてないThreadでの会話であれば為す術がありません。

これは、情報共有おじさん - ローファイ日記 のjune29さんによるはてブコメントの

「自分に届かなかった情報を、そういう情報があるだろうと想像して、あらためて取得しにいくコスト」は「届いた情報を無視するコスト」に比べて圧倒的に高いので、基本は届けておいて、各自が適宜で無視、が好き。

http://b.hatena.ne.jp/entry/189105486/comment/june29

に僕の言いたいことが全てまとめられています。

辛うじて、”Also send to #channel" というチェックを入れれば、属するchannelにもう同時に投稿することはできます。しかし、これを常時ONにするというのはThreadの思想に反するので厳しいでしょう。

SlackのThread、知らん間に話伸びてるのに気づかないことが多いからやっぱり好きじゃないな

— ゆーけー / Yuki AKAMATSU (@ukstudio) 2018年4月16日

理由その2 テキストによるコミニュケーションしかできない

SlackのThreadでは、画像やtext snippetの投稿ができません。たとえば障害対応でThreadでの会話が始まってしまったとき、アクセスログやスクリーンショットはThreadには投稿できないので、やっぱりchannelに戻って投稿するしかありません。

僕がどうしているか

こまめに Also send to #channel する

ここにThreadがありますよ、ということをわかってもらうために、Thread内でもchannel全体に発信したほうがよい投稿に関しては"Also send to #channel"のチェックを入れて投稿しています。

むしろ一時的なchannelを作る

いずれ障害や問題は解決するので、その時点でそのチャンネルはアーカイブして社内 Wiki に簡単な概要を作成する。概要には当然チャットログへのリンクを貼っておく。

最近ユビレジではじめた Slack チャンネルの新しい運用 - Diary

始めからある程度の投稿がされることがわかっている議題に関しては、最近僕は積極的にこの運用をしていくことにしています。(例として障害対応などのインフラオペレーションログ)

まとめ

とはいえThreadは便利なので、これからも確実に使われていくでしょう。Threadを使う人が、このThreadの存在に気づいていない人がいる ということに気を配ることができれば、不幸な情報の取り零しも僅かなものになっていくと思います。

2018年04月16日
2018年03月29日

高専DJ部 #17 でした

kosendj-bu #17

まあ1ヶ月以上経っているんですが。

セトリ

今回は意図してチャラめにいきました。途中でシャンパンが出てきたときに咄嗟にChampagne Showersを流したのが僕の中でのピークです。

  1. Down Dirty (Extended Mix) - Rivero
  2. Shots - LMFAO Feat. Lil Jon
  3. #SELFIE (Club Mix) - The Chainsmokers
  4. Children (Extended Mix) - Vigel
  5. Whatcha Need (Extended Mix) - W&W
  6. Radical (Original Mix) - Dyro, Dannic
  7. Internet Friends - KNIFE PARTY
  8. Saiko - Aero Chord
  9. RIOT (Extended Mix) - Seth Hills
  10. Rage (Extended Mix) - Arston
  11. With You feat. Emelie Cyreus (Progressive Extended Mix) - Magnificence, Venomenal, Emelie Cyreus
  12. Champagne Showers - LMFAO Feat. Natalia Kills
  13. Glow feat. Nikon (Original Mix) - Nikon, Paris & Simo

. @yu_suke1994 with party peoples #kosendj pic.twitter.com/XHhuckHEnk

— あそなす (@asonas) 2018年2月17日
2018年03月29日
2018年02月04日

落ちていたitamaeのintegration specを直しました

itamae readme

master build failed

itamaeの名前を久々に聞いたのは、昨年11月に行なわれた福岡Ruby会議02でのことでした。前夜祭でのまなてぃさんの発表でitamaeを使っているとの話を聞き、また、懇親会でまなてぃさんがPullRequsetを出したがテストが通らずmergeもしてもらえないという話を聞き、それからずっとitamaeのことがどこか頭の片隅にありました。

その後、転職記事でも触れましたが、業務でpuppetを置き替えることになったときに、ここはitamaeを使ってみようと考えました。そこでitamae-kitchen/itamaeを見に行くと、そもそもmaster branchのでのCIが(2017年3月から)failedになっていることに気づきました。

cookpadでの採用実績や、gihyoでの解説記事、バージョンも1.9を迎えるなどそれなりに成熟しているOSSと言って差し支えないでしょうが、masterのCIが失敗しているプロダクトにあまりいい印象はないでしょう。そこで、業務でitamae recipeを書きつつ、その合間と個人的な時間でitamaeのCIを直すことに挑戦しました。

fix CI

まずは手元で実行できるように

さて、では作業にとりかかろうとforkし、cloneしてbundle installを実行しましたが、まずこれが失敗します。原因としては、net-ssh gemが、itamaeが依存しているspecinfraで要求しているバージョンとvagrantが要求しているバージョンとで衝突しているせいでした。

itamaeが要求しているvagrantですが、ryot_a_raiさんがforkしたものであり、またその意図もよくわからなかったので、gem update vagrantをしてしまえと思いました。

なるほど。そもそもなんでforkしていたか忘れてしまった

— Ryota Arai (@ryot_a_rai) 2017年12月7日

しかしvagrantはある時点からrubygemでの配布をやめ、公式サイトからパッケージをインストールする方式になっていたので、そもそもvagrantへの依存自体を削除することにしました。

test-unitで落ちるspec

さて、落ちるspecを見てみます。

https://app.wercker.com/buildstep/58bf89e2ae336e01005e1487

ERROR :         Command `gem install -v 3.2.0 test-unit` failed. (exit status: 1)
ERROR :   gem_package[test-unit] Failed.

というわけで、test-unit gemのあたりでなにやら失敗しているようです。このrecipeを見ると、以下のようになっています。

gem_package 'test-unit' do
  version '3.2.0'
end

何の変哲もないgem_packageですが、何故失敗するのでしょうか。

test-unit gemは、power_assert gemに依存しています。power_assert gemの内部で、%i を使用しているコードがあるのですが、integration specで使用しているubuntu trustyのRubyが1.9.3でまだこのリテラルに対応していないために、power_assert gemのインストール(RDocの生成)に失敗してしまいます。

https://github.com/k-tsj/power_assert/blob/180b0c0fe619f4619d91e25b1d09b30f3df2f14c/lib/power_assert/parser.rb#L61

itamaeのintegration specでは、trustyにbuilt inのRuby(1.9.3)を使うんだけど、Ruby 1.9.3には %i がまだ実装されてないからpower_assert gem v1.1.1のinstallで落ちるんだ……

— うなすけ (@yu_suke1994) 2017年12月10日

まあそれはそうなんですがEOLなRubyのためにアレコレするのはちょっとどうかなーと思っているので、普通にRuby 2.2以上を入れたい気持ちです。

— うなすけ (@yu_suke1994) 2017年12月10日

なので、ubuntuをtrusty(14.04 LTS)ではなくxenial(16.04 LTS)にアップグレードしてしまいました。

パッケージがインストールできなくなる

ある程度覚悟していましたが、ubuntuをアップグレードした結果、バージョンを指定していたパッケージのインストールに失敗するようになってしまいました。 これは、単純にバージョンを有効なものに変更するだけで済みます。これでslのバージョンが上がり(?)ました。

 package 'sl' do
-  version '3.03-17'
+  version '3.03-17build1'
 end

rcスクリプトを参照するrecipeが存在する

とりあえず、以下のrepiceを見てください。

service "nginx" do
  action [:enable, :start]
end

execute "test -f /etc/rc3.d/S20nginx" # test
execute "test $(ps h -C nginx | wc -l) -gt 0" # test

service "nginx" do
  action [:disable, :stop]
end

execute "test ! -f /etc/rc3.d/S20nginx" # test
execute "test $(ps h -C nginx | wc -l) -eq 0" # test

https://github.com/itamae-kitchen/itamae/blob/2c57ecc2f085643a47a7d509040685dbecde8bc7/spec/integration/recipes/default.rb#L246

見てわかるように、rcスクリプトを参照しているrecipeがあります。しかし、ubuntu xenialにアップグレードしたことによって、initがUpstartからsystemdへと変化しました。その結果、rcスクリプトは利用できなくなってしまい、このrecipeは適用できません。(この辺ちゃんとした理解ができてないです)

ただ、rcスクリプトを使用したコマンドの内容自体は、続く行で実行している ps にて担保できているとみなせます。なので、rcスクリプトを使用しているrecipeを削除することで対応しました。

複数回実行したときに落ちる場所が変わるspec

新規に起動したVMに対してspecを実行する場合と、それが失敗して、もう一度そのVMに対してspecを実行する場合とで、落ちるspecが異なることに気付きました。

原因調査のためにvagrant sshなどでVMに入り調べたところ、以下のspecでその問題が発生していました。

execute "mkdir /tmp/link-force-no-dereference1"
link "link-force-no-dereference" do
  cwd "/tmp"
  to "link-force-no-dereference1"
  force true
end

execute "mkdir /tmp/link-force-no-dereference2"
link "link-force-no-dereference" do
  cwd "/tmp"
  to "link-force-no-dereference2"
  force true
end

このmkdirを実行している部分です。mkdirは、既に存在しているディレクトリを対象にして実行するとエラーを返します。一度目の実行で作成されたディレクトリが残ったまま、もう一度recipeを適用すると、作成対象のディレクトリは既に存在しているためにエラーになってしまいます。

なので、このexecuteに対してnot_if制約を追加することにより、エラーが発生しないようにしました。

これについては、一度作成したVMに対して複数回specを流す場合に発生する問題で、CI上では都度インスタンスを作成するために問題になりません。 また、mkdir-pを追加することでも回避できるでしょう。

mkdir -p でうまくいったりしないの #wakate2018w

— why/橘和板 (@whywaita) 2018年2月3日

解消できなかったsticky bit問題

とあるrecipeの実行で、net-scp gemが例外を吐いて落ちる、という問題が発生しました。

file '/tmp/file_edit_with_suid' do
  action :edit
  owner 'itamae2'
  group 'itamae2'
  mode '4755'
end

これについては、エラーの内容、backtraceが深いこと、recipeの実行そのものには成功していることなどから、深追いするのは諦めました。実力不足とも言えます。

なぜか以下のような変更をすることによって回避できるので、workaroundである旨をcommit message書いておきました。

 file '/tmp/file_edit_with_suid' do
-  action :edit
   owner 'itamae2'
   group 'itamae2'
   mode '4755'
end

Rakeが複数インストールされている

実はこれまでに挙げた問題というのは、specを実行する前段階であるrecipeの適用段階で発生していた問題でした。integration specでは、まずVMに対してitamae repiceを適用してから、そのrepcipeが正しく適用されているかの確認のためにserverspecを実行しています。

という訳で、やっとserverspecが落ちているところまで辿りつきました。次のようなspecです。

describe command('gem list') do
  its(:stdout) { should include('rake (11.1.0)') }
end

内容としては、rake gemのversion 11.1.0が入っていることを期待するもので、repcipeにも同様の記述が存在しています。

しかし、同様にrepcipeでのインストール指定を行なっているbundler 1.16では、rakeのversion 10系をdependencyとしています。 そのために、gem listの実行では複数versionのrakeがインストールされている事実が返ってくるので、文字列 'rake (11.1.0)' のmatchに失敗します。

これについては、文字列の末尾の閉じカッコを削除し、複数versionのrake gemがインストールされている状態でも通るようにしました。(あまり筋がいいとは思えませんが……)

test-unit gemが存在してしまう

test-unit gem、2回目の登場です。

以下のrepcipeにより、test-unit gemは削除されているはずなのですが、実際にはtest-unit gemは削除されておらず、specが落ちてしまいます。

gem_package 'test-unit' do
  version '3.2.0'
end

gem_package 'test-unit' do
  version '3.1.9'
end

gem_package 'test-unit' do
  action :uninstall
end

これは、ubuntuがxenialにアップグレードされたことに関係しています。 xenialでは、Ruby 2.3.1がaptからインストールされますが、Ruby 2.3.1では、test-unit gemをdefault gemとして扱っています。

そのために、test-unit gemをuninstallすることができず、specは落ちる、ということでした。

これについては、このspecを削除することで対応しました。

wercker.ymlの書き直し

さて、これでローカル環境でspecが通るようになったので、CIであるwerckerで実行できるようにしなければなりません。

しかし、Vagrantのインストール方法を変更したので、wercker.ymlの内容を変更する必要があります。

まずは愚直に、Ruby officialのdocker imageをboxに指定してみましたが、Vagrantの起動に失敗します。エラーの内容を見ると、modinfoが存在していない、というものでした。

しかし、色々調べてみたところ、docker container内でmodinfoをインストールすることはできないようです。

(数ヶ月前のことなのでどこを参照してその結論に至ったかは覚えてないのですが、今ruby:2.3.1のimageに対してapt install kmodを実行すると、インストールできるので、この認識が間違っている可能性は大いにあります。 しかし、modinfoの実行自体も、様々なmoduleに対して実行してもエラーが返ってくるので、やはり一筋縄ではいかないようです)

よくわからんなー状態になっていたのですが、そういえばsue445さんがitamae pluginをCIすることに一家言ある方だったことを思い出し、そのwercker.ymlを参考にすることにしました。

34歳になった&itamaeプラグインを本気でCIする #omotesandorb - くりにっき

そして紆余曲折あり、drecom-ruby imageを使用してVagrantのインストールと実行に成功するようになりました。

sue445さんのアドバイス in itamae.slack #random

Pull Requestの作成

これでなんとかようやくCIがpassするようになったので、pull requestを作成しました。

Fix failing integration spec (including workaround) by unasuke · Pull Request #253 · itamae-kitchen/itamae

#253

これに取り組み始めたのが12月の頭、PullReqの作成が1月の末であることから、まるまる2ヶ月の間、格闘していたことになります。実作業時間は恐らく1週間とちょっとくらいだと思いますが……

12月のESMさんでのOSSパッチ会でもくもくしていたのが遠い昔のように思えます(その時はmkdir問題に取り組んでいました)。

このPullReq自体も、wercker pipelineの編集が必要なためにCIは落ちているのですが、仕方ないですね。

情報科学若手の会冬の陣2018での発表

情報科学若手の会冬の陣2018 #wakate2018w - connpass

また、これに関して、情報科学若手の会冬の陣2018で発表してきました。以下が資料となります。

unasuke/wakate2018w_talk

2018年02月04日
2018年02月01日

株式会社バンクで働きはじめました

bank

TLDR

from 株式会社spice life (2015-04-01 〜 2018-01-31) to 株式会社バンク (2018-02-01 〜)

Bank, Inc - 株式会社バンク

転職活動でお世話になった方々には本当に感謝しています。ありがとうございました。

退職直前にやったこと

退職直前に負債を出来る限り返済するの、気持ちよく退職できるのでおすすめです。

フラー株式会社を退職し、合同会社ヘマタイトに入社しました - Allajah’s Reservoir

誰?

うなすけです。

2018年02月01日
2018年01月31日

Windows 10に開発環境を構築する in 2018年1月

Powershell on ConEmu

Windowsネイティブな開発環境があるとよさそうという気持ちになったので、構築してみることにした記録です。

前提条件

という条件のもと、Windows 10上にRubyおよびGolangの開発環境を構築しました。

PowerShell

なるべくネイティブ環境を目指すので、cmd.exeもしくはPowerShellを用いることになります。なので、PowerShellを使用しました。ただ、powershell.exeをそのまま使うのはちょっとつらいので、ターミナルエミュレーターからPowerShellを使用します。ConEmuやcmderなどがありますが、今回はConEmuを使うことにしました。

ConEmuの設定

ConEmuでは、colorschemeとしてSolarized Darkを、PowerShellの起動オプションとして-executionpolicy remotesignedを追加しました。

ConEmu PowerShell 起動オプション ConEmu PowerShell colorscheme

参考

Windows 10の開発環境を整えた - YAMAGUCHI::weblog

Chocolatey

LinuxでのaptやDNF、macOSでのhomebrewのようなパッケージマネージャーは開発には欠かせません。 Windowsで使用できるパッケージマネージャーといえばChocolateyなので、インストールしました。インストールにあたって、WMF経由ではなく、Chocolatey公式サイトの手順に従いました。

参考

とりあえずインストールしたパッケージ

Rubyのインストール

Rubyは、RubyInstallerを用いてインストールしました。場所はデフォルトのC直下にしています。

RubyInstaller for Windows

uru

Rubyのバージョンを切り替えて使いたいとなっても、rbenvやrvmはPowerShellでは動作しません。なので、uruを使用してRubyのバージョンを切り替えることにします。

インストール

  1. jonforums / uru / wiki / Downloads — Bitbucket よりnupkgをダウンロードする
  2. PowerShellでnupkgをダウンロードしたディレクトリに移動する
  3. choco install uru.0.8.4.nupkg を実行する

インストールが終了したあとは、uru admin add C:\Ruby25-x64\bin --tag 2.5.0 などでuruにRubyを追加し、 .ruby-version のあるディレクトリで uru auto を実行するとRubyのversionが切り替わります。

参考

Golang

Golangも、Rubyと同様にインストーラ(msi)を用いてインストールしました。

Downloads - The Go Programming Language

環境変数

また、環境変数として、以下の値を登録しました。

参考

Docker for Windowsのインストール

公式のインストーラを使用することで、PowerShellからdockerを使用することができるようになりました。

Docker Community Edition for Windows - Docker Store

Windows Subsystem for Linuxのインストール

ChocolateyやDockerの環境を構築しても、どうしてもLinux環境がないとどうにもならないことがあるので、WSLのインストールも行ないます。

ちなみに、このブログを書くためのmiddlemanはWSL環境でしか動作しませんでした。

これに関しては、必要になったタイミングで使うという方針なので、あまり環境構築に手間をかけないことにしました。

参考

参考サイト一覧

当初はMSYS2でいくつもりだった

最初はMSYS2でやっていくつもりだったのですが、Docker for Windowsを入れたタイミングでdockerコマンドがMSYS2で入れたzshから使用できなかった(PATHが通ってなかっただけ?)のでエイヤでPowerShellに切り替えました。

MSYS2の環境構築で参考にしたサイト一覧

2018年01月31日
新しい投稿
古い投稿