ひよっこエンジニアの雑多な日記

なんとかWeb系のエンジニアをやっています。

CircleCIでelasticsearchにkuromojiをインストールして起動させる

CircleCIで自動テストをしたいもののelasticsearchの処理を含んだ処理周りがうまくテストされなくて結構ハマったので備忘録。

やりたいこと

アプリケーションの機能として簡単な全文検索をelasticsearchを使って実現していたので、CircleCIにもelasticsearchを導入して全文検索用のindexを作成をアプリケーションのテストコードで行なっていた。
CircleCIを使ってGitHubでプルリクエストを上げた瞬間に自動でテストが走らせるCI環境を構築して、全テストをパスさせたい!

問題点

しかし、elasticsearchを導入してpluginとしてkuromojiを導入する必要があり、それを実現するのに四苦八苦。
elasticsearchを動かすだけならできるのだが、kuromojiを導入する方法がわからない…

ひとまずここみたら全てが解決しました。

解決法

circle.ymldependenciesに以下を追記してあげるだけでOK

dependencies:
  post:
    - wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.3.2.tar.gz
    - tar -xvf elasticsearch-5.3.2.tar.gz
    - elasticsearch-5.3.2/bin/elasticsearch-plugin install analysis-kuromoji
    - elasticsearch-5.3.2/bin/elasticsearch: {background: true}
    - sleep 10 && wget --waitretry=5 --retry-connrefused -v http://127.0.0.1:9200/

これ書いておくとelasticsearchをwgetでダウンロードして、解凍して、kuromojiインストールして、elasticsearchを起動してくれる。

毎回wget走るの重くなりそうでいややなーとなる場合は以下みたいな感じに書き換える。

dependencies:
  cache_directories:
    - elasticsearch-5.3.2
  post:
    - if [[ ! -e elasticsearch-5.3.2 ]]; then wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.3.2.tar.gz && tar -xvf elasticsearch-5.3.2.tar.gz && elasticsearch-5.3.2/bin/elasticsearch-plugin install analysis-kuromoji; fi
    - elasticsearch-5.3.2/bin/elasticsearch: {background: true}
    - sleep 10 && wget --waitretry=5 --retry-connrefused -v http://127.0.0.1:9200/

cache_directoriesを使うとディレクトリをキャッシュできるようなので、wgetして解凍したディレクトリをキャッシュしてくれるようになる。
! -e elasticsearch-5.3.2のところでディレクトリの存在確認をしてくれるのでキャッシュされてなかったらwget、解凍、インストールしてくれるし、キャッシュされてたらこの処理を飛ばしてくれるようになるので無駄なオーバーヘッドなくなるぽい。

これでelasticsearchをCircleCI上でも使えるようになってめでたしめでたし。

ちなみに

machine:
  services:
    - elasticsearch

最初、これでelasticsearch立ち上がるやん!と喜んでいたのですが、この記述をしているとwgetで落としてきたelasticsearchとは別物の子が動いちゃうので、いくらkuromojiをインストールしてもpluginがインストールされていないことになってテストが全く通らなくて禿げ上がりそうでした。
この記述に気づかず1時間ぐらい消費したのは愚かでした…

CentOS7系でhttpアクセスを許可する

毎度ConoHaでサーバー構築する際に忘れてしまうので備忘録

操作

httpを許可する

$ firewall-cmd --add-service=http --zone=public --permanent

httpsを許可する

$ firewall-cmd --add-service=https --zone=public --permanent

ファイアウォールをリロード

$ firewall-cmd --reload

ファイアウォールが正しく設定されているか以下のコマンドで確認

$ firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: dhcpv6-client http https ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  sourceports:
  icmp-blocks:
  rich rules:

serviceのあたりにhttpとhttpsが追加されていればOK

CentOS7で毎度環境構築するたびに忘れてて、検索するのがだるいのでブログ化
あとserviceコマンドに慣れすぎててsystemctlもよくど忘れする
あとmysqlいれたつもりになってるとmariadbが入ってて焦るときがある(ほぼmysqlと一緒だけど…)

【Rails】enumで特定の値を選択肢から省きたい

きむらです。またもやenum関連ですがちょっとなるほどと思ったことがあったので備忘録。

enumに設定している値を全て取り出す

例えばセレクトボックスに選択肢としてenumに設定している値を出す場合などによく使うとおもいます。

# blogというモデルに公開範囲(非公開、公開、一部に公開)のようなステータスがある想定
class Blog < ActiveRecord::Base
  enum status: { unpublish: 0, publish: 1, part_publish: 2 }
end

# enumに設定したstatusの状態をすべて取得する
Blog.statuses
=> {"unpublish"=>0, "publish"=>1, "part_publish"=>2}

てな感じでモデル.enumを設定した属性の複数系と書くことでenumに設定した値を取得することができます!
これを使えばブログの公開範囲選択セレクトボックスを作成するのが簡単になったりします!

enumに設定している特定の値だけを取得したい

便利とはいえ特定の状態だけを選択させたくなるときもあります。
例えば一部に公開(part_publish)を特定の箇所では選択肢に入らないようにしたいとか

そんなときはsliceexceptを使うと幸せになれます!

sliceを使ってpart_publishを省く

Blog.statuses.slice(:unpublish, :publish)
=> {"unpublish"=>0, "publish"=>1}

sliceを用いると引数に指定した値だけを取り出すことができます。
特定の値を省くというより、特定の値だけを取り出すという感じですね!

exceptを使ってpart_publishを省く

Blog.statuses.except(:part_publish)
=> {"unpublish"=>0, "publish"=>1}

exceptを用いると引数に指定した値は取得しないようになります!
省くという意味合いではexceptの方が正しそうですね。

といった感じで簡単にenumに設定した特定の値だけを取得できるようになります!
これらを使ってクラスメソッドなんか作ってあげるとスマートっぽい気がしますね!

class Blog < ActiveRecord::Base
  enum status: { unpublish: 0, publish: 1, part_publish: 2 }

  def self.restrict_statuses
    statuses.except(:part_publish)
  end
end

Blog.restrict_statuses
=> {"unpublish"=>0, "publish"=>1}

slice、exceptは何者か

この二つはActiveSupportのメソッドのようです!
enumを設定して設定内容を取得したもののクラスが以下にになります!

Blog.statuses.class
=> ActiveSupport::HashWithIndifferentAccess

つまりBlog.statusesで取得できるものはハッシュってことになります。
RailsだとハッシュはActiveSupportパイセンの力でちょいちょい強化されていて、その強化された力を用いることで割と簡単にハッシュ操作ができたりします…。sliceexceptはその力の一部であるということです…。

ほんとActiveSupportActiveRecordあたりはよしなにいろんなことをやってくれるので便利すぎるなあという気持ちになります。

最近RailsのよしなにしてくれるところにあぐらかいてRuby力がなくなってきている(そもそもそんなにない)ので、その辺鍛え直さないとなあ…。

2017年が始まったので今年の目標を掲げてみる

お久しぶりです。きむらです。
めちゃめちゃブログサボってました…もはや存在忘れそうになってました…笑

2017年は気持ちを改めてブログ書きます!目標は3日で1記事!
というわけで2017年最初の記事は今年の目標を綴っていきたいと思います!(戒めのためにも)

2017年の個人テーマ

  • コミュニケーション
  • 興味関心
  • 意思決定

2017年に掲げる個人テーマは上記3点です! それぞれ少し深堀します。

コミュニケーション

これは若干コミュ障気味の自分を変えていくために意識したいなあと…。

仲のいい友達や職場の人とは大体喋れるんですけど、ちょっと苦手だなあと感じる人や微妙な距離感の人、初対面の人と向き合うと途端に喋れなくなる(もはや逃げ出したくなる)という状態を解消しなければ…と思っています…。
何かの本でコミュニケーションは人生を左右する云々のことが書いてあって、そうだよなあと思いつつコミュニケーションをないがしろにしていた感はあります(反省)

お正月休みにKindleでコミュニケーションに関するコミックエッセイを読んで、コミュニケーションを楽にする方法みたいなものを学んだ感があるので、それを実践していきたい所存です。

興味関心

いろんなことに興味関心を持つようにしたいです!

というのも自分が興味関心あることが今ぱっとでないという完全に無趣味無関心人間になってしまっていたという状態を解消したいです…。

無関心状態があることによって人と話したりしても、そんなん言われても興味ないんだよなあとか、人自体に興味関心がわかないんだよなあみたいな、ある意味中二病とも言える病に20半ばの今でもかかっているという事態を解消するというのがこのテーマを掲げた一番の理由ですかね…
このテーマはコミュニケーションにもつながりますしね…

意思決定

これは仕事、プライベート共にですね…。

仕事でもプライベートでも色々考えすぎて意思決定まで時間がかかりすぎたり、決定することを人に任せてしまったりということが多々あったので、もっと自分で何かを決定するということをしていかねばと…。
もはやご飯いくところも完全に人任せばっかりだったし…

なのでちょっとずつ自分で何かを決めていける、決めるまでのスピードを早められるようにするということをやっていきたいと思います!

おわりに

個人的に今年一年は自分自身の人生がどうなるかというのが色々な意味で占われる一年になるのではないかなあと思っています。
そんな一年で自分をきちんと見つめ直して、本当に興味あることや今後どのようになっていきたいかを見つけて豊かな人生を構築する足がけにしていきたいと思います!

そして今年こそ彼女をば…!!!笑

【Nginx】apple-touch-iconに攻め込まれる場合の対処

2ヶ月ぶりくらいの更新です…
毎度お世話になっております。きむらです…

最近色々とやばいことが重なりすぎて人生が楽しくなってきています。(白目)

さて今日はちょっとした記事ではありますがタイトルの通りの設定を備忘録代わりに書いときます!

状況

現在Nginx+Unicornで運用しているRailsアプリケーションがapple-touch-iconに攻められまくり、apple-touch-iconをサーバに配置していないのでRoutingエラーを弾き出しまくっていました…
そしてイケてないエラーハンドリングをしてしまっているのでアクセスされるたびにアラートメールが飛んでくる…
一時間に10通は送信されてくるので煩わしさが半端じゃない!!(エラーハンドリング改善しろって話なんですけどね…はい…)
Nginxでそのアクセスをさばいていなかったので、Unicornまでアクセスが到着してしまっているという状況でした…

解決策

一番はapple-touch-iconを設置してしまうことなのですが、用意しているわけではなかったのでNginxパイセンにさばいてもらうことにしました

root /アプリまでのパス/current/public;

location / {
     ルートパスの設定
}

location ~ ^/(apple-touch-icon*) {
     キャッシュの設定とか
}

ひとまずapple-touch-iconなんとかへのアクセスがあったら/アプリまでのパス/current/public配下を見せるように設定を記述しました。
これでapple-touch-iconなんとかを配置していなくてもNginxパイセンが404をはじき返してくれて、Unicornさんが怒りのアラートを出すことがなくなりました!一安心!

とりあえず最近手掛けてるアプリの作りやばいし、色々やばいし、色々頑張んなきゃいけないしでつらたん
今、誰かに優しくされたら惚れてまいそう(真剣)

mysqlでメールアドレスにマスクをかけるよ

今回は2週間ぶりくらいの更新!
ちょっとずつ間隔を短くしたい!

今回は件名の通りmysqlでメールアドレスにマスクをかけます。
hogehoge@example.com -> xxxxxxx-1@example.com
上みたいな感じにします!

シチュエーションとしては

  • 本番データをステージングに突っ込みたいけど個人情報やし、うかつに突っ込めない…
  • そんなときはメールアドレスにマスクをかけちゃお! みたいな感じです

兎にも角にも手順

1. 本番環境からdumpとる
2. ローカルにdumpを突っ込む(DBは作成してからNE)
3. マスクかけるupdate文を流す

update 'テーブル名' set 'emailのカラム' = replace('emailのカラム',left('emailのカラム',instr('emailのカラム','@')-1),concat('xxxxxxx_',id));

4. ローカルからdumpとる
5. scpでステージングに送る
6. ステージングでDBにdump突っ込む
7. 優勝

きょうのはんせいてん

インフラ触るときは1字1句の誤字脱字のチェック、
なにか質問するときはまず自分で確認できるところはないか考えてから
ちゃんと足りないことがないか確認してからアクションする

備考

postgresqlの場合はこうする

update 'テーブル名' set 'emailのカラム' = replace('emailのカラム',substring('emailのカラム', 1, strpos('emailのカラム','@')-1),concat('xxxxxxx_',id));

bootstrap datepickerで土日の色を変えるよ!

気がついたら、また前回更新から一ヶ月の時が過ぎてしまっていました…
この一ヶ月間は転職したり引っ越ししたりとかなりバタバターっとしていて割と人生的に変換期に入ってきている感があります…!

今回はbootstrap datepickerについて書いていきたいと思いますー!
ちょっと開発をしていてカレンダーから日付入力したいなーと考えた時にお手軽に実装できると噂のbootstrap datepickerを導入しました。
それで土日だけ色を違う色にしたいなーと思ったりして色々調べたものの日本語記事であまり情報がなかったので今回の題材にしようかなーと思いました。

(今回もRails開発の中での導入なのでGemを使って導入していたりしますがご愛嬌ということで…)

bootstrap datepickerを導入するよ!

1. Gemfileに追記

gem 'bootstrap-datepicker-rails'

2. bundle install
3. application.jsに追記

//= require bootstrap-datepicker/core
//= require bootstrap-datepicker/locales/bootstrap-datepicker.ja.js

とりあえず言語は日本語だけで良いのこんな感じ

4. application.cssに追記

 *= require_self
 *= require bootstrap-datepicker3
 *= require_tree .

これで一通り準備は完了!

bootstrap datepicker使ってみるよ!

javascript
$(document).ready(function(){
  $('.datepicker').datepicker();
});
HTML
<div class="input-group">
    <!-- erbの書き方なので注意 -->
    <%= f.text_field :input_date, class: "form-control datepicker" %>
</div>

とりあえずちょいちょいっとこんな感じで書くと下のような感じになります!
f:id:kimuraysp:20160716235227p:plain

とはいえかなり質素感が半端ないですね…
せめて土日だけでもわかりやすくなってほしい…

土日に色をつけるよ!

ということで土日に色をつけましょう!
まずはjavascriptを改良

javascript
$(document).ready(function(){
  $('.datepicker').datepicker({
    beforeShowDay: function(date) {
      var myDate = new Object();
      if (date.getDay() == 0) {
        myDate.enabled = true;
        myDate.classes = 'class-sunday';
        myDate.tooltip  = '日曜日';
      } else if (date.getDay() == 6) {
        myDate.enabled = true;
        myDate.classes = 'class-saturday';
        myDate.tooltip  = '土曜日';
      } else {
        myDate.enabled = true;
        myDate.classes = 'class-weekday';
        myDate.tooltip  = '平日';
      }
      return myDate;
    }
  });
});

beforeShowDayを設定することで日付表示の前に処理を行ってくれる。
ここの感じだとobjectにenabled, classes, tooltipを設定できるとのこと。
今回大事なのはclassesです!
これを使うことで色を変えたい曜日を判別します。

まずカレンダーに表示される日にちは1日単位でtd要素と成っているということを念頭に置いておいてください。
一日ごとにbeforeShowDayをみて処理を行います。
そこでif (date.getDay() == 0)みたいな感じで日にちと謎の数字を判定しています! この謎の数字は日〜土を表していて0〜6で表現されます。 なので0だったら日曜日の処理、6だったら土曜日の処理、それ以外は平日の処理をやってね!ということになります。

で次に設定する内容についてです。
enabletooltipは本質じゃないので割愛で…
大事なのはclassesこれに設定した値は一日単位で生成されるtd要素のclassとして追加されます。

そしてclassが追記されることでスタイルを当てることができるようになります!

.class-sunday {
  color: red !important;
}
.class-saturday {
  color: blue !important;
}

これをcssで記入してやることで

f:id:kimuraysp:20160717001759p:plain

こんな感じで土日に色がつきちょっとおしゃれな感じになりました!

おまけ

入力フォームをちょっとおしゃれにする

<div class="input-group">
  <%= f.text_field :input_date, id: "date-area", class: "form-control datepicker" %>
  <label for="date-area" class="input-group-btn">
    <span class="btn btn-success"><i class="fa fa-calendar"></i></span>
  </label>
</div>

f:id:kimuraysp:20160717002233p:plain

bootstrapと合わせることでちょっとおしゃれなdatepickerの入力フォームができてしまいます!
bootstrap datepickerというだけありbootstrapとの親和性は高いですね!

さて今回はbootstrap datepickerについて書きました。
探してた時は藁にもすがる思いでしたがわかってみると意外となんてことないコードでした。
こういう微妙にハメられる系を見つけ次第どんどん記事にしていこうと思います(また次は一ヶ月後かなあ…笑)