ホーム ブログ ページ 41

Amazon RDS for MySQL でフルアクセス権限を持つユーザーを作成する

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

データベースにアクセスするユーザーを作成する場合、本来であればアクセス可能なデータベースや権限を細かく設定すべきですが、稀にフルアクセス権限を持つユーザーを作成したい場合もあると思います。

MySQLであれば

GRANT ALL ON *.* TO user@'localhost' IDENTIFIED BY 'パスワード';

とすることでフルアクセス可能なユーザーを作成することができますが、同コマンドをAmazon RDS for MySQLで実行すると

ERROR 1045 (28000): Access denied for user 'root_account'@'%' (using password: YES)

というような権限エラーが発生します。

このような場合は

GRANT ALL ON `%`.* TO user@'localhost' IDENTIFIED BY 'パスワード';

というように、 `%` で対象となるデータベースを指定することでフルアクセス可能なユーザーを作成することができます。

CVE-2015-7547のglibcライブラリの脆弱性について、CentOS系での修正済みバージョンの確認と適用方法について

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。アピリッツの本多です。

本日2016年02月17日、glibcライブラリの脆弱性の記事が掲載されました。

脆弱性の詳細につきましては以下の記事をご確認頂くとして、本ページでは修正後のglibcのバージョンと、適用方法に情報を絞ってご紹介したいと思います。

Google Online Security Blog: CVE-2015-7547: glibc getaddrinfo stack-based buffer overflow

https://googleonlinesecurity.blogspot.jp/2016/02/cve-2015-7547-glibc-getaddrinfo-stack.html

各CentOSでの修正後のglibcのバージョン情報

OS対応の有無修正後のバージョン
CentOS5系不要
CentOS6系必要2.12-1.166.el6_7.7
CentOS7系必要2.17-106.el7_2.4

情報元:

CVE-2015-7547 – Red Hat Customer Portal

Red Hat Customer Portal

Red Hat Customer Portal

glibcのアップデート手順

rootユーザーにて以下のコマンドを実行します。

# yum clean all

# yum update glibc

アップデート完了後はシステムの再起動を行ってください。

CentOS7系では、以下のコマンドを叩く事で、再起動せずとも更新されたglibcを適用する事が出来るそうです。

# systemctl daemon-reexec

情報元:

Critical glibc buffer overflow vulnerability in getaddrinfo() on Linux (CVE-2015-7547 & CVE-2015-5229)

おまけですが、Amazon Linuxの場合のglibcの情報も記載しておきます。

修正後のバージョン
2.17-106.166.amzn1

更新方法は上のやり方と同じですので、早急の対応を行いましょう。

情報元:

https://alas.aws.amazon.com/ALAS-2016-653.html (SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: sslv3 alert handshake failure)

rubyistのためのscala (3) クラスとオブジェクト指向

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


Rubyで書くあれはScalaだとどう書くの?シリーズ。 今回はクラスとオブジェクト指向について。

クラス

クラスの宣言と継承

Ruby

class Foo < Bar
end

Scala

class Foo extends Bar {
}

コンストラクタ

Rubyではinitializeという名前のメソッドを定義する。

class Foo
  def def initialize(bar)
    # new した時点でここが実行される
  end
end

Scalaにはコンストラクタを複数定義できるが、ここではデフォルトのコンストラクタについて説明する。

デフォルトのコンストラクタはクラス定義のブラケット内にそのまま記述できる。
引数はクラス名の後ろのカッコ内に書く。

class Foo(bar: Int) {
  // new した時点でここが実行される
}

モジュール

Ruby

module Foo
  def bar
  end
end

Scala

trait Foo {
  def bar: Unit = {
  }
}

barというメソッドを持つtrait Fooを定義することができる。

Mixin

Scalaではtraitを継承することでmixinを行う。

Ruby

module Bar
end

class Foo
  include Bar
end

Scala

trait Bar {
}

class Foo extends Bar {
}

ひとつのクラスが複数のtraitをmixinする場合、二つ目以降は with というキーワードを使う。

Scala

class Foo extends Bar with Baz with Hoge {
}

TODO: prependusingについても調べて書く

名前空間

Rubyではモジュールを名前空間として使うことができる。

Ruby

module Foo
  module Bar
    class Baz
    end
  end
end

baz = Foo::Bar::Baz.new

Scalaではパッケージのほか、シングルトンオブジェクトも名前空間として使うことができる。

Scala

package foo
object Bar {
  class Baz {
  }
}

val baz = new foo.Bar.Baz()

TODO: import について書く

メソッド

キーワードは同じ def
引数と返り値の型を指定する。

Ruby

class Foo
  def bar(a, b)
    a + b
  end
end

Scala

class Foo {
  def bar(a: Int, b: Int): Int = {
    a + b
  }
}

プロパティとアクセサ

デフォルトのゲッター、セッター

Ruby

class Foo
  attr_accessor :bar, :baz
  def initialize(bar, baz)
    @bar = bar
    @baz = baz
  end
end

foo = Foo.new(1, "abc")
foo.bar  # => 1
foo.baz  # => "abc"

Scala

class Foo(var bar: Int, var baz: String) {
}

val foo = new Foo(1, "abc")
foo.bar  // => 1
foo.baz  // => "abc"

セッターの実装

Ruby

class Foo
  attr_reader :bar
  def bar=(i)
    @bar = i
  end
end

foo = Foo.new
foo.bar = 1
foo.bar  # => 1

Scala

class Foo {
  private var _bar: Int = _
  def bar = _bar
  def bar_=(i: Int): Unit = this._bar = i
}

val foo = new Foo()
foo.bar = 1
foo.bar  // => 1

Scalaのセッターメソッドは def 変数名_=(引数): Unit = ??? という形で定義する。

演算子メソッド

Rubyでメソッドとして再定義可能な演算子

|  ^  &  <=>  ==  ===  =~  >   >=  <   <=   <<  >>
 +  -  *  /    %   **   ~   +@  -@  []  []=  ` ! != !~

Scalaで再定義できない予約語、キーワード
FAQ How do I find what some symbol means or does?より引用)
(これ以外の記号、英数字は使えるらしい)

// Keywords
<-  // Used on for-comprehensions, to separate pattern from generator
=>  // Used for function types, function literals and import renaming
// Reserved
( )        // Delimit expressions and parameters
[ ]        // Delimit type parameters
{ }        // Delimit blocks
.          // Method call and path separator
// /* */   // Comments
#          // Used in type notations
:          // Type ascription or context bounds
<: >: <%   // Upper, lower and view bounds
" """      // Strings
'          // Indicate symbols and characters
@          // Annotations and variable binding on pattern matching
`          // Denote constant or enable arbitrary identifiers
,          // Parameter separator
;          // Statement separator
_*         // vararg expansion
_          // Many different meanings

どちらも記号を名前としたメソッドを定義することで演算子を定義できる。

class Foo
  def +(other)
    "add method"
  end
end

foo1 = Foo.new
foo2 = Foo.new
foo1 + foo2  # "add method"
class Foo {
  def +(other: Foo): String = "add method"
}

val foo1 = new Foo
val foo2 = new Foo
foo1 + foo2  // "add method"

引数のデフォルト値

Ruby

class Foo
  def bar(baz = 1)
    baz
  end
end

foo = Foo.new
foo.bar()  # => 1
foo.bar(2)  # => 2

Scala

class Foo {
  def bar(baz: Int = 1): Int = {
    baz
  }
}

val foo = new Foo()
foo.bar()  // => 1
foo.bar(2)  // => 2

可変長引数

Rubyでは定義するときも呼び出すときも * という記号をまえにつける。

class Foo
  def bar(baz, *hoge)
    # 2つめ以降の引数はhogeに配列として入る
  end
end

foo = Foo.new
baz = 1
hoge = ["foo", "bar"]
foo.bar(baz, *hoge)

Scalaでは定義するときは *をうしろにつけ、呼び出すときは :_* という記号をうしろにつける。

class Foo {
  def bar(baz: Int, bar: String*): Unit = {
    // 2つめ以降の引数は bar にSeqとして入る
  }
}

val foo = new Foo
val baz = 1
val hoge = Seq("foo", "bar")
foo.bar(baz, hoge:_*)

※読みやすいレイアウトでまとめましたサイトを作りましたので、こちらもご参照ください。
http://kkismd.github.io/rb2scala/

rubyistのためのscala (1) 値と式

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


Rubyで書くあれはScalaだとどう書くの?シリーズ。 今回は値や式についてまとめてみました。

数値

種類RubyScala備考
整数123123 2147483647L整数は32bit(Int),64bit(Long)の2種類がある
実数123.45123.45 123. 123.45d 123.45f実数はDoubleとFloat
浮動小数1.2e-31.2e-3
16進整数0xffff0xffff
8進数0377ゼロから始める8進数表記はScala 2.11から非推奨
2進整数0b10112進数のリテラルなし
桁区切り文字1_000_000_000桁区切り文字はなし

文字列

種類RubyScala備考
ダブルクォート"this is a string expression\n""this is a string expression\n"
シングルクォート'this is a string expression''a'シングルクォートはChar型を表すため文字列には使えない
シンボル:aaa'aaa
ヒアドキュメント<"""foo bar baz """改行を含む文字列はダブルクォートを3つ重ねる(Raw String)。バックスラッシュによるエスケープが効かない。
式埋め込み"foo #{1 + 2} baz"s"foo ${1 + 2} baz"ダブルクォートの前に小文字のs (interpolator) を置く
フォーマットsprintf("foo %d baz", 123) "foo %d baz" % [123]"foo %d baz".format(123)

変数

種類RubyScala備考
変数a = 123var a = 123
定数A = 123val a = 123変数をvalで宣言すると再代入がコンパイルエラーになる(Rubyの定数より厳格)

演算子

ScalaもRubyと同じように演算子の一部がメソッドのシンタックスシュガーとして定義されている。

1 + 2 は 1.+(2) のシンタックスシュガー

種類RubyScala備考
代入foo = barfoo = bar再代入が必要な時はvarで宣言する
配列参照array[1]array(1)カッコによる配列参照はメソッド呼び出し .apply(n) のシンタックスシュガー
属性参照foo.barfoo.bar引数なしのメソッドをカッコ省略できる
自己代入foo += 1foo += 1再代入があるのでvar変数として宣言が必要
多重代入foo, bar, baz = 1, 2, 3 foo, bar, baz = [1, 2, 3](foo, bar, baz) = (1, 2, 3) Array(foo, bar, baz) = Array(1, 2, 3)多重代入はパターンマッチのシンタックスシュガー
範囲式1 .. 201 to 20 1.to(20)整数クラスの .to() メソッドを使う。引数が1つしかないメソッドはドットやカッコを省略できる。
アンド条件foo && bar foo and barfoo && bar演算子 and は使えない
オア条件foo || bar foo or barfoo || bar演算子 or は使えない
否定!foo not foo!foo演算子notは使えない
3項演算子obj == 1 ? foo : barif (obj == 1) foo else bar3項演算子がないのでif式を使う

※読みやすいレイアウトでまとめましたサイトを作りましたので、こちらもご参照ください。
http://kkismd.github.io/rb2scala/

rubyistのためのscala (2) 制御構造

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


Rubyで書くあれはScalaだとどう書くの?シリーズ。 今回は制御構造です。

if-then-else

Ruby

if a = b
  "equal!"
else
  "not equal!"
end

Scala

if (a == b) {
  "equal!"
}
else {
  "not equal!"
}

Scalaでもifは式であり、値を返すことができる。 後置式はない。

unless

Ruby

unless foo?
  "not foo"
else
  "foo"
end

Scala

if (!isFoo)
  "not foo"
else
  "foo"

Scalaにunlessはない。

case

Ruby

case hoge
when 1
  "one"
when 2, 3
  "two or three"
end

Scala

hoge match {
  case 1 =>
    "foo"
  case 2|3 =>
    "two or three"
}

Rubyのcase式もScalaのmatch式もどちらも強力だがここでは最も基本的な形を挙げている。

繰り返し

whileループ

Ruby

while true
  puts("Hello")
end

Scala

while (true) {
  println("Hello")
}

untilループ

Ruby

until f.eof?
  print f.gets
end

Scala

while (!f.isEof) {
  println(f.getLine)
}

untilはない。

forループ

Ruby

for i in [1,2,3]
  print i * 2, "\n"
end

Scala

for (i <- Seq(1,2,3)) {
  println(i * 2)
}

Scalaのfor式はもっと多機能だがここでは基本的な形を挙げている。

break

Ruby

i = 0
while true
  puts i
  i += 1
  if i > 10
    break
  end
end

Scala

import scala.util.control.Breaks
val breaks = new Breaks
var i = 0
breaks.breakable {
 while (true) {
   println(i)
   i += 1
   if (i > 10) breaks.break()
 }
}

ループのブレイクが構文として用意されていないので、標準ライブラリの Breaks を使う必要がある。

next, redo, retry

Ruby

lines.each do |line|
  next if line.blank?
  puts line
end

Scala

lines.foreach { line =>
  if (!line.isEmpty) {
    println(line)
  }
}

next, redo, retryなどの構文はないのでifなどを使って実装する必要がある。

例外処理

例外の送出

Ruby

raise StandardError.new("例外が起きました")

Scala

throw new RuntimeException("例外が起きました")

例外の捕捉

Ruby

begin
  do_something
rescue ZeroDivisionError => e
  recover(e)
ensure
  must_to_do
end

Scala

try {
  doSomething
}
catch {
  case e: ArithmeticException =>
    recover(e)
}
finally {
  mustToDo
}

return

Ruby

return 1

Scala

return 1

returnはほぼ同じ。 関数やメソッド、ブロックの最後のretrunを省略すると、Rubyと同じように最後に評価された値を返す。

※読みやすいレイアウトでまとめましたサイトを作りましたので、こちらもご参照ください。
http://kkismd.github.io/rb2scala/

重いeclipseを早くするには?試した8つの方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

たまごです。

業務でSTSを使ったのですが、激重で心がくじけそうになりました。eclipseを軽くする小技は色々ありますが、今日は備忘も兼ねて、自分の試した小技をまとめていきたいと思います。

 コンテンツアシストを早くする

Window>Preferences>Java>Editor>Content Assist

↑上記のAuto activation delayを80くらいにする。(僕は60にしています)

これでかなり挙動のもっさり感が改善。

 テーマをクラシックにする

Window>Preferences>General>Appearance

↑上記のThemeをClassicに変更。

 アニメーションを禁止する

Window>Preferences>General>Appearance

↑上記のEnable animationsを非選択に。

 パースペクティブをカスタマイズする

Window>Customize Perspective>Tool Bar Visibility

↑上記で、不要なツールバーを非表示にする。(僕はhelp以外は全部チェック外してます)

 Tomcatのホットデプロイを無効化する

Serversタブ>Tomcat>Overview>Publishing

↑上記で、Never publishing automaticallyを選択。

 プロパティエディタからSimplePropertyEditorに変えてみる

こっちの方が軽いらしいです。

 iniファイルのメモリ設定を変えてみる

  • Xms2048m
  • Xmx2048m
  • XX:MaxPermSize=512m

こんなかんじにしてみる。数字はテキトーなので、最適かどうかは不明です。

 こまめにrun garbage collectorしてみる

Window>Preferences>General

↑上記で、Show heap statusにチェック。

すると、heap statusと共にバケツアイコンが表示されるようになるので、こいつをクリックしてこまめにrun garbage collectorする。(ただし、よく忘れる)

ruby-opencvのインストール

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

RubyでOpenCVを使ってみたくて
gemのruby-opencvを入れてみました。

OpenCVは画像処理や画像解析ができるオープンソースのライブラリです。

http://opencv.org/http://opencv.jp/

画像の顔認識や、
動画中の特定条件に合致したコマのみキャプチャするとか
そういうことができます。
機械学習機能があるので、
学習させれば、好みの顔が写ってる画像だけ拾って来る
みたいなこともできるようです。(難しいようですが)

RubyはOpenCV公式の対象言語ではないとのことですが、
問題なく使えるとのこと。
gemもあって、わりとメジャーなようだったので
インストールしてみました。

https://github.com/ruby-opencv/ruby-opencvhttp://www.rubydoc.info/gems/ruby-opencv/frames

なかなか依存関係のバージョンが合わず一苦労だったので
以下手順メモ。・環境・OpenCVインストール

  1. ライブラリをいろいろインストール
  2. yasm のインストール
  3. x264 のインストール
  4. fdk-aac のインストール
  5. ライブラリ設定
  6. ffmpeg1.2 のインストール
  7. opencv-2.4.6.1 のインストール

・ruby-opencvインストール

■ 環境

  • CentOS6.7
  • Ruby 2.1.7(rbenv)
  • Rails 4.1.6(rbenv)

■ OpenCVインストール

1. ライブラリをいろいろインストール

# yum --setopt=group_package_types=optional groupinstall Base
# yum groupinstall "Development Tools"
# yum install http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm

# vi /etc/yum.repos.d/rpmforge.repo
※enabled=0にする

# yum -y install gtk2-devel
# yum install expat-devel
# yum install libarchive libarchive-devel
# yum install libcurl3 ※ない
# yum install qt qt-devel

# yum install gtk*
# yum install cmake28

# yum install autoconf automake make gcc gcc-c++ pkgconfig wget libtool zlib-devel
# yum install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
※enabled=0にする

2. yasm のインストール(x264 のビルドに必要)

# cd /usr/local/src
# wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
# tar zvxf yasm-1.3.0.tar.gz 
# cd yasm-1.3.0
# ./configure
# make
# make install

3. x264 のインストール(ffmpeg のビルドに必要)

# cd /usr/local/src
# git clone git://git.videolan.org/x264
# cd x264
# ./configure --enable-shared
# make
# make install

4. fdk-aac のインストール

# cd /usr/local/src
# git clone --depth 1 git://github.com/mstorsjo/fdk-aac.git
# cd fdk-aac
# autoreconf -fiv
# ./configure
# make
# make install

5. ライブラリ設定

# export LD_LIBRARY_PATH=/usr/local/lib/
# export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig"
# echo /usr/local/lib > /etc/ld.so.conf.d/custom-libs.conf
# ldconfig

6. ffmpeg1.2 のインストール

# cd /usr/local/src
# git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
# cd ffmpeg
# git checkout -b release1.2 origin/release/1.2
# ./configure --enable-gpl --enable-nonfree --enable-libfdk_aac --enable-libx264 --enable-shared
# make
# make install

# yum --enablerepo=rpmforge install ffmpeg-devel

バージョン確認

# ffmpeg -version

7. opencv-2.4.6.1 のインストール

# cd /usr/local/src
# wget ftp://ftp.jp.netbsd.org/pub/pkgsrc/distfiles/opencv-2.4.6.1.tar.gz
# tar vxzf opencv-2.4.6.1.tar.gz
# cd opencv-2.4.6.1
# cmake28 .
# make
# make install
# ldconfig

バージョン確認

# cat /usr/local/share/OpenCV/OpenCVConfig-version.cmake

■ ruby-opencvインストール

$ vi Gemfile

以下を追記
--------------------
gem 'ruby-opencv'
--------------------

$ bundle update

インストール完了です。

以下は失敗例

・opencv-2.4.11入れた時のエラー

/usr/local/src/opencv-2.4.11/modules/highgui/src/ffmpeg_codecs.hpp:104: error: ‘CODEC_ID_H264’ was not declared in this scope

コーデック関連のライブラリでエラーがたくさんでる。。

http://code.opencv.org/issues/3986OpenCV3.0RC1で解決されたらしいですが、ruby-opencvはOpenCV3.*に対応してないのでバージョンは上げられず。

https://github.com/Itseez/opencv/issues/4940OpenCV2.4.9、2.4.10でも同様のエラーがでるぽいです。OpenCV2.4.8も別のエラーがでて結局だめでした。

とりあえず試してみる分には問題ないので
2.4.6.1でよしとしました。

bashプロンプトのカスタマイズ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

bashのプロンプトが突然「-bash-4.1$」のようになってしまって
直した時に調べたメモです。

いつもは「[hoge@localhost ~]$」のように
[ユーザ名@ホスト名 カレントディレクトリ]$
の形で表示されていたのが、
突然「-bash-4.1$」となってしまいました。

何かのタイミングでデフォルト設定に戻ってしまったようです。

・フォーマットの設定
・色の設定

■ フォーマットの設定

bashのプロンプトはPS1でフォーマットを設定できます。
デフォルトは¥s-¥v¥$です。

[hoge@localhost ~]$export PS1="\s-\v\$"
-bash-4.1$

-bash-4.1$

むむ。どうも落ち着つきません。

なので、いつもどおり
[ユーザ名@ホスト名 カレントディレクトリ]$
のフォーマットで表示されるよう設定し直します。

[\u@\h \W]\$

これを設定する。

-bash-4.1$export PS1="[\u@\h \W]\$"
[hoge@localhost ~]$

直りました。
これを「/etc/profile」や「~/.bashrc」に追記しておけばOKです。

他にも設定できるフォーマットがいろいろあって、
man bashで確認できます。

PROMPTING
       When  executing  interactively, bash displays the primary prompt PS1 when it is ready to read a command, and the secondary prompt PS2 when it needs more input to complete a command.  Bash allows these prompt strings to
       be customized by inserting a number of backslash-escaped special characters that are decoded as follows:
              \a     an ASCII bell character (07)
              \d     the date in "Weekday Month Date" format (e.g., "Tue May 26")
              \D{format}
                     the format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation.  The braces are required
              \e     an ASCII escape character (033)
              \h     the hostname up to the first ‘.’
              \H     the hostname
              \j     the number of jobs currently managed by the shell
              \l     the basename of the shell’s terminal device name
              \n     newline
              \r     carriage return
              \s     the name of the shell, the basename of $0 (the portion following the final slash)
              \t     the current time in 24-hour HH:MM:SS format
              \T     the current time in 12-hour HH:MM:SS format
              \@     the current time in 12-hour am/pm format
              \A     the current time in 24-hour HH:MM format
              \u     the username of the current user
              \v     the version of bash (e.g., 2.00)
              \V     the release of bash, version + patch level (e.g., 2.00.0)
              \w     the current working directory, with $HOME abbreviated with a tilde (uses the value of the PROMPT_DIRTRIM variable)
              \W     the basename of the current working directory, with $HOME abbreviated with a tilde
              \!     the history number of this command
              \#     the command number of this command
              \$     if the effective UID is 0, a #, otherwise a $
              \nnn   the character corresponding to the octal number nnn
              \\     a backslash
              \[     begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
              \]     end a sequence of non-printing characters

■ 色の設定

サーバ毎にプロンプトの色を変えておけば
どのサーバにログインしているのかわかりやすくなります。

・文字色をシアンに変える例

$ export PS1=”¥[¥e[0;36m¥][¥u@¥h ¥W]¥$¥[¥e[0m¥]”

¥[¥e[0;36m¥]~¥[¥e[0m¥]で挟まれた部分が「0;36」で指定された装飾/色になります。

この形式はANSIエスケープシーケンスというそうです。

0;36をもっと詳しく説明すると、
0と36の2つの装飾指定がされていて、

0→文字装飾なし
36→文字色をシアンにする

という意味になります。
これにさらに背景色を青にしたい、となると0;36;44となって、0と36と44の3つの装飾指定をする
という意味になります。

0→文字装飾なし
36→文字色をシアンにする
44→背景色を青にする

\[\e[0;36;44m\][\u@\h \W]\\$\[\e[0m\]

なので、最初に「¥[¥e[0;36m¥]~¥[¥e[0m¥]」挟まれた部分が…
とは言いましたが、本来は、¥[¥e[0;36m¥]以降 を「装飾無し&文字色シアン」で表示する
¥[¥e[0m¥]以降 を「装飾なし」で表示するという意味になるようです。

もっと他の装飾指定を追加することも可能です。

↓こちらのページでとてもわかりやすく説明されていました。
http://oxynotes.com/?p=5418

とりあえず↓のように設定。

$ export PS1="\[\e[0;36m\][\u@\h \W]\\$\[\e[0m\]"

これでどのターミナル開いてるか分かりやすくなりました。

FullCalendarで営業日カレンダーを作成する(小さいカレンダー)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

営業日カレンダーを作成したくて、FullCalendarのオプションを色々いじって実装しました。

バージョン:fullcalendar-2.4.0

js

$(document).ready(function() {

	$('#calendar').fullCalendar({
		header: {
			left: 'prev,next today',
			center: 'title',
			right: ''
		},
		buttonText: {
			today: '今日'
		},
		dayNamesShort: ['日','月','火','水','木','金','土'],
		defaultDate: '2016-02-03',
		businessHours: false,
		titleFormat: {
			month: 'MMM YYYY'
		},
		// 表示用データ
		events: [
			{
				start: '2016-02-09',
				rendering: 'background',
				color: '#ff9f89'
			},
			{
				start: '2016-02-06',
				end: '2016-02-08',
				rendering: 'background',
				color: '#ff9f89'
			},
			{
				start: '2016-02-13',
				end: '2016-02-15',
				rendering: 'background',
				color: '#ff9f89'
			},
			{
				start: '2016-02-20',
				end: '2016-02-22',
				rendering: 'background',
				color: '#ff9f89'
			},
			{
				start: '2016-02-27',
				end: '2016-02-29',
				rendering: 'background',
				color: '#ff9f89'
			},
		]
	});
});

eventsのデータの中で、

dayNamesShort: [‘日’,’月’,’火’,’水’,’木’,’金’,’土’]で曜日の表示を1文字にします。

rendering: ‘background’を指定することにより、そのイベントの日が背景色の表示になります。

color: ‘#ff9f89’を指定することにより、休日っぽい色にしています。

businessHours: falseで土日の背景色を無効にしています。

実際はevents部分のデータはjsonでサーバから取得していたのですが、今回は表示のテスト用にjsの中に記述しています。

css

body {
	margin: 40px 10px;
	padding: 0;
	font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
	font-size: 14px;
}

#calendar {
	max-width: 220px;
	margin: 0 auto;
}

max-width: 220px;でカレンダーのサイズを指定します。

また、デフォルトのままだとスクロールバーが出たりするので、微調整します。

css続き

.fc-basic-view .fc-body .fc-row {
	min-height: 1em !important;
}

.fc button {
	height: 2em !important;
	padding: 0 .1em !important;

	/* text & cursor */
	font-size: 0.8em !important;
}

jsのオプションでセルの高さを指定する方法がわからなかった(小さくできなかった)ので、fullcalendar.cssのスタイルを一部上書きしています。

これで冒頭の営業日カレンダーを作成することができました。

irb 上で using の動作を試したときのメモ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

インスタンスメソッドを特定の場面のみ変更したい場合に using と refine を使う方法があります。irb 上でなかなか思った通りに動かなかったのでメモしておきます。

 参考 (instance method Module#refine)

http://docs.ruby-lang.org/ja/2.0.0/method/Module/i/refine.html

 環境

OS (sw_vers ; uname -a)

ProductName: Mac OS X

ProductVersion: 10.11.3

BuildVersion: 15D21

Darwin pomme.local 15.3.0 Darwin Kernel Version 15.3.0: Thu Dec 10 18:40:58 PST 2015; root:xnu-3248.30.4~1/RELEASE_X86_64 x86_64

ruby (ruby -v; irb -v ; pry -v)

ruby 2.1.9p441 (2015-12-23 revision 53262) [x86_64-darwin15.0]

irb 0.9.6(09/06/30)

Pry version 0.10.3 on Ruby 2.1.9

 使ってみました。

変更されるクラス (Enterprise) の定義

pomme:~ kadosaway$ pry
	[1] pry(main)> class Enterprise
	[1] pry(main)* def earn
	[1] pry(main)* puts "much!"
	[1] pry(main)* end
	[1] pry(main)* end
	=> :earn

変更を加えるモジュール (Strategist) の定義

[2] pry(main)> module Strategist
	[2] pry(main)* refine Enterprise do
	[2] pry(main)* def earn
	[2] pry(main)* puts 'more!!!'
	[2] pry(main)* end
	[2] pry(main)* end
	[2] pry(main)* end
	=> #<refinement:enterprise @strategist>

変更前の動作確認

[3] pry(main)> prj = Enterprise.new
	=> #<enterprise:0x007fc5788456d0>
	[4] pry(main)> prj.earn
	much!
	=> nil

変更を using によって適用しての動作確認のつもり

[5] pry(main)> using Strategist
	=> main
	[6] pry(main)> prj = Enterprise.new
	=> #<enterprise:0x007fc57909ca90>
	[7] pry(main)> prj.earn
	much!
	=> nil

irb (pry)上では期待した通りにならない!?

命令を1行にして実行してみると

[8] pry(main)> using Strategist; prj = Enterprise.new; prj.earn
	more!!!
	=> nil

期待通りになりました。

同じメソッドを再度呼んでみると

[9] pry(main)> prj.earn
	much!
	=> nil

変更が解除されている。

試しに

[10] pry(main)> using Strategist; prj.earn; prj.earn
	more!!!
	more!!!
	=> nil
	[11] pry(main)> using Strategist; prj.earn; \
	[11] pry(main)* prj.earn
	more!!!
	more!!!
	=> nil
	[12] pry(main)> prj.earn; prj.earn; using Strategist; prj.earn
	much!
	much!
	more!!!
	=> nil

using を使用後に同行にて変更が反映される様でした。

arel_tableを使った時のメモ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

日々の気温差に体がついて行っていない気がする中西です。

少し前にarel_tableを使用したので、簡単な使い方等をメモしてみます。

複雑なSQL文

スコープなどを書こうと思った場合に、条件がすこし難しい場合があります。

そういった時に、生のSQL文を使用することもあると思います。

少し前に、下記のようなスコープを書いたとこがありました。

scope :except_codes, -> { where.not('(test_code = 0 OR test_code IS NULL) AND code_created_at IS NULL') }

生のSQL文をを用いています。

そのとき、先輩からarel_tableの話を聞き使ってみることにしました。

使ってみた結果が、下記になります。

scope :except_codes, -> { where.not(arel_table[:test_code].eq_any([0, nil]).and(arel_table[:code_created_at].eq(nil))) }

今回は、短いSQL文ですが、長いSQL文になった場合、生のSQL文では後々わかりずらくなってしまう恐れがあります。

そういった場合に、arel_tableを使うことで後々理解がしやすくなると思われます。

arel_tableの使い方

今回上記で使用した部分について簡単にメモします。

まず、下記部分で使用するカラム名を指定しています。

arel_table[:test_code]
arel_table[:code_created_at]

このあとに、条件を追加します。

それぞれ、今回使用している部分は下記のような意味となります。

eq_any(○) :○以外の場合(≠)
eq(○)   :○の場合(=)

○の部分が複数ある場合、配列として入力することで複数の値を条件にできます。

a.eq([0, 1]) :aが「0」か「1」の場合

複数の条件を組み合わせたい場合には、andやorを用いることができます。

こうすることで、複雑な条件文の場合にも比較的簡単に書くことができます。

まとめ

今回は実際に自分が使用した、簡単な部分についてメモしてみました。

このほかにも、likeやorder等も簡単に書けるようです。

気になる方が、調べてみてください。

追記(2016/2/2)

ちょっと指摘があったので追記。

今回紹介しているarel_tableは、Rails用の非公開APIなので、使用する場合は、それを念頭に置き、注意してください。

CarrierWave使用時のTips

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Railsに画像等のファイルをアップロードする機能を実装するgem「CarrierWave」を使用する際のTipsを纏める。

Railsに画像等のファイルをアップロードする機能を実装するgem「CarrierWave」を使用する際のTipsを纏める。

 話の前提

テーブル「users」にフィールド「picture_url」があるという前提。

(picture_urlにはアップロードするファイルのURLが格納される。)

 モデルに関するTip

acts_as_paranoid を併用する場合の注意点

Railsに論理削除を実装できるgem「acts_as_paranoid」を導入しているモデルにCarrierWaveを使用する場合は、skip_callback を設定する必要がある。

class User < ActiveRecord::Base
  acts_as_paranoid
  mount_uploader :picture_url, ImageUploader
  skip_callback :commit, :after, :remove_picture_url!
end

※skip_callbackがないと、データベースが更新された後、画像が削除されてしまう。

 コントローラに関するTip

確認画面が存在する場合の工夫

確認画面がなく、1クリックで更新する様なシステムの場合は非常に単純(編集画面→更新)。

# データベースの更新を行い、指定のディレクトリにファイルを配置する。
@user.save!

しかし、確認画面がある場合は、少し複雑になる(編集画面→確認画面→更新)。

確認画面がある場合は、暗黙的に以下を満足する必要がある事が恐らく一般的である。

  1. 確認画面にファイルを表示する(画像の場合)。
  2. 確認画面を表示しただけでは、データベース更新も格納ファイルの変更もしない。

CarrierWaveでは、通常のアップロード(save)以外に、一時的なアップロードを行う事ができるので、その機能を活用する。

※一時的アップロードでは、データベースは更新されず、指定のディレクトリとは別の一時ディレクトリにファイルがキャッシュとして保存される。

確認時のアクション
# 一時的アップロード(@userインスタンスには一時ディレクトリのパスが入る)
@user.picture_url.cache!
確認画面のビュー
<%# 一時ディレクトリの場所にある画像を表示 %>
<%= image_tag(@user.picture_url.url) %>

<%# キャッシュ名(一時ディレクトリの名前)をhiddenで渡す %>
<%= hidden_field_tag :"cache[picture_url]", @user.picture_url.cache_name %>

※アップロードファイルのフィールドが1つの場合はパラメータ名は”cache_picture_url”等でも良いが、この例では複数フィールドがある場合にも対応できる様に配列にしている。

更新時のアクション
# パラメータで受け取ったキャッシュから画像を復元する
@user.picture_url.retrieve_from_cache! params[:cache][:picture_url]
@user.save!

 ビューに関するTip

form_for, form_tag 使用時の注意点

form_for, form_tagを使用する場合はmutipartオプションが必要である。

<%= form_for(@user, html: { multipart: true }) do |f| %>

【Java】Bean Validationで条件付きチェック

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Javaで条件付きチェックを実装するにあたり、Bean Validationのバリデーショングループを使ってみました。

※Spring Frameworkを使用しています。

 【グループ】

検証グループのインターフェースを作ります。

public interface Role {
	interface Admin {}
	interface General {}
}

 【Bean】

チェック対象のフィールドにグループを指定します。

public class ValidationTestBean {

	private String role;

	@NotEmpty(groups = Admin.class)
	@Size(min = 1, max = 30, groups = General.class)
	private String name;
	
	// getter,setter省略
}

 【コントローラ】

コントローラからバリデータを呼び出します。

@Controller
@RequestMapping({ "/validation/test" })
public class ValidationTestController {

	@Autowired
	private Validator validator;

	@RequestMapping(value = "confirm", method = GET)
	public String confirm(@ModelAttribute("bean") ValidationTestBean bean,
			Errors errors, Model model) {

		// 検証グループ生成
		Object[] groups = createValidationGroups(bean);

		// 入力チェック
		ValidationUtils.invokeValidator(validator, bean, errors, groups);
		if (errors.hasErrors()) {
			return "validation/test/input";
		}
		return "validation/test/confirm";
	}

	private Object[] createValidationGroups(ValidationTestBean bean) {

		List<object> groups = new ArrayList<object>();

		// 条件によりグループを追加
		if ("admin".equals(bean.getRole())) {
			groups.add(Admin.class);
		} else {
			groups.add(General.class);
		}
		return groups.toArray();
	}
}

createValidationGroupsメソッドでグループを追加しています。

このとき、条件により異なるグループを設定することにより、Beanで指定したグループのみバリデーションを実行することができます。

今回割愛しましたが、グループは省略したり複数指定したりも可能です。

グループを活用することにより条件付きチェックをできるだけアノテーションで実装することができました。

RailsでMySQLに格納できない文字が入力された場合の対処法方の検討

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

RailsでMySQLに格納できない文字が入力された場合の対処法方の検討しました

 テーブル例

FieldType
idint(11)
hogevarchar(255)

 エラーの出る文字の一例(本文中に記載すると投稿できないため外部サイト参照)

 実行例

ユーザが自由に文字列を入力できる場合、MySQLに格納できない文字が入力される可能性がある。

> t = Hoge.new(hoge: "<エラーの出る文字>")
=> #<hoge id: nil, hoge: "<エラーの出る文字>">
> t.save!
(0.6ms)  BEGIN
SQL (0.3ms)  INSERT INTO `hoges` (`hoge`) VALUES ('<エラーの出る文字>')
Mysql2::Error: Incorrect string value: '\xF0\xA8\xBC\xB2' for column 'hoge' 
at row 1: INSERT INTO `hoges` (`hoge`) VALUES ('<エラーの出る文字>')
(0.1ms)  ROLLBACK
ActiveRecord::StatementInvalid: Mysql2::Error: Incorrect string value: 
'\xF0\xA8\xBC\xB2' for column 'hoge' at row 1: INSERT INTO `hoges` (`hoge`) 
VALUES ('<エラーの出る文字>')

 検出方法

直接Mysql2::Errorは直接例外検出できないため、ActiveRecord::StatementInvalidを検出して判定することでエラー処理を行うことができる

テスト用のメソッド

def hoge_test(str)
  t = Hoge.new(hoge: str)
  t.save!
rescue ActiveRecord::StatementInvalid => e  
  if(e.cause.class == Mysql2::Error 
    && e.cause.message.match(/^Incorrect string value/))
    puts "[DEBUG!] MySQLに格納できない文字が入力されました."
	# エラー処理等
  end
end

実行結果

> hoge_test("<エラーの出る文字>")
(0.6ms)  BEGIN
SQL (0.5ms)  INSERT INTO `hoges` (`hoge`) VALUES ('<エラーの出る文字>')
Mysql2::Error: Incorrect string value: '\xF0\xA8\xBC\xB2' for column 'hoge' 
at row 1: INSERT INTO `hoges` (`hoge`) VALUES ('<エラーの出る文字>')
(0.1ms)  ROLLBACK
[DEBUG!] MySQLに格納できない文字が入力されました.
=> nil

Rack の話 | 初心者向け | DoRuby

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Rack はとてもシンプルな規約に基づいたインタフェースです。

Ruby on Rails や Sinatraは、Rackの上に実装され、UnicornやPumaなどのWebサーバに渡されます。

今回は、Rackの基礎をさっと説明します。

 せっかちなあなたへ

$ gem install rack
$ vi config.ru
run -> (env) { [200, {"Content-type" => "text/html"}, ["Hello, world"]]}
$ rackup config.ru

そして、 http://localhost:9292 にアクセスするだけ!

簡単に実装できました。

 改めて Rackとはなんぞや

http://rack.github.io にはこんな説明があります。

Rack provides a minimal interface between webservers that support Ruby and Ruby frameworks.

Web サーバと Rubyやフレームワークをつなぐ最小のインタフェースを提供している

rackの規約を満たしていれば、フレームワークやWebサーバを簡単に差し替えることができます。

rackには WEBrickというシンプルなWebサーバも搭載されており、rackの規約を満たすスクリプトを書くだけで簡単にWebアプリを作成することができます。

 Rackの規約

最低限以下を満たしていればOK

  1. アプリとなるオブジェクトを記述して run に渡します。 (上記の例だと、runに渡している Procオブジェクト)
  2. オブジェクトは次の規約を満たすものとします
    1. 引数を1つもつcallメソッドが定義されている(慣習的に仮引数名は env)
    2. callメソッドは [ステータスコード, ヘッダのハッシュ, 本文の配列] を返す

通常は設定ファイルに記述します。慣習的に拡張子が.ruのファイルに記述します。

中身の実体は Rubyなので .rb でも良さそうですが、run などのDSLとして拡張されるので変更されているみたい。

Ruby on Rails のアプリひな形だと app_path/config.ru になります。

 Rack Middleware

上記の規約を満たしていればOKなのですが、それだと 巨大な callメソッドになってしまいます。

Ruby が使えるのでクラスを切り出すことも可能ですが、そんな複雑なインタフェースをもつわけはありません。

use を使うことで、フィルタのように処理をつなげることができます。

たとえば、Basic認証を実装します。(このMiddlewareはRack標準に定義されています)

require 'rack/auth/basic'
use Rack::Auth::Basic, "input username" do |username, password| 
  username == "foo" && password == "secret"
end
run -> (env) { [200, {"Content-type" => "text/html"}, ["Hello, world"]]}

 Rack Middleware の規約

次を満たせば Rack Middlewareとなります

  1. 最初の引数に アプリとなるオブジェクトを受け取る initializeメソッドが定義されている
  2. Rackの規約を満たす call メソッドが定義されている

use を使って複数呼び出すことができますが、順番に注意してください。

次の場合は MiddleA -> MiddleB -> MiddleC と呼ばれます。

use MiddleA
use MiddleB
use MiddleC
run App

 Rails と Middleware

rack middleware コマンドで確認できます。

$ rack middleware

普段なかなか触らない Rackについて簡単に説明しました。

Railsのソースをながめると処理の流れをつかめるので、ぜひ追ってみてください。

抽象化しているので複雑ですが、実体は非常にシンプルです。

【Rails】特定のアクションだけ認証を外す方法【devise】

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

管理画面等の特定のページをログインせずに閲覧したい時の方法を記述します。

とても簡単

自分がタイトルどうりの機能が必要になったのですが、方法がわからず結構苦労しました。

ですが、なんてことは無い単純なことでした。

authenticate_user!

認証が必要になるようにする場合controllerに

	    before_action :authenticate_user!
	

と記述するかと思います。(「user」の部分はdeviseに使っているクラス)

これを公開したいアクションの際に外すだけでした。

	    before_action :authenticate_user!, except: [:public_action]
	

なんですぐに気づかなかったんだろう…

Docker を試してみる(1)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


 はじめに

共有の開発やCIサーバにMySQLの別のバージョンを使いたい!ってときにOSに共存させるのは結構面倒で、最悪壊したりしてしまいます。

そんなときに、Docker は便利です。

Dockerは仮装マシンではなくOS上で仮想環境を構築するソフトウェアです。

Linuxコンテナ型仮想化技術を使ってますが、vagrantと同様に簡単に使える環境が整っています。

今回はその使い方を調べてみました。

 インストール

今回はCentOS7を使いますが、せっかくなので vagrant を使いましょう。

前準備

以下のソフトウエアを準備します。

  • VirtualBox 5.0.14
  • vagrant 1.8.1
  • bento/chentos-7.1 (virtualbox, 2.2.2)

適当なフォルダで次のコマンドを実行します。

$ vagrant init bento/chef-7.1
$ vagrant up
$ vagrant ssh

準備はできましたか?

ログイン後、dockerの動く環境であるか一応確認します。

  • 64bitであること
  • Kernel 3.10 以降であること
[vagrant@localhost ~]$ uname -a
Linux localhost.localdomain 3.10.0-229.el7.x86_64 #1 SMP Fri Mar 6 11:36:42 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

インストール

CentOS7のextrasレポジトリに docker 1.8.2 がありますが、今回はdocker公式のものを使います。

repository の登録

デフォルトで有効にしちゃってますので、気に入らなければ enabled = 0 を設定してください。

[vagrant@localhost ~]$ sudo su -
[root@localhost ~]# cat > /etc/yum.repos.d/docker.repo <<'EOF'

[dockerrepo]

name=Docker Repository baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/ enabled=1 gpgcheck=1 gpgkey=https://yum.dockerproject.org/gpg EOF [root@localhost ~]# cat /etc/yum.repos.d/docker.repo

[dockerrepo]

name=Docker Repository baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/ enabled=1 gpgcheck=1 gpgkey=https://yum.dockerproject.org/gpg

インストール
[root@localhost ~]# yum install docker-engine -y
[root@localhost ~]# systemctl start  docker
[root@localhost ~]# systemctl status docker
docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled)
   Active: active (running) since ...
[root@localhost ~]# systemctl enable docker
一般ユーザで動かす

デフォルトではdockerはrootユーザしか使えません。

一般ユーザで使うためには docker グループに追加します。

[vagrant@localhost ~]$ sudo gpasswd -a vagrant docker

コンテナを起動してみる

使用するコンテナを探す

vagrant と同様にコンテナのイメージは Docker Hubで公開されています。

コマンドラインからも検索できますが、今回は Webから mysql 用のコンテナを探してみましょう。

https://hub.docker.com/explorer

現在対応しているのは 5.5, 5.6, 5.7 の3種類ですが、今回は 5.7 を使います。

でも、わざわざダウンロードする必要はありません。自動的にpullしてくれます。

使用するコンテナを実行する

以下のコマンドを実行して、仮想環境にログインしてみましょう。

[vagrant@localhost ~]$ docker run -t -i --rm mysql:latest /bin/bash
Unable to find image 'mysql:latest' locally
latest: Pulling from library/mysql
...
Status: Downloaded newer image for mysql:latest
root@4e05429b2b2f:/# 

プロンプトが返ってきたら成功です。もう仮想環境の中です。
-iインタラクティブモード-t端末を使用する–rm終了時にコンテナを削除する

実行中のコンテナを確認する

別の端末を起動して、以下のコマンドを実行してみます。

[vagrant@localhost ~]$ docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
4e05429b2b2f        mysql:latest        "/entrypoint.sh /bin/"   4 minutes ago       Up 4 minutes        3306/tcp            pensive_payne

コンテナの一覧が表示されます。
IMAGE実行中のコンテナCOMMAND実行中のコマンドSTATUSステータスNAMESコンテナの名前(指定するか勝手に付けられる)

今回は STATUS が 「Up 4 minutes 」なので起動中と分かります。

コンテナを終了させる

stop コマンドを使います。引数には ps コマンドで出力された NAMES の値を指定します。

[vagrant@localhost ~]$ docker stop pensive_payne
pensive_payne

pensive_payne にはpsコマンドのNAMESの値を指定してください。

もう一度コンテナの一覧をみてみます。

[vagrant@localhost ~]$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

なにも表示されなくなりました。

MySQLを使う

次は mysqlサーバを起動します。

起動

run コマンドを使います。

[vagrant@localhost ~]$ docker run  -e MYSQL_ROOT_PASSWORD=password -d mysql:latest
8e05ca461fa74135cf84e1f0f5f2e229810b40402e865c28fc593320bd26ba3a
[vagrant@localhost ~]$ docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
8e05ca461fa7        mysql:latest        "/entrypoint.sh mysql"   19 seconds ago      Up 15 seconds       3306/tcp            small_lichterman

-dデタッチオプション。コンテナをバックグラウンドで動作させる

mysql コンテナはmysqldをフォアグラウンドで起動するので、サーバとして起動させるならば -d オプションは必須です。

サーバに接続する

コンテナ中の mysql クライアントを使って接続するには以下の通り。

[vagrant@localhost ~]$ docker exec -it small_lichterman sh -c 'mysql -uroot -p'
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.10 MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

次回はもうちょっと進んだ使い方を説明します。

サーバのデータ完全消去をやってみた

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

もうすぐ2年目が終わってしまって、新人と言えなくなってきた中西です。

少し前にサーバーの撤去を行う機会があり、その時にサーバーのデータ完全消去の方法を色々と調べて行ったので、まとめてみました。

今回行ったデータ消去の方法は、インストールCDのレスキューモードをもちいた方法です。

ちょうど、サーバー構築用のSentOS6のiosデータが入ったCDがあったため、それをもちいて行いました。

事前準備物

・LinuxOSのCD(今回はCentOS6.6のisoイメージのインストール用CDを使用)

・データを完全消去するサーバー

・任意のディスプレイ

・任意のキーボード、マウス

 実行手順

今回行った時の手順を説明します。

前準備

1. サーバー起動

2. 任意のユーザーでログイン

3. ディスク配置の確認

$ df -kl
Filesystem                   1K-blocks     Used Available Use% Mounted on
/dev/mapper/VolGroup-lv_root  18102140 16079472   1103116  94% /
tmpfs                           510172        0    510172   0% /dev/shm
/dev/sda1                       495844    32670    437574   7% /boot

 例えば、上記のように表示されている場合、接続されているHDDはsdaとなる。

 消去対象になるため、間違えないようにメモしておく。

4. CDをドライブにセット後、サーバー再起動

 $ reboot

レスキューモードで起動(CentOS6.6の場合)

※OSによりレスキューモードの起動方法が異なる場合があるので要確認

1. 青画面に「Welcome to CentOS 6.6!」と表示されるページで「ESC」キーを押す

 (中段にいくつか選択肢があり、下部に「Automatic boot in ○○ seconds…」とカウントダウンされているページ)

2. ブートオプション画面(「boot:」と表示される画面)が開くので、「linux rescue」と入力する

3. Choose a Language画面で、「Japanese」を選択する(Englishや他言語でも可)

4. Language Unavailable画面で、「OK」を押す(言語によっては、表示されない。Japaneseは表示される)

5. Keyboard Type画面で、「jp106」を選択する

6. Setup Networking画面で、「No」を選択する

7. Rescue画面で、「Skip」を選択する

8. 「Shell」や「reboot」などの選択肢が表示される画面で、「Shell Start shell」を選択する

9. 画面下部に「bash-4.1#」と表示される

ディスクのパーティションを切りなおす

1. fdiskコマンドを起動(fdisk -l)

# fdisk /dev/sda 

2. “p”コマンドでパーティションを確認する

コマンド (m でヘルプ):p
〜略〜
デバイス Boot Start End Blocks Id System
/dev/sda1 * 1 13 104391 83 Linux
/dev/sda2 14 913 7229250 8e Linux LVM

 例えば上記の場合、パーティションは1、2の2つとなる。

3. “d”コマンドでパーティションを削除する

 手順2の場合、下記の用に2から削除を行う。

コマンド (m でヘルプ):d
コマンド (m でヘルプ):2

4. 手順3を「1」まで繰り返す

5. “p”コマンドでパーティションがないことを確認する

コマンド (m でヘルプ):p

6. 作業結果を”w”コマンドでディスクに書き込む

コマンド (m でヘルプ):w

ディスクの初期化(0埋め)

1. ディスク全域に”0″で埋めることで、情報を全て消去する

# dd if=/dev/zero of=/dev/sda

 上記は1度だけ”0″で上書きするもの。

 現状の15GBytes以上のハードディスクに関しては、データの完全消去は1度の上書きで十分であると言われている。

 アメリカ国立標準技術研究所(NIST)が2006年に発表したSpecial Publication 800-88の7ページでは、次のように述べられている。『2001年以降の(15GBytes以上の)集積度の高いATAハードディスクにおいては、データの完全消去はディスク全域に1回のみ上書きすれば事足りる』。

 また、Center for Magnetic Recording Researchは、次のように述べている『データの完全消去はディスクに対する1回の上書きのことである。アメリカ国家安全保障局も推奨要綱にて、同相信号除去比(CMRR)試験をした結果、複数回の上書きは何ら安全性の向上に優位な差をもたらさず、1回の上書きで十分であることを認めている』。

https://ja.wikipedia.org/wiki/

 より、安全になるか分からないが複数回の上書きを行いたい場合、shredコマンドをもちいると良い

# shred -n 3 -z -v /dev/sda

 上記shredコマンドは、ランダムな値を3回上書きし、その後”0″で上書きを行っている。

 上記をddコマンドで行う場合、下記のようになる。

# dd if=/dev/urandom of=/dev/sda
# dd if=/dev/urandom of=/dev/sda
# dd if=/dev/urandom of=/dev/sda
# dd if=/dev/zero of=/dev/sda

消去の確認

1. 「exit」と入力することで「Shell」や「reboot」などの選択肢が表示される画面に戻る。

2. 「reboot」を選択し、CDを取り出す

3. OSが立ち上がらないことを確認する

 ddコマンドによるデータ全消去における注意点

ddコマンドは下記コマンドでデータの全消去が行える。

# dd if=/dev/zero of=/dev/sda

この場合、全ての設定がデフォルト値となる。

この中には、1度に読み込むまた、書き込みバイト数も設定されている。

デフォルトの読み込み及び書き込みのバイト数は512byteであるため、大容量のディスクにたいしてコマンドを実行する場合、多大な時間がかかってしまう。

1度の読み込み及び書き込みのバイト数を設定するには下記のようにすればよい。

# dd if=/dev/zero of=/dev/sda bs=32M

上記では、1度の読み込み及び書き込みのバイト数を32Mbyteに設定している。

このバイト数は単純に大きくすれば早くなるという訳ではなく、スペック等により、大きくしすぎると逆に処理が遅くなる場合があることに注意してもらいたい。

32Mから256Mほどがちょうど良い設定値だと言われている。

また、読み込み及び書き込みのバイト数はそれぞれ個別に設定することもできる。

下記に一覧を表示する。

・bs=[バイト数]:1度に読み込み及び書き込めるバイト数の設定

・ibs=[バイト数]:1度に読み込めるバイト数の設定 

・obs=[バイト数]:1度に書き込めるバイト数の設定

 ddコマンドによるデータ全消去にかかる時間

300GBのハードディスクを消去した時

# dd if=/dev/zero of=/dev/sda

・9836.86s

・30.4MB/s

# dd if=/dev/zero of=/dev/sda bs=256M

・1736.51s

・172MB/s

もう少しbsの値を抑えてもそれほど時間は変わらなかったかもしれません。

環境により異なるため、あくまで1例としてご覧ください。

生産的な振り返り方法「KPT」について

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

たまごです。

技術ネタではないですが。今回、開発フェーズ終了に際して、チーム内でKPTを実施しましたので、以下、KPTについてご説明したく思います。

 KPTとは

「KEEP 続けていきたいこと」「PROBLEM 問題点」「TRY 次回からこうしよう」を順番に書き出していく振り返り方式です。

左上部にKEEP、左下部にPROBLEM、そして両者を受けて右側にTRYを書いていきます。

 実施方法

必要なアイテム

最もオーソドックスなやり方は、ホワイトボードと付箋を使うやり方です。

ホワイトボードへの準備

まず、ホワイトボードの中心に縦線を引きます。次に左側の中心に横線を引きます。左上スペースにKEEP、左下スペースにPROBLEM、右スペースにTRYとマーカーで記入します。

KEEPTRY
PROBLEM

↑こんなかんじ。

振り返り手順

準備ができたら、KEEP⇒PROBLEM⇒TRYの順番で振り返りを実施します。

付箋書き書きタイムを設ける

この際、KEEP、PROBLEM、TRYの各振り返りのフェーズごとに、五分ほどの時間をとって付箋記入タイムを作ります。そして、付箋記入タイミング後、書いた付箋をホワイトボードに貼りだしていくわけです。

ホワイトボードに貼りだした付箋をもとに、わいわいする

貼りだす際は、進行者が似た付箋ごとである程度グループ化してあげると、より俯瞰がしやすくなります。また、貼りだした内容について各自が色々コメントしていくと(全部にコメントしていると時間がなくなると思うので、臨機応変に)盛り上がります。

 KPTの利点

利点1 : 声なき声を拾える

まずは、KPTというより、振り返り自体の効能について。

普段なかなか共有できない各人の感じている思いを、共有することができます。「何か懸念点はあるか」と漠然と問いかけるよりは、フォーマットを提示した方がアウトプットしやすくなります。そのフォーマットのひとつとして、KPTが有用です。

利点2 : we vs problem の構図を作れる

こちらは、KPTというよりホワイトボードを利用する利点です。

問題が人から切り出されて、ホワイトボードという形に可視化されるため、いわゆるwe vs problemの構図を作りやすくなります。人 vs 人になると不毛なので。個人攻撃ではなく、問題を解決するべきです。そのためにこの図式を意識することは有用です。

これは何もホワイトボードに限らず、プロジェクタで映し出したexcelファイルでもいいし、evernoteでも同じことです。要は、皆が一同に見えるもので、かつ、個人から切り離されていればよいかと思います。

利点3 : 「KEEP」の存在

振り返りというと、ついつい問題点ばかりがクローズアップされがちです。しかし、KPTはまずKEEPの洗い出しから始める点が秀逸です。これによって、(1)出だしがポジティブになり、振り返り自体が生産的な場になりやすくなる。(2)忘れがちなプロジェクトの価値を再認識できる――などの効果があります。

(1)の効果があるため、KPTの実施順は是非ともKEEPから始めた方が良いように思われます。

利点4 : 「KEEP」「PROBLEM」を受けての「TRY」である点を可視化できている

KPTは「続けたいこと」「改善したいこと」、その止揚としての「次からこうしようぜ」の三つから成り立つ非常にシンプルな振り返り方法です。

にもかかわらず、KEEPとPROBLEMを左、TRYを右に配置することで、TRYが左のKEEPとORBLEMを精査した上での止揚であることが明示できていることが素晴らしい。「良い点がこれだけありました。改善点がこれだけありました。だから、次はこうしましょう」のストーリーがたった二本の線で表現できるのは、白眉です。

利点5 : アウトプットが他人の影響を受けない

最初に付箋を記入している段階では、互いがどんなことを書こうとしているかが見えないため、他人の意見に影響されずに済みます。「個人の意見を吸い出すタイミング」「それを共有するタイミング」が両方存在するのは、大きなメリットではないでしょうか。

(もちろん、他人の意見が起爆剤となった発想が湧く場合もあるかと思うので、そういう場合は、思いついた段階で付箋を足していってもいいのではないでしょうか)

 KPTのカスタマイズ案

以下は、KPTを実践して思ったカスタマイズ案

ホワイトボードではなく、プロジェクタを使いたいかもしれない

今回、付箋の文字が小さすぎたり読みづらかったりしたために、メンバーがホワイトボード上の付箋を判読できない問題が発生しました。

ホワイトボードとの距離の近さによってミーティングのイニシアチブに差が生まれるのは、あまり好ましいことではありません。なので、次からはプロジェクタを使って、事前に書き込んでもらった共有ファイルを映す形も検討しようかなと考えています。(書き込む時間を会議外に持てるので、振り返り自体の時間短縮にもつながります)

ただ、そのままやると、上記にあげたKPTの利点をいくつか潰すことになってしまうので、やり方を考えねばなりません。その辺りは、また書く機会があれば、いずれ。

PROBLEMをPROBLEM(WISH)としたい

これは以前からKPTをやるたびに思っていたことなのですが。KPTはKEEP(続けていきたいこと)、PROBLEM(改善したいこと)の観点しかないため、ふと思いついた次からやりたいことをどこに含めればよいか迷ってしまいます。TRYに書いてもいいのですが、できればTRYは「左の内容を精査したもの」という位置づけを保ちたいです。

そこで左下の「PROBLEM」を「PROBLEM(WISH)」として、突発的なやりたいことはここに書いたらどうかと思います。

「次から~したい」という思いは、いわば「今~できていない」の裏返しです。なので、WISHという観点をPROBLEMの中に含めることで、PROBLEMがよりポジティブで生産的なものになりやすくなる効果もあるのではないかと、勝手に思っています。

IDCF オブジェクトストレージを利用したMySQLのバックアップ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rickNo39です。
IDCフロンティアでは、スナップショットという機能がありますが、対象ディスク全てが対象となりサイズと時間で従量課金となるため、オブジェクトストレージ(の無料枠)を利用して対象ファイルだけバックアップを行った設定を記載します。

事前設定

使用するミドル

  • logrotate
  • mysql

料金プラン

50GBまで無料、10TBまでの定額プラン有
136.7GBまで保存すると定額プランのほうがお得になってくるようです。

オブジェクトストレージへ送信・削除

vim /etc/logrotate.d/mysql-dump
—–
/extdisk1/dump/*.sql {
create 600 mysql mysql
daily
rotate 7
size 0
missingok
dateext
compress
create 444
postrotate
mysqldump -uroot -h localhost –single-transaction –opt –all-databases > /extdisk1/dump/dump.sql
endscript
lastaction
// 圧縮したdumpをオブジェクトストレージに送信
s3cmd put /extdisk1/dump/dump.sql-`date ‘+%Y%m%d’`.gz s3://バケット名
// logrotateでは当日分圧縮してくれないので自分で圧縮
cp /extdisk1/dump/dump.sql /extdisk1/dump/dump.sql-new
gzip /extdisk1/dump/dump.sql-new
// 当日分のdumpもオブジェクトストレージへ送信
s3cmd put /extdisk1/dump/dump.sql-new.gz s3://バケット名
// 6日前(実質7日前)のdumpを削除
s3cmd del s3://バケット名/dump.sql-`date -d ‘6 day ago’ ‘+%Y%m%d’`.gz
endscript
}
—-

容量確認のメール送信

日々容量を確認するのも手間なので、
下記のようなシェルを作成しcronで設定してメールを送るようにします。
vim object_storage_consumption.sh
—-
#!/bin/bash
PID=$!
TIMER=1
HOSTNAME=”hoge@hoge.com”
ADDRESS=”hoge@hoge.com”
DATA=`timeout -s 9 60 s3cmd du -H`
if [ -n “$DATA” ]; then
BODY=”IDCF オブジェクトストレージ使用量\n$DATA\n50GBから有料、136.7GBを超える場合はプラン変更”
echo -e “$BODY” | /usr/bin/mail -s ‘IDCF Object storage consumption’ -r $HOSTNAME $ADDRESS
echo “s3cmdからデータを取得できませんでした。”
fi
—-

たまに?オブジェクトストレージのレスポンスがやたら遅くてメールの中身が途中で途切れることもありますが、気にしない。

以上、とっても簡単バックアップ方法でした。

【Oracle】トリガーの状態とエラー内容の確認方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

トリガーを作成したは良いけど動作しない。

そんな時はトリガーの状態とエラー内容を確認してみましょう。

※注)以下はMacの設定となります

 メソッドジャンプ

command + R

Eclipseではcommandを押したままメソッドをクリックすると宣言元のメソッドにジャンプできる機能があります。

Atomの場合、似たような機能としてcommand + Rでメソッドを検索できます。

Eclipseに比べると若干不便ですが、Atomはスクリプト系の言語で使われることが多く、定義位置の解析が難しいらしいので仕方ないのかもしれません。

 Eclipse風テーマ

テーマ:Atom Light

Atomのデフォルトのテーマは背景が黒ですが、Eclipseに近づけるため背景が白のAtom Lightに設定変更します。

Atom->環境設定->テーマ->

 インターフェーステーマ:Atom Light

 シンタックステーマ:Atom Light

 文字サイズ小さくする

フォントサイズ:12

デフォルトだと文字サイズが少し大きめですので、小さくします。

Atom->環境設定->設定->

 フォントサイズ:12

 不可視文字を表示

この設定はEclipseでもデフォルトでは無いですが、個人的にあったほうが良いと思う設定です。

Atom->環境設定->設定->

 ■不可視文字を表示

次回、パッケージ編に続きます

最近人気な記事