Fusicきばんブログ

Fusic基盤ユニットの非公式技術ブログ

Stack Clash脆弱性対応まとめ

基盤ユニットの貞方(@sadapon2008)です。 Stack Clash脆弱性の対応について調べた情報をまとめておきます。

Stack Clashとは

セキュリティ企業のQualys社が6月19日に公表した、ローカルからの特権昇格の恐れがある脆弱性です。 対象OSはLinux系、BSD系、Solaris系に影響があるとのことです。 今のところリモートからの攻撃成功可能性は低いようですが、昔問題になったShellShockのようなものと組み合わさるとまずいです。

Qualys社の公表記事はこちらです。

https://blog.qualys.com/securitylabs/2017/06/19/the-stack-clash

メディア記事

www.itmedia.co.jp

japan.zdnet.com

news.mynavi.jp

www.security-next.com

thinkit.co.jp

対応方法

根本的にはアプリケーションバイナリの再コンパイルが必要とのことですが、kernelとglibcで影響を軽減するためのアップデートが公開されているようです。kernelとglibcを更新したらシステムを再起動をした方がよさそうです。 ここではLinux系のアップデート情報をまとめておきます。

Red Hat Enterprise Linux(RHEL)

RedHat社が特設サイトを開設しています。

https://access.redhat.com/security/vulnerabilities/stackguard

RHEL5~7のアップデートが公開されています。

CentOS

CentOS6~7のアップデートが公開されています。

[CentOS-announce] CESA-2017:1486 Important CentOS 6 kernel Security Update

[CentOS-announce] CESA-2017:1480 Important CentOS 6 glibc Security Update

[CentOS-announce] CESA-2017:1481 Important CentOS 7 glibc Security Update

[CentOS-announce] CESA-2017:1484 Important CentOS 7 kernel Security Update

CentOS5はすでに本家のRHEL5が通常サポート終了で延長サポートフェーズになってしまったため、RHEL5のアップデートが一般公開されておらず、CentOS5のアップデートパッケージを作成できない状況のようです。 海外フォーラムで見かけたアドバイスとして「有償サポートつきのRHEL5を購入して移行する」というのもありましたがそのあたりはシステム次第でしょう。 また、独自にCentOS5のサポートを提供しているベンダもあるようです。

www.miraclelinux.com

Ubuntu

公式の質問フォーラムに情報がまとまっていました。

askubuntu.com

Amazon Linux

アップデートが公開されています。

ALAS-2017-844

ALAS-2017-845

AWS全般についてはこちらにまとまっています。

Linux Security Advisories - June 2017

複数AWSアカウントのRoute53で管理されている複数HostedZoneの複数DNSレコードをうまく変更する

基盤ユニットの小山 ( @k1LoW ) です。

そろそろ PHPカンファレンス福岡2017ですね!

弊社Fusicでは前日に会社会議室を開放してクーラーの効いているWiFiスポットを提供しますので、是非ご利用下さい。 Fusicは天神にありますしアクセスも良いです。福岡の開発会社をみるいい機会ですよ!

fusic.co.jp

さらにカンファレンスの次の日は無限ビール(?)を開催します!

fusic.doorkeeper.jp

楽しみですね!


さて、以前ちょっと面倒なDNS設定変更作業がありましたので、その作業手順をメモしておこうと思います。

主にRubyの話です。

DNS設定変更作業内容

1つ1つの作業はただのDNSレコードの設定変更だったのですが、少し面倒で

  • 複数のAWSアカウントのRoute53で管理されているHostedZone
  • HostedZoneも複数
  • HostedZone内の変更対象のDNSレコードも複数
  • それぞれ変更内容が異なる
  • DNSレコードの先にはそれぞれWebサーバが存在。設定変更後も同じWebサーバにリクエストが通る前提

というものを、(Webサイトが存在するので)できるだけ短時間に実施する必要がありました。

結果として、Codenize.toolsによるコード化ができ、+Rubyスクリプトでの事前のテストで変更内容の確認ができたので心理的ストレスなく当日を迎えられました。

作業内容

1. AWSリソース操作の権限をつなげる

対象Route53が複数のAWSアカウントにまたがっていたので、まずはAWSリソースの操作権限を1つのIAM Userにつなげました。

メインのAWSアカウントでIAM Userを作成し、それ以外のアカウントにはAssume Role用のIAM Roleを作成して連携させています。

~/.aws/credentials~/.aws/config は以下のようになりました。

# ~/.aws/credentials
[change-task-user-main]
aws_access_key_id = XXXXXXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# ~/.aws/config
[profile change-task-role-a]
role_arn = arn:aws:iam::11111111111111:role/change-task
source_profile = change-task-user-main

[profile change-task-role-b]
role_arn = arn:aws:iam::222222222222:role/change-task
source_profile = change-task-user-main

[profile change-task-role-c]
role_arn = arn:aws:iam::333333333333:role/change-task
source_profile = change-task-user-main

2. DNSの設定をCodenizeする

Route53の設定は特にコードでの管理がされていませんでしたので、まずはコードで管理できるようにします。

Codenize.toolsの1つであるRoadworkerを利用します。

RoadworkerはRoute53の設定をコード化して管理運用するツールです。

Codenize.toolsの各ツールにはエクスポート機能があるのでいつでもコード化できます。

以下のようにRoute53の設定をRoadworkerのexport機能でエクスポートしました。

$ AWS_PROFILE=change-task-user-main bundle exec roadwork -e -o Routefile.main
$ AWS_PROFILE=change-task-role-a bundle exec roadwork -e -o Routefile.a
$ AWS_PROFILE=change-task-role-b bundle exec roadwork -e -o Routefile.b
$ AWS_PROFILE=change-task-role-c bundle exec roadwork -e -o Routefile.c

3. CodenizeしたDNS設定を使って、別のAWSアカウントでテスト環境を構築する

エクスポートしたRoutefileを使って別のAWSアカウントでRoute53のテスト環境を構築します。

$ AWS_PROFILE=change-task-test bundle exec roadwork -a -f Routefile.main
$ AWS_PROFILE=change-task-test bundle exec roadwork -a -f Routefile.a
$ AWS_PROFILE=change-task-test bundle exec roadwork -a -f Routefile.b
$ AWS_PROFILE=change-task-test bundle exec roadwork -a -f Routefile.c

これで本番環境のDNS環境(本番DNS)とテスト用のDNS環境(テストDNS)ができました。

4. HTTPリクエストのテストを作成する

本番環境NS、テスト環境NS、そして(念の為)GoogleのNSを使ったHTTPリクエストのテストを作成します。

NSの変更は Resolv::DefaultResolver#replace_resolvers で切り替えました。

HTTPリクエストのテストは取得したHTMLに期待する文字列が含まれているかどうかの簡単なテストです。

ざっくりですが以下のような感じで構築しました。

require 'spec_helper'

dns = {
  production: 'XXX.XXX.XXX.XXX',
  test: 'YYY.YYY.YYY.YYY',
  google: '8.8.8.8'
}

specs = [
  { fqdn: 'example.com', url: 'http://example.com', expected: 'Production Site' },
  { fqdn: 'www.example.com', url: 'http://www.example.com', expected: 'Production Site' },
  { fqdn: 'example.jp', url: 'https://example.jp', expected: '本番サイト' },
  { fqdn: 'blog.example.org', url: 'blog.example.org', expected: 'Production Blog' }
]

dns_req_spec(dns, specs)
# spec_helper.rb
def dns_req_spec(dns, specs)
  dns.each_with_index do |d, idx|
    specs.each do |spec|
      describe "#{spec[:fqdn]} #{idx} DNS" do
        before(:context) do
          resolver = Resolv::DNS.new(nameserver: [d])
          Resolv::DefaultResolver.replace_resolvers([Resolv::Hosts.new, resolver])
        end
        it "#{spec[:url]} http access" do
          connection = Faraday.new spec[:url] do |conn|
            conn.use FaradayMiddleware::FollowRedirects
            conn.adapter :net_http
          end
          res = connection.get '/'
          expect(res.body.force_encoding('UTF-8')).to include(spec[:expected])
        end
      end
    end
  end
end

これで、本番環境NS、テスト環境NS、GoogleのNSの3つにおいて正常にHTTPリクエストが通るかどうかのテストができました。 (正確には対象DNSレコードがCNAMEの場合はテストできませんが)

(ちなみに、Route53のDNSレコードの設定が反映されたかどうかのテストであれば roadwork -t で実施できます。今回はテストDNSというものがあったので利用していません。)

5. テストDNSのDNSレコードの設定を変更する

テストDNSを今回の変更内容に合わせて変更します。

Routefileを編集してRoadworkerの apply オプションで一気に適用できるから便利ですね。

[Edit Routefile.*]
$ AWS_PROFILE=change-task-test bundle exec roadwork -a -f Routefile.main
$ AWS_PROFILE=change-task-test bundle exec roadwork -a -f Routefile.a
$ AWS_PROFILE=change-task-test bundle exec roadwork -a -f Routefile.b
$ AWS_PROFILE=change-task-test bundle exec roadwork -a -f Routefile.c

先ほど4で作成したHTTPリクエストテストを実行して、DNSレコード設定変更後も正常にHTTPリクエストが通ることを確認します。

6. 本番DNSのDNSレコードの設定を変更する

既に検証はテストDNSで終わっているので、先ほど修正したRoutefileを本番のRoute53にそれぞれ apply していけば完了です。

$ AWS_PROFILE=change-task-user-main bundle exec roadwork -a -f Routefile.main
$ AWS_PROFILE=change-task-role-a bundle exec roadwork -a -f Routefile.a
$ AWS_PROFILE=change-task-role-b bundle exec roadwork -a -f Routefile.b
$ AWS_PROFILE=change-task-role-c bundle exec roadwork -a -f Routefile.c

再度、先ほど4で作成したHTTPリクエストテストを実行して、DNSレコード設定変更後も正常にHTTPリクエストが通ることを確認します。

これで完了です。

まとめ

インフラの設定をコード化(Codenize)することによってその後の作業を効率化、さらに作業漏れの軽減ができました。

Rubyで「リゾルバを変更する」という処理を書けることで、事前のテスト検証も実施できました。

今回のDNSがAPIで設定変更可能なRoute53でなかったと思うとちょっとツラいですね。

もし同じようなDNS設定変更があった場合の、何かの参考になれば幸いです。

mockmock × Google Cloud Platform( × Slack)

こんにちは。Fusic 基盤ユニットの濱野です。
今日は、先日 4/6 に正式リリースされた 弊社サービス mockmock を使ってみた話を書いてみようと思います。

mockmock とは?

- mockmockはIoTの開発支援サービス。
- クラウド上に仮想デバイスを作成し、開発中のサーバーに疑似データを送ってくれる。
- デバイスの制約を受けずにIoTのサーバーアプリの開発が進められるので、とっても楽。

というサービスです。

目標

mockmock から Google Cloud Platform(以下、GCP) に作ったAPI を叩き、
Slack に通知を飛ばす
とりあえず、シンプルにWeb API を叩けるようになる!!!

まず最初に、GCPにAPI サーバーを作ります。

使用したのは、永年無料で使用できると噂の f1-microです(※1)。
こちらのサイト https://blog.apar.jp/web/6966/ を参考にさせて頂きました。

環境は、

$ nginx -v
nginx version: nginx/1.10.2

$ php -v
PHP 7.0.17 (cli) (built: Mar 14 2017 15:14:30) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies

です。

ちなみに、f1-micro では、メモリが 0.6 GB しかありません。
docker の mysql image をrun しようとしましたが、
メモリ不足で起動すらできませんでした。
後日、省メモリについても調べます。。。

PHP のコード

docroot に、2種類のファイルを作成しました。

1つめ
index.php

<?php
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
  echo json_encode(['key' => '鍵']);
}

こちら、後ほど説明しますが、
mockmock のプロジェクトを作る際に必要になる処理です。
‘鍵’ と書いたところに、mockmock のプロジェクト作成時に提示される 認証キー を入れます。

2つめ
success.php

<?php
function send_to_slack($message) {
  $webhook_url = 'https://hooks.slack.com/services/カスタムインテグレーションのURL';
  $options = array(
    'http' => array(
      'method' => 'POST',
      'header' => 'Content-Type: application/json',
      'content' => json_encode($message),
    )
  );
  $response = file_get_contents($webhook_url, false, stream_context_create($options));
  return $response === 'ok';
}
$message = array(
  'username' => 'mockmock',
  'text' => 'fooooo!!!',
);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
  // request body に json が送られてくる際、$_POST は空になるので、この処理が必要。
  $json = file_get_contents('php://input');
  $array = json_decode($json, true);
  if ($array['status'] == 'success') {
    $date = new DateTime();
    $now = $date->format('Y-m-d\TH:i:s.u');
    $message['text'] = 'success'.$now;
  } else {
    $message['text'] = 'error';
  }
   send_to_slack($message);
} else {
  echo send_to_slack($message);
}

とりあえず動くことを目標に頑張りました。
slack 通知の送り方は、この辺を参考にしました。ありがとうございます。
http://qiita.com/hoto17296/items/621a6e16f23785a543f3 http://qiita.com/gorogoroyasu/items/a73ba2180d0934f51485 (これ、自分の記事です。)

これで、サーバー側完成です。

(file_get_contents(‘php://input’) を知らなくて、結構ハマリました。 普段はCakePHPを使って開発しているので、素書きのPHPが難しい。。。)

mockmock 側の設定

次に、mockmock 側の設定の話を書いていきます。

公式のヘルプ
を参考にさせていただきました。

ヘルプに沿って、こんな感じの設定を書きます。

f:id:adiboy:20170409233749p:plain

そして、疎通確認を行います。 注意点は、mockmockからのリクエストが GETで飛んでくることです。 まあ、URL にアクセスしてるだけだから当たり前といえば当たり前なのですが。。。

次に、mockグループの新規作成を行います。

と言っても、適当に名前をつけるだけです。

そのあと、mockステータス を設定します。 新規作成を押したあと、 f:id:adiboy:20170409233829p:plain こんな感じで設定します。 f:id:adiboy:20170409233842p:plain

データテンプレート というのは、どのようなデータを送信するか のテンプレートのことです。
ヘルプが参考になります。 https://console.mock-mock.com/help#help_data_template
デフォルトで、 {'hello': 'world'} というデータを送るようなテンプレートがセットされます。
ここを自由にカスタマイズできる仕組みです。

その後、 mock のタブを開き、新規登録を押すと、準備完了です。
f:id:adiboy:20170409233915p:plain

あとは、操作 ボタンから、 起動 を選択するだけ。
数秒 ~ 数十秒 したら、 mockからAPI にデータが飛んできます。

ということで

mockmock は、本来IoT のデバイスの代わりとして使うものですが、 任意のデータをWebAPIに送れるので、GCPに作ったAPI を叩き、Slack に通知を飛ばしてみました。 ハローワールドすることはできたかな? と思います。
少しでもとっつきやすいと思っていただけたら幸いです。

次回は、もう少し mockmock を掘り下げてみようと思います。
楽しい週末でした(※3)!

Slack のスクショ f:id:adiboy:20170409234915p:plain

※1
GCP を使うのは、完全に今回が初めてです。
SSH するのが大変でした。
普通に ~/.SSH/authorized_keys に公開鍵を設定するだけではだめらしい。
http://qiita.com/kosuke_nishaya/items/3d9a95f559d0c22d8134
のような設定が必要らしいです。

※2
もともと、 AWS の API Gateway を叩いて、 Lambda からSlack に通知を飛ばす的な、
サーバーレス的なやつをしたかったのですが、
どうもうまく行きませんでした。

まあ、AWS の知識は皆無に等しいので、詳しい方々は問題ないと思いますが。。。
それで、こんな感じでGCP を使うことにしたのです。

※3
http://ghostshell.jp/ を見に行く予定だったのに、
予定が大幅にずれ込んだため、泣く泣く延期します。
ネタバレはしないでください。

CakePHP3の負荷テストでの落とし穴

基盤ユニットの貞方(@sadapon2008)です。

CakePHP3のアプリをApacheBenchで負荷テストした際にはまった落とし穴をご紹介します。

前提

  • CentOS 7.3 + Apache 2.4 + PHP 7.0.17(remi版のmod_php)

落とし穴:ApacheBenchでCakePHP3の負荷テストをやってみたら全く性能が出ない

非常に簡単な負荷テストとして、静的HTML、素のPHP、CakePHP3.4.3でGETに対して簡単なHTMLを返すだけのものを用意し、 下記のコマンドでApacheBenchを実行してRequests per secondを測ってました。

$ ab -t 10 -c 20 -n 1000000 http://a.b.c.d/

すると、CakePHP3だけ3桁以上性能が悪い結果が出て(´・ω・`)となりました。 CakePHP3のデバッグモードはオフにしています。

  • 静的HTML: 約 8,000 req/s
  • 素のPHP: 約 7,500 req/s
  • CakePHP3: 約 2 req/s

原因

さすがにこの結果はおかしいだろうと原因を調査したところ、下記の記事を見つけました。

stackoverflow.com

PHP 5.4以上ではHTTPのリクエストのConnectionヘッダを指定しないとheader()が非常に遅くなるとのことでした。 CakePHP3のソースを見てみると↓の箇所で使っているheader()がまさに該当していました。

https://github.com/cakephp/cakephp/blob/3.4.3/src/Http/ResponseEmitter.php#L144

ワークアラウンド

前述の記事を参考にab -kを指定してConnection: keep-aliveが有効になるようにしてみました。

$ ab -t 10 -c 20 -n 1000000 -k http://a.b.c.d/

その結果、かなり改善しました!

  • CakePHP3 before: 約 2 req/s
  • CakePHP3 after: 約 700 req/s

元記事によるとクローラーなど行儀の悪いクライアントはConnectionヘッダが欠落していることもあるとのことなので、例えばApacheなら以下のような設定を行うことで、Connectionヘッダを強制することが可能です。

※ (2017/3/28追記)HTTP/1.1ではConnectionヘッダを指定しない場合はkeep-aliveをデフォルトとするようでしたのでプロトコルのバージョンをHTTP/1.0に絞り込む設定に変更しました。

<If "%{SERVER_PROTOCOL} =~ m#^HTTP/1\.0#i">
SetEnvIfNoCase Connection "^(keep-alive|close)$" APP_CONNECTION=1
RequestHeader set Connection close env=!APP_CONNECTION
</If>

↑の設定をすると-kを指定せずとも同じくらいの結果が得られました。

Rust言語でゆるくツールを作ってみるお話

Fusicの中野です。

最近、弊社の東京事務所内で人気のRust(プログラミング言語)について。

Rust言語

Rust言語についてのイメージは

  • 所有権と借用
  • 難しい
  • GCがない
  • 速いっぽい

とかでしょうか。

特に、所有権と借用のメモリ管理まわりの概念が、少し難しい言語かなと思います。

しかし、パターンマッチ・型推論・総称型・マクロなど、とても魅力的な要素がたくさん ある言語なので、今回はRust言語の勉強用にちょっとしたツールを作ってみました。

作ってみたツール

ということで、

github.com

主な機能として

  • $HOME/.ssh/config をパースする
  • Host <何か> の何か部分を取り出して、tmuxのパネルを分割してSSHで接続
  • それぞれの接続先にコマンドを送りつける

です。

使用したライブラリとして、

$HOME/.ssh/configのパース => rust版parsecのnom
readlineっぽいやつ => liner

を使わせていただきました。

nomはparsecとそっくりだったので、exampleとガヴリールドロップアウトを見ながら、 さくっと利用する事ができました。

感想として

Rustは難しい部分もあるかと思いますが、コンパイルが通れば気持ちいいですし そこそこ想定通りの動きをしてくれます。

rustup・rustfmt・racerなどの開発用ツールや、Rustの日本語記事や日本語訳ドキュメントなど、 簡単に利用するための環境が充実してきました。

Rust言語が気になっている人は、軽く試してみてはいかがでしょうか?

障害対応の裏側で何をやっているかの話

Fusic 平田です。
基盤ユニットの追加モジュール的な何かになりました。

何書こうかなーと思い、最近あったtypoとの悲しい戦い*1をまとめなおすとかでも良かったんですが、せっかくなので違う話を。

サイトが閲覧できない!な時に何をやっているか

障害対応なんかに遭遇しやすい、あるいは呼ばれやすい性質でして。
その時何やっているのかって話を少し。

あわてない、さわがない、はしらない

まあとりあえず。
何もいい結果に繋がらないので。

起きている状況をなるべく正確に知る

「全く閲覧できない」なのか、「閲覧できるけどすごく重い」なのか、それだけでも大きな違いなので、状況確認は正確に。

ネットワーク的に到達できるのか、サーバにログインできるのか

これすらできない場合は、

  • ネットワーク起因だったりするので周辺の状況(経路でネットワークダウンの障害報が出てないかなど)を確認する
  • OSがハングしている場合は、再起動を試みる

といった対応にシフトします。

リソースの使用状況の確認

dstatで確認することが多いです。
リソース監視を行っているのであれば、そのグラフ状況を見るなどして、リソースの使用状況を確認します。

  • メモリが枯渇している
  • CPUを使い過ぎている
  • I/O待ちが発生しまくっている

といった感じで、ボトルネックを特定します。

ログを見る

/var/log/ 以下であったり、アプリケーションのログであったりを確認して、特異な(OOM Killerなんかは特異の典型)ログが出ていないかを確認します。
特異点の判断ポイントとしては

  • 明らかに普段出ないログが出力されている
  • ログの量が普段より明らかに多い

といった観点になるでしょうか。

ただ目で追うのもさすがに辛いので、grepなりwcなり、コマンドと組み合わせて原因を探る感じです。

あと、アクセスログを精査するのであれば、Kataribeが便利です。
ISUCON御用達ツールですが、負荷の高い箇所だったりアクセス増だったりの一次調査で使えます。

対策を決めて実行する

原因が明確に特定できたのであれば、対応する内容も明確になります。
アプリケーションの修正であったり、ミドルウェアの設定値変更であったり。
緊急度と対応時間とを天秤にかけて、場合によっては一次対応(応急処置)と二次対応(抜本的な対策)を分けるケースもあります。

原因が分からないケース

というのも当然あるので、その際は出力するログを増やすなどして網を張るようにしています。

実例だとこんな感じ

1ヶ月ほど前に起きた事例ですが。

  1. 状況としては「繋がるけどすごく重い」 → OSがハングしているとか、全く手が付けられないわけではなさそう
  2. ssh繋いでみたところ、接続できた → 障害報もないし、ネットワークはあまり関係なさそう
  3. リソースを確認するとロードアベレージが異様に高い → CPU起因だから、どこかで重い処理が走っているとか?
  4. ログを確認すると、httpサーバのログが大量に出ている → アクセスが相当増えた?
  5. アクセスログを精査する → 特定のページに対してアクセスが集中していることが分かった(原因判明)
  6. 特定のページと関連リソース(ページ内の画像)に対して一時的にキャッシュするよう設定変更(対策)

実例その2

こんなケースも。

  1. 「サイトに繋がらない」 → あらゆる可能性あり
  2. ssh繋いでみたところ、接続できた → ネットワークはあまり関係なさそう、OSも大丈夫そう
  3. リソースはどれもおおむね問題なし → 明確な原因が不明
  4. ログを確認するが、どれも平常通り → 明確な原因が不明だけど、httpのプロセスがうまく動作しなくなっているのかもしれない
  5. 応急措置としてhttpサーバを再起動(一時対応)したら復旧した → 引き続き注視しつつ、ログを精査するなどして調査
  6. 特定の処理が重くて落ちた可能性がある → 開発環境で再現するかを検証(原因判明)
  7. 再現したのでアプリケーションを修正してリリース(抜本的な対策)

というわけで

何かものすごいことをやっている話ではないので恐縮なのですが、こんな感じで障害対応していますって話でした。

余談: ログをもっといい感じに可視化して集中管理したい

可視化 + 集中管理の仕組みを設ければ、調査系で呼ばれる回数が減りそうだなーと。
前時代感なまま過ごしていたんですが、この辺をKibanaに集めるような仕掛けをぼちぼち組まねばな、と。

って書いてしまったので、今年の前半はその辺を整備していきます。

*1:100以上のコミットを経て、ようやく落ち着いた。と思う。

cakephp/cakephp にPR 出してmerge された話

(Fusic Advent Calendar 24日目)http://qiita.com/advent-calendar/2016/fusic & (CakePHP3 AdventCalendar 24日目)http://qiita.com/JoJeongMin/items/9fbc4cc1de9268b5de56http://qiita.com/advent-calendar/2016/cakephp3です。

Fusic 新卒の濱野です。
基盤ユニットに配属されてまもなく半年。
周りの席にはその道10年の職人さんが多く座っているので、
いつもつらい気持ちで席についています。

そんな肩身の狭い新卒ですが、
最近少しだけ胸をはれることがありました!

それは、、、

http://bakery.cakephp.org/2016/12/11/cakephp_3310_released.html
f:id:adiboy:20161223210812p:plain

そう。cakephp の core に出したPR が merge されたのです!!!
これはめでたい!!!

ということで、今回は、PR がマージされるまでの模様を時系列に沿ってお伝えしようと思います。
これを機に、PRの数が増えるとうれしいです!!!

何なおしたの?

pagination のバグを修正しました。

$paginate = [
    'limit' => 30,
    'maxLimit' => 20,
];

という設定をした時に、

maxLimit => 20

が無視され、

limit => 30

が採用されていました。
つまり、 maxLimit がちゃんと動いていませんでした。

どうやって見つけたか?

プラグインを作っていたら、挙動がおかしかったのでcore を読みました。
ちなみに、core は極力読むようにしています。
そして、時々ブログなどに結果報告を書いています。

例1
例2

その癖をつけていたおかげで、割とすんなり問題箇所の特定ができました。
そして、何が原因なのかがわかりました。

issue を登録する

こんなissue を登録しました。
https://github.com/cakephp/cakephp/issues/9848

全部英語で書くのが意外と大変でした。

PR を投げる

ついでに、issue に紐付ける形でPR も出しました。

I showed an example to fix this bug in #9849 ,
please review it, and I expect for some comments.
If my PullRequest is not worth to merge, don't hesitate to close it.

って書いて。
超意訳すると、

一応このissue を解決するPR 送りますー  

っていう感じです。

https://github.com/cakephp/cakephp/pull/9849

中の人とやり取りする

PR を出すとすぐ、chinpei215さんが調整してくださいました。
そして、マージされるまで面倒を見てくださいました。
この場を借りてもう一度お礼させて頂きます。
本当に有難うございました。

結局やり取りをしたのは2人でした。
一人は前述のchinpei215さん。
もう一人は、dereuromarkさん。

お二方とやり取りし、コードを修正しました。
そして、気づいたらマージされていました。

PR を出してから Merge されるまで1日もかかりませんでした。

感想

中の人は、優しかったです。(もちろんご指摘も頂きましたが)
そして、社内の人から声をかけられる機会が増えました。
これからも何かあったらどんどんプルリク出していこうと思います。

以上、未経験から入った新人が (cakephp/cakephp)https://github.com/cakephp/cakephp/ にPR を送ってマージされた話でした!