2017年12月31日日曜日

railsのplaceholderでi18n対応する

最近i18n対応することがあって、テキストのplacehodlerをどう国際化するのか不明だったので調べました。

まず書いてみたのはこんな感じ
= form_for(:user, url: 'xx') do |f|
  = f.text_field :last_name, { placeholder: t('activerecord.attributes.user.last_name'), required: true }
これだと、placeholderが翻訳できないエラーが出ました。
placeholder="<span class="translation_missing" title="translation missing: en.activerecord.attributes.user.last_name">Last Name</span>"


調べてみたところ、en.ymlにplacehodlerのhelper用の記述を加えて、form側の記述を変える必要があるようです。
・en.yml
en:
  helpers:
    placeholder:
      user:
        last_name: 'Last Name'

・form
= f.text_field :last_name, { placeholder: true, required: true }
これだとちゃんと言語が英語のときでもplaceholderがen.ymlに設定したLast Nameが表示されました。



参考URL
https://stackoverflow.com/questions/25677031/how-do-i-translate-placeholder-text-in-rails-4

2017年12月22日金曜日

プロを目指す人のためのRuby入門を読みました

プロを目指す人のためのRuby入門を読みました

2014年からrubyやりはじめてもう3年の経験あるんですが、
改めて入門本読んでみるとまだまだ知らなかったり理解が浅いところとかあって、
読んでよかったなぁと思いました。

特に最近日付を入力させるフォームを使ってるところでちょっとどうしようか考えていたのがあったので、
以下の2つがタイムリーにささりました。

・正規表現のキャプチャの結果に名前をつけられる
text = '今日は2017年12月22日です'
result = /(?<year>\d+)年(?<month>\d+)月(?<day>\d+)日/.match(text)

p result[:year]
p result[:month]
p result[:day]

これで
"2017"
"12"
"22"
という風に取れる


・rescue演算子を使ってbegin/endを省略できる
require 'Date'
text = 'aaaaaa'
result = Date.parse(text) rescue nil
p result
parseできない文字列の時にはnilが返って来る。
これまでbegin/endって囲んでてうざいなと思っていたので、いいことを知りました。

2017年5月22日月曜日

rails4.1.6からrails5.0.3にアップデートでActiveSupport::TimeWithZoneにはまった

rails4.1.6からrails5.0.3にアップデートをした際にrspecのテストが落ちて、
それを解決するのに調べました。

環境
ruby2.3.1
rails4.1.6からrails5.0.3

rspecはこんな感じ
test_time = Time.now

user.test_at = test_time
user.save!

ごにょごにょ処理

test_atが変わらないよねっていうテスト
expect(user.test_at).to eq(test_time)

4.1.6では通っていたけど5.0.3で落ちたテスト結果
expected: 2017-05-16 16:26:54.647989000 +0900
          got: 2017-05-16 16:26:54.000000000 +0900

test_timeはTimeクラス、user.test_atはActiveSupport::TimeWithZone。
rails4.1.6のときはsave!のタイミングではTimeWithZoneのミリ秒はまるめられてなかったみたい。
4.1.6でもexpectの前にreloadすると、ミリ秒はまるめられたものに変わった。
rails5ではsave!のタイミングでミリ秒をまるめたものを保持するように変わったげ。

2017年4月18日火曜日

rspecでtimecopで日時を固定したのにFactoryGirlのデータが固定されない

rspecのテストで特定の日時でのテストをしたくて、
timecopで日時を固定したのにFactoryGirlのデータが固定された日付ではなく、
現在日時のデータになってしまったので、調べました。

環境は以下です
timecop 0.8.0
factory_girl 4.5.0
rspec 3.5.0

テストデータとテストはこんな感じです。
FactoryGirl.define do
  factory :aaa do
    target_date Date.today.tomorrow
  end
end

Timecop.freeze(Date.parse('2017-04-04'))
aaa = FactoryGirl.create(:aaa)
expect(aaa.target_date == Date.today.tomorrow).to eq(true)
実行すると、trueにならずにテスト失敗となります。。

FactoryGirlの書き方を以下のようにすると、ちゃんと固定された日時を元に日付が入りました
target_date { Date.today.tomorrow }

参考URL
http://stackoverflow.com/questions/33110516/timecop-does-not-work-with-datetime-attributes-defined-in-factorygirl

2017年4月13日木曜日

omniauth-facebookのバージョンあげたら値が取れなくなった

omniauth-facebookのバージョンが古かったのでバージョンをあげたところ、
取れてた氏名の値が取れなくなったので調べました。
変更前:2.0.0
変更後:4.0.0

これまでのコード
取得部分
last_name = auth.info.last_name
first_name = auth.info.first_name

config部分
config.omniauth :facebook, 'app_id', 'app_token', locale: 'ja_JP', provider_ignres_state: true, scope: 'email, public_profile'

調べてみると、configに追加するだけで取れるようになるようです。
以下のように修正しました。
config.omniauth :facebook, 'app_id', 'app_token', locale: 'ja_JP', provider_ignres_state: true, scope: 'email, public_profile', info_fields: 'email, first_name, last_name'


参考URL
http://stackoverflow.com/questions/33090322/get-first-name-and-last-name-fields-from-facebook-omniauth

2017年4月4日火曜日

active_adminのバージョンあげたらshowの処理が変わってたのでパッチ当てた

active_adminのバージョンを1.0.0.pre5にあげたらこれまでshowで見れてた
xxx_idなどが表示されなくなったので調べました。

https://github.com/activeadmin/activeadmin/blob/master/lib/active_admin/resource/attributes.rb#L27
どうやらこの処理でxxx_idやxxx_countなどの値が表示対象から外されるようになったようです。
ただ、それだと困るとの意見があったのでパッチを当てることにしました。

こちらのクックパッドさんの投稿を参考にして以下のようなパッチを書きました。
http://techlife.cookpad.com/entry/a-guide-to-monkey-patchers

require 'active_admin/version'
unless ActiveAdmin::VERSION == '1.0.0.pre5'
  raise "Confirm need this patch"
end

module ActiveAdmin
  class Resource
    module Attributes
      def reject_col?(c)
        return false
      end
    end
  end
end

2017年2月13日月曜日

carrierwaveで画像のwidthとheightを取る

carrierwaveで画像をS3にアップロードするのですが、
一定のwidthとheightより小さいものはアップロードしないように
validateではじきたいなということでwidthとheightを取得する方法を調べました。

やり方としては、modelにwidthとheightの値を格納する変数を用意して、
uploaderでwidthとheightに格納する処理を記述すればよいようです。
保存をする前にwidthとheightを取ることができるので、
自分で比較してはじいたり、validateではじいたりどちらもできます。
class Image < ActiveRecord::Base
  mount_uploader :image, ImageUploader

  attr_accessor :width, :height
end

class ImageUploader < CarrierWave::Uploader::Base
  process :store_dimensions

  def store_dimensions
    if file && model
      model.width, model.height = `identify -format "%wx%h" #{file.path}`.split(/x/)
    end
  end
end

参考URL
https://github.com/carrierwaveuploader/carrierwave/wiki/How-to:-Get-image-dimensions

2017年2月6日月曜日

MacOS Sierraでrmagickが入らない件

Mac Sierraでrmagickのインストールがエラーになったので調べました。

rubyのバージョンは以下のとおりです
ruby 2.3.1
RMagick 2.13.3
起きたエラーは以下です。
ERROR:  Error installing rmagick:
    ERROR: Failed to build gem native extension.

    /Users/xxx/.rbenv/versions/2.3.1/bin/ruby extconf.rb
checking for Ruby version >= 1.8.5... yes
checking for clang... yes
checking for Magick-config... no
Can't install RMagick 2.13.3. Can't find Magick-config in ...

調べてみるとImageMagickが入ってないからというのが多かったのですが、
ImageMagickはちゃんと入っていて、バージョンは7系でした。
ただ、バージョンが7系なのがだめなようで、これを6系のものに入れ替えると、
うまくrmagickをインストールすることができました。

brew uninstall imagemagick

brew install imagemagick@6

brew link --force imagemagick@6


参考URL
http://stackoverflow.com/questions/41647979/imagemagick-7-with-rmagick-2-16-on-macos-sierra-cant-find-magickwand-h

2017年1月31日火曜日

railsのActiveRecordでSystemStackErrorが出た件

何気なくmodel作ってenum書いてたらSystemStackError出たので調べました。
railsのバージョンは4.1.6でした。

こんな感じのmodelを作っていました。
class Sample < ActiveRecord::Base
  enum target: {
    all_user: 0,
    parent: 1,
  }
end

そして動かしてみようとすると、エラーが出ました。
irb(main):001:0* aaa = Sample.new
SystemStackError: stack level too deep
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activerecord-4.1.6/lib/active_record/scoping.rb:68:in `value_for'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activesupport-4.1.6/lib/active_support/per_thread_registry.rb:47:in `public_send'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activesupport-4.1.6/lib/active_support/per_thread_registry.rb:47:in `block in method_missing'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activerecord-4.1.6/lib/active_record/scoping.rb:14:in `current_scope'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activerecord-4.1.6/lib/active_record/scoping/named.rb:25:in `all'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activerecord-4.1.6/lib/active_record/scoping/named.rb:151:in `block in scope'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activerecord-4.1.6/lib/active_record/model_schema.rb:335:in `compute_table_name'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activerecord-4.1.6/lib/active_record/model_schema.rb:148:in `reset_table_name'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activerecord-4.1.6/lib/active_record/model_schema.rb:109:in `table_name'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activerecord-4.1.6/lib/active_record/core.rb:151:in `arel_table'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activerecord-4.1.6/lib/active_record/core.rb:167:in `relation'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activerecord-4.1.6/lib/active_record/scoping/named.rb:33:in `default_scoped'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activerecord-4.1.6/lib/active_record/scoping/named.rb:28:in `all'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activerecord-4.1.6/lib/active_record/scoping/named.rb:151:in `block in scope'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activerecord-4.1.6/lib/active_record/model_schema.rb:335:in `compute_table_name'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activerecord-4.1.6/lib/active_record/model_schema.rb:148:in `reset_table_name'
... 10760 levels...
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activesupport-4.1.6/lib/active_support/dependencies.rb:241:in `load'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activesupport-4.1.6/lib/active_support/dependencies.rb:241:in `block in load'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activesupport-4.1.6/lib/active_support/dependencies.rb:232:in `load_dependency'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/activesupport-4.1.6/lib/active_support/dependencies.rb:241:in `load'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.7.2/lib/spring/commands/rails.rb:6:in `call'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.7.2/lib/spring/command_wrapper.rb:38:in `call'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.7.2/lib/spring/application.rb:191:in `block in serve'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.7.2/lib/spring/application.rb:161:in `fork'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.7.2/lib/spring/application.rb:161:in `serve'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.7.2/lib/spring/application.rb:131:in `block in run'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.7.2/lib/spring/application.rb:125:in `loop'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.7.2/lib/spring/application.rb:125:in `run'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.7.2/lib/spring/application/boot.rb:19:in `'
 from /Users/xxx/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
 from /Users/xxx/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
 from -e:1:in `
'



調べてみると、enumには使ってはいけない単語を使ってるけど、
それをチェックしてないから起こっているエラーのようです。
すでに修正されていて、rails4.2からはSystemStackErrorではなく、
conflictしてるとわかるエラーが出るようです


参考URL
https://github.com/rails/rails/issues/16347
https://github.com/rails/rails/commit/94b7328b08fcc55e82bfcaa34a25ae718921ae1c

2017年1月24日火曜日

jenkinsのpluginのupdateでエラー出た件

Jenkinsのプラグインのアップデートをしようとアップデート画面を開いたら、
エラーが出てJenkinsおじさんが怒っていたので調べました。

対象のバージョンは以下のとおりです
Jenkins 1.595
Subversion Plug-in 1.54

Jenkinsの管理 - プラグインの管理 - アップデートを開くと、
Subversionプラグインで以下のエラーが出ていました。

javax.servlet.ServletException: org.apache.commons.jelly.JellyTagException: jar:file:/var/cache/jenkins/war/WEB-INF/lib/jenkins-core-1.595.jar!/hudson/PluginManager/table.jelly:74:52:  java.lang.StackOverflowError
 at org.kohsuke.stapler.jelly.JellyClassTearOff.serveIndexJelly(JellyClassTearOff.java:117)
 at org.kohsuke.stapler.jelly.JellyFacet.handleIndexRequest(JellyFacet.java:127)
 at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:735)
 at org.kohsuke.stapler.Stapler.invoke(Stapler.java:876)
 at org.kohsuke.stapler.MetaClass$3.doDispatch(MetaClass.java:183)
 at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:53)
 at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:746)
 at org.kohsuke.stapler.Stapler.invoke(Stapler.java:876)
 at org.kohsuke.stapler.Stapler.invoke(Stapler.java:649)
 at org.kohsuke.stapler.Stapler.service(Stapler.java:238)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
 at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:686)
 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1494)
 at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:96)
 at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:88)
 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482)
 at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:48)
 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482)
 at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:84)
 at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:51)
 at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
 at jenkins.security.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:117)
 at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
 at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
 at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
 at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:142)
 at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
 at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:271)
 at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
 at jenkins.security.BasicHeaderProcessor.doFilter(BasicHeaderProcessor.java:93)
 at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
 at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249)
 at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:67)
 at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
 at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:76)
 at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:164)
 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482)
 at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:46)
 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482)
 at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:81)
 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482)
 at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30)
 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1474)
 at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:499)
 at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
 at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:533)
 at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
 at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
 at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:428)
 at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
 at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
 at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
 at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
 at org.eclipse.jetty.server.Server.handle(Server.java:370)
 at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:489)
 at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:949)
 at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1011)
 at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)
 at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
 at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
 at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:668)
 at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
 at winstone.BoundedExecutorService$1.run(BoundedExecutorService.java:77)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
 at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.commons.jelly.JellyTagException: jar:file:/var/cache/jenkins/war/WEB-INF/lib/jenkins-core-1.595.jar!/hudson/PluginManager/table.jelly:74:52:  java.lang.StackOverflowError
 at org.apache.commons.jelly.impl.TagScript.handleException(TagScript.java:745)
 at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:289)
 at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
 at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:161)
 at org.apache.commons.jelly.tags.core.WhenTag.doTag(WhenTag.java:46)
 at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
 at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
 at org.apache.commons.jelly.TagSupport.invokeBody(TagSupport.java:161)
 at org.apache.commons.jelly.tags.core.ChooseTag.doTag(ChooseTag.java:38)
 at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
 at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
 at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
 at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
 at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
 at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
 at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
 at org.kohsuke.stapler.jelly.CallTagLibScript$1.run(CallTagLibScript.java:99)
 at org.apache.commons.jelly.tags.define.InvokeBodyTag.doTag(InvokeBodyTag.java:91)
 at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
 at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
 at org.apache.commons.jelly.tags.core.CoreTagLibrary$1.run(CoreTagLibrary.java:98)
 at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
 at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
 at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120)
 at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
 at org.kohsuke.stapler.jelly.CallTagLibScript$1.run(CallTagLibScript.java:99)
 at org.apache.commons.jelly.tags.define.InvokeBodyTag.doTag(InvokeBodyTag.java:91)
 at org.apache.commons.jelly.impl.TagScript.run(TagScript.java:269)
 at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
 at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
 at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
 at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
 at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
 at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
 at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
 at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
 at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
 at org.kohsuke.stapler.jelly.ReallyStaticTagLibrary$1.run(ReallyStaticTagLibrary.java:99)
 at org.apache.commons.jelly.impl.ScriptBlock.run(ScriptBlock.java:95)
 at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
 at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120)
 at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
 at org.kohsuke.stapler.jelly.CallTagLibScript.run(CallTagLibScript.java:120)
 at org.apache.commons.jelly.tags.core.CoreTagLibrary$2.run(CoreTagLibrary.java:105)
 at org.kohsuke.stapler.jelly.JellyViewScript.run(JellyViewScript.java:95)
 at org.kohsuke.stapler.jelly.DefaultScriptInvoker.invokeScript(DefaultScriptInvoker.java:63)
 at org.kohsuke.stapler.jelly.DefaultScriptInvoker.invokeScript(DefaultScriptInvoker.java:53)
 at org.kohsuke.stapler.jelly.JellyClassTearOff.serveIndexJelly(JellyClassTearOff.java:112)
 ... 65 more
Caused by: java.lang.StackOverflowError
 at java.io.UnixFileSystem.getBooleanAttributes0(Native Method)
 at java.io.UnixFileSystem.getBooleanAttributes(UnixFileSystem.java:242)
 at java.io.File.exists(File.java:813)
 at hudson.util.TextFile.exists(TextFile.java:57)
 at hudson.model.UpdateSite.getData(UpdateSite.java:271)
 at hudson.model.UpdateSite.getPlugin(UpdateSite.java:331)
 at hudson.model.UpdateCenter.getPlugin(UpdateCenter.java:332)
 at hudson.model.UpdateSite$Plugin.getNeededDependencies(UpdateSite.java:684)
 at hudson.model.UpdateSite$Plugin.isNeededDependenciesCompatibleWithInstalledVersion(UpdateSite.java:762)
 at hudson.model.UpdateSite$Plugin.isNeededDependenciesCompatibleWithInstalledVersion(UpdateSite.java:763)

調べてみると、Subversionプラグインをupdateするとよいらしく、
Jenkins上からはアップデートできないので手動でアップデートを行いました。
wget http://updates.jenkins-ci.org/download/plugins/subversion/2.7.1/subversion.hpi
sudo cp -p subversion.hpi /var/lib/jenkins/plugins/
sudo service restart jenkins

これでエラーは出なくなりました。
ちなみにJenkinsでエラーは出なくなるけど、インストール済みのプラグインのところからSubversionプラグインが消えてました。
消えたままでも問題なさそうでしたけど、一応入れたほうがよいかなという場合は、
利用可能のところからインストールすることでまたインストール済みのところに現れるようになりました。


参考URL
https://issues.jenkins-ci.org/browse/JENKINS-36361
http://qiita.com/tnishi91/items/50e6a1f1071c135a22ee

2016年11月22日火曜日

rubyのaws-sdkでALBのターゲットグループに紐付いているEC2インスタンスのIPを取得してみた

ELBからALBにリプレイスを行うにあたって、ALB配下のインスタンスのIPを取得する必要があったので調べました。
ALBはターゲットグループを割り当てる形になるので、指定したターゲットグループに紐づくインスタンスを取得すればIP取れました。

require 'aws-sdk'

alb = Aws::ElasticLoadBalancingV2::Client.new(
  region: 'ap-northeast-1',
  access_key_id: 'xxx',
  secret_access_key: 'xxx'
)

ec2 = Aws::EC2::Client.new(
  region: 'ap-northeast-1',
  access_key_id: 'xxx',
  secret_access_key: 'xxx'
)

instance_healths = alb.describe_target_health({ target_group_arn: 'xxx' })
instance_ids = instance_healths.target_health_descriptions.map {|t| t.target.id }

ec2_instances = ec2.describe_instances({ instance_ids: instance_ids })
instance_ips = ec2_instances.reservations.map { |e| p e.instances[0].public_ip_address }

2016年11月9日水曜日

aws-sdk v2でS3操作するとエラー出た

rubyのaws-sdkでS3の操作しようとしたら、エラー出たのでその時の対応。
sdkのバージョンは以下で指定
gem 'aws-sdk', "~>2.1"

出たエラーは以下のようなもの
F, [2016-11-08T11:23:44.711503 #21962] FATAL -- : 
Aws::Errors::MissingRegionError (missing region; use :region option or export region name to ENV['AWS_REGION']):
  app/xxx:12:in `new'
  app/xxx:12:in `update_s3_bucket_acl'
  app/xxx.rb:338:in `update_s3_bucket_acl'
  app/xxx.rb:323:in `block in update'
  app/xxx.rb:306:in `update'
  config/initializers/quiet_assets.rb:6:in `call_with_quiet_assets'

そのときのコードの一部がこれ
require 'aws-sdk'

s3 = Aws::S3::Resource.new(
  access_key_id: #{access_key_id},
  secret_access_key: #{secret_access_key}
)

bucket = s3.bucket(bucket_name)

対応内容はエラーにまんま書いてあるように、regionを追加しました
s3 = Aws::S3::Resource.new(
  region: 'ap-northeast-1',
  access_key_id: #{access_key_id},
  secret_access_key: #{secret_access_key}
)

S3ってregion関係ないと思うので指定いらなそうなのになと思うのは勉強不足なのでしょう...


参考URL
http://qiita.com/rikitoro@github/items/45f9c85c218343e69014
http://stackoverflow.com/questions/28825047/aws-sdk-v2-for-s3

2016年10月24日月曜日

rubyのaws-sdkでELBに紐付いているEC2インスタンスのIPを取得しようとしたらバージョン2系で記法が変わってた件

ELBに紐付いているEC2インスタンスのIPを取得していたのですが、
aws-sdkのバージョンを1系から2系に変更したらけっこう記法が変わってたので調べました。

バージョン1系
require 'aws-sdk'

elb_name = 'aaa'

AWS.config({
  access_key_id: 'xxx',
  secret_access_key: 'xxx',
  ec2_endpoint: 'xxx',
  elb_endpoint: 'xxx'
})

elb = AWS::ELB.new
lb_instances = elb.load_balancers[elb_name].instances
instance_ips = lb_instances.map { |instance| instance.public_ip_address }

バージョン2系
require 'aws-sdk'

elb_name = 'aaa'

# ELBクライアント
elb = Aws::ElasticLoadBalancing::Client.new(
  region: 'xxx',
  access_key_id: 'xxx',
  secret_access_key: 'xxx'
)

# EC2クライアント
ec2 = Aws::EC2::Client.new(
  region: 'xxx',
  access_key_id: 'xxx',
  secret_access_key: 'xxx'
)

lb_instances = elb.describe_load_balancers({ load_balancer_names: [elb_name] })[:load_balancer_descriptions][0][:instances]
ec2_instances = ec2.describe_instances({ instance_ids: lb_instances.map { |instance| instance.instance_id } })
instance_ips = ec2_instances.reservations.map { |e| e.instances[0].public_ip_address }

2016年9月27日火曜日

rubyのバージョンをあげたらrails consoleが起動しなくなった件

rubyのバージョンを2.1.3から2.3.1にあげることになったので、バージョンアップをしたところ、
bundle exec rails cでエラーが出るようになりました。
$ bundle exec rails c
/Users/xxx/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- bundler/setup (LoadError)
 from /Users/xxx/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.1.3/lib/spring/commands.rb:33:in `'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.1.3/lib/spring/commands.rb:4:in `'
 from /Users/xxx/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
 from /Users/xxx/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.1.3/lib/spring/application.rb:77:in `preload'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.1.3/lib/spring/xxx.rb:140:in `serve'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.1.3/lib/spring/application.rb:128:in `block in run'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.1.3/lib/spring/application.rb:122:in `loop'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.1.3/lib/spring/application.rb:122:in `run'
 from /Users/xxx/Documents/github/test/vendor/bundle/ruby/2.3.0/gems/spring-1.1.3/lib/spring/application/boot.rb:18:in `'
 from /Users/xxx/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
 from /Users/xxx/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
 from -e:1:in `
'

調べてみると、bundle installでvendor/bundle配下に入れた時に、
springがvendor/bundleのbundlerを読み込もうとしてないよってエラーになっているようです。

更に調べてみると、springの1.6.3で直っているようです。

元のspringのバージョンが以下
$ bundle exec gem list|grep spring
spring (1.1.3)
spring-commands-rspec (1.0.2)

springのバージョンを最新にする
$ bundle update spring
$ bundle exec gem list|grep spring
spring (1.7.2)
spring-commands-rspec (1.0.2)

springを停止してからrails cをしてみると、いろいろメッセージでるけど、ちゃんと起動しました
$ bundle exec bin/spring stop
Spring stopped.
$ bundle exec rails c
Resque::Helpers will be gone with no replacement in Resque 2.0.0.
Running via Spring preloader in process 8207
Loading development environment (Rails 4.1.6)
irb: warn: can't alias context from irb_context.
Cannot read termcap database;
using dumb terminal settings.
irb(main):001:0> 


参考URL
http://qiita.com/koshigoe/items/2304ec081a9f036e8941

2016年8月17日水曜日

apache httpd serverがバージョンアップで起動しなくなった

apacheのhttpd serverがバージョンアップしたら起動しなくなったので調べました。
バージョンアップは意図して行ったのではなく、AWSのautoscaleで起動したインスタンスが
セキュリティアップデートでhttpd serverがバージョンアップしてしまった感じです。

バージョンアップ前のバージョン : 2.4.16-1.63.amzn1
バージョンアップ後のバージョン : 2.4.23-1.66.amzn1

バージョンアップ後、apacheが起動しないのでerror_logには以下の内容が残っていました。
[Tue Aug 16 19:16:23.815996 2016] [suexec:notice] [pid 3157] AH01232: suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Tue Aug 16 19:16:23.816582 2016] [proxy_hcheck:crit] [pid 3157] AH03262: mod_watchdog is required
AH00016: Configuration Failed

いろいろ調べてみたところ、mod_watchdog.soをloadする必要がありそうです。
元々の設定では読み込んでませんでした。
$ grep watchdog /etc/httpd/conf.modules.d/00-base.conf
#LoadModule watchdog_module modules/mod_watchdog.so

rpmに含まれているるconfでは読み込まれているようです。
$ grep watchdog /etc/httpd/conf.modules.d/00-base.conf.rpmnew 
LoadModule watchdog_module modules/mod_watchdog.so

mod_watchdog.soをloadするようにすると、無事に起動しました。


参考URL
http://forums.fedoraforum.org/showthread.php?t=310826

2016年8月10日水曜日

nginxのせいでDisk Fullになってアクセス不能になった件

正直恥ずかしい話ですし、Disk監視ちゃんと入れておけば防げる話です。

AWSのEC2でnginx動かしていたら、Disk使用率が100%になってレスポンスが返せなくなりました。
原因はnginxが巨大なログファイルを出力していたためなのですが、
dfだとdiskが喰われているのに、/に移動してdu -sh *でディレクトリごとの使用量を見てみても、
どこがdiskを喰っているのかわかりませんでした。

そこで何かのプロセスがファイルをつかんでいるだろうと調べたところ、nginxが巨大なログファイルをつかんでいました。
なぜそれがduでわからなかったかというと、実際のファイルは存在していなかったからです。
nginxの起動ユーザーはec2-userになっていたのですが、nginxはyumでインストールしたものなので、
log出力先のディレクトリのオーナーがnginxユーザーになっており、
ログがローテーとするタイミングで実ファイルへの書き込みができなくなっていて、
その存在しないファイルにずっと出力が続けられていて、ディスクを喰っていた感じです。

まずnginxのプロセスを調べました。
$ps -ef|grep nginx
root      2258     1  0  2015 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
ec2-user  2259  2258  0  2015 ?        01:06:48 nginx: worker process
ec2-user  2260  2258  0  2015 ?        01:06:14 nginx: worker process
ec2-user  4949  4810  0 22:31 pts/0    00:00:00 grep nginx

プロセスIDが2259が開いているファイルを調べたところ、deletedな巨大なaccess.logが見つかりました。
$sudo lsof -p 2259
COMMAND  PID     USER   FD   TYPE             DEVICE   SIZE/OFF   NODE NAME
nginx   2259 ec2-user    2w   REG              202,1     175662 275456 /var/log/nginx/error.log-20150528 (deleted)
nginx   2259 ec2-user    4w   REG              202,1     175662 275456 /var/log/nginx/error.log-20150528 (deleted)
nginx   2259 ec2-user    5w   REG              202,1 5977988117 275453 /var/log/nginx/access.log-20150528 (deleted)
nginxを再起動すると、diskの空きが増えて、またレスポンスが返せるようになりました。

2016年7月19日火曜日

Recommendifyを入れてみたらちょっとはまった

今更なのですがRecommendifyを試してみて、普通にgem入れようとしたら入らなかったので調べました。
試した環境はMac OSX El Capitanです。

まずは以下の2つをインストール。
brew insert redis
brew insert hiredis

次にGemfileにhiredisとrecommendifyを追加。
gem install hiredis
gem install recommendify

そしてbundle installを実行。
すると、recommendifyが入らなくてエラーになりました。
Installing recommendify 0.3.8 with native extensions

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    /Users/xxx/.rbenv/versions/2.1.3/bin/ruby extconf.rb

make "DESTDIR=" clean
rm -f *.o

make "DESTDIR="
mkdir -p ../bin
gcc -Wall recommendify.c -lhiredis -o ../bin/recommendify
recommendify.c:4:10: fatal error: 'hiredis/hiredis.h' file not found
#include 
         ^
1 error generated.
make: *** [build] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/xxx/yyy/vendor/bundle/ruby/2.1.0/gems/recommendify-0.3.8 for inspection.
Results logged to /Users/xxx/yyy/vendor/bundle/ruby/2.1.0/extensions/x86_64-darwin-14/2.1.0-static/recommendify-0.3.8/gem_make.out
An error occurred while installing recommendify (0.3.8), and Bundler cannot continue.
Make sure that `gem install recommendify -v '0.3.8'` succeeds before bundling.

調べてみたところ、recommendifyをgitからnativeブランチで取得するとよさそうです。
gem install recommendify, git: "https://github.com/danmorin/recommendify.git", branch: "native"
これで無事に入りました。

参考URL
http://blog.naberon.jp/post/2013/09/09/site-recommend/
http://d.hatena.ne.jp/itmsc/20130812/1376289715
http://qiita.com/toyama0919/items/bef2e375e9ebde9a01ba
https://github.com/paulasmuth/recommendify/issues/6

2016年7月6日水曜日

nologinのユーザーをログインできるようにする

ログインできないユーザーをログインできるようにする必要があったので調べました。
usermodでログインシェルを変更できるようです。
cat /etc/passwd | grep test
test:x:501:501::/home/test:/sbin/nologin

usermod -s /bin/bash test

cat /etc/passwd | grep test
test:x:501:501::/home/test:/bin/bash

参考URL
http://server-setting.info/centos/login_user.html

2016年7月1日金曜日

Google Maps APIでMissingKeyMapError出たので調べた

ちょっとgoogle maps apiで出力してる地図を置き換えていたら、
<script src="http://maps.google.com/maps/api/js?sensor=true"></script>
でこれまで動かしていた地図は表示されていたのですが、
<script src=”https://maps.googleapis.com/maps/api/js”></script>
を使ったら地図が表示されず、MissingKeyMapErrorがコンソールに出ていました。

google maps apiで調べてみると、呼び出してるJSにはAPIキーがパラメーターで渡せるようですが、
使い方を説明しているページの多くが、APIキーはなくても大丈夫と書いてあったので、
面倒だし取得しないでやろうとしていたら地図が表示されてません。

そして更に調べたところ、2016/06/22からAPIキーは必須になったそうです。
渋々APIキーを取得してパラメーターに入れたところ、ちゃんと地図が表示されました。
現状ではこれが正しい形なようです。(sensor=true|falseはつけなくてよいようです。)
<script src=”https://maps.googleapis.com/maps/api/js?key={APIキー}”></script>

参考URL
http://blog.cloud9works.net/web/how-to-fix-google-map-api-key-error/
https://developers.google.com/maps/documentation/javascript/error-messages#deverrorcodes

2016年6月14日火曜日

hadoop止まらないので調べた

もう使われてないhadoopが動いていて、無駄にログ吐き続けてdiskを喰っていたので
止めようとしたら止まらなかったので調べました。

とりあえず止める系のコマンドをいくつか叩いてみましたが、プロセスは残ったままでした。
$ ./sbin/stop-all.sh 
This script is Deprecated. Instead use stop-dfs.sh and stop-yarn.sh
16/06/13 11:18:15 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Stopping namenodes on [ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com]
ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com: no namenode to stop
localhost: no datanode to stop
Stopping secondary namenodes [0.0.0.0]
0.0.0.0: no secondarynamenode to stop
16/06/13 11:18:19 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
stopping yarn daemons
no resourcemanager to stop
localhost: no nodemanager to stop
no proxyserver to stop

$ ./sbin/stop-dfs.sh 
16/06/13 11:17:41 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Stopping namenodes on [ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com]
ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com: no namenode to stop
localhost: no datanode to stop
Stopping secondary namenodes [0.0.0.0]
0.0.0.0: no secondarynamenode to stop
16/06/13 11:17:46 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

$ ./sbin/stop-yarn.sh 
stopping yarn daemons
no resourcemanager to stop
localhost: no nodemanager to stop
no proxyserver to stop


 ./sbin/hadoop-daemon.sh stop tasktracker
no tasktracker to stop

$ ./sbin/hadoop-daemon.sh stop datanode
no datanode to stop

そこで調べてみたところ、どうやらPIDファイルがなくなってるのが原因っぽいです。
configファイルのPIDまわりの記述を調べてみました。
$ grep PID_DIR etc/hadoop/*
etc/hadoop/hadoop-env.cmd:set HADOOP_PID_DIR=%HADOOP_PID_DIR%
etc/hadoop/hadoop-env.cmd:set HADOOP_SECURE_DN_PID_DIR=%HADOOP_PID_DIR%
etc/hadoop/hadoop-env.sh:export HADOOP_PID_DIR=${HADOOP_PID_DIR}
etc/hadoop/hadoop-env.sh:export HADOOP_SECURE_DN_PID_DIR=${HADOOP_PID_DIR}
etc/hadoop/mapred-env.sh:#export HADOOP_MAPRED_PID_DIR= # The pid files are stored. /tmp by default.
PIDファイルの置き場はデフォルトの/tmpっぽくて、
すでに長期間運用したこのhadoopはtmpwatchですでにpidファイルが削除されているようで、
もうkillするしかなさそうです。ということでkillして停止しました。。。


参考URL
http://masa-cbl.hatenadiary.jp/entry/20121018/1350576124