railsのdatabase.ymlを見てmysqlを起動するシェル スクリプトを書いたのでメモ。database.ymlからパスワードをmysqlのPasswordプロンプトにコピペしなくてもよくなります。
database.yml内のパスワードをmy.cnf形式の中間ファイルに書き出しmysqlを起動します。mysqlを終了したら中間ファイルは消します。
- -cオプション
- 起動するコマンド(デフォルト: mysql)
- DBのダンプを取りたいときは
-c mysqldump
と指定して| gzip -9 > dump.sql.gz
などとパイプでつなげて使用します。
- -dオプション
- database.ymlのパス(デフォルト: config/database.yml)
- -eオプション
- database.yml内のエントリ名(デフォルト: staging)
- -lオプション
- database.yml内のエントリ名の一覧を表示して終了
スクリプトのファイル名はmysqlrailsにしました。ライセンスはMITです。
mysqlrails
#!/bin/sh
command=mysql
db_yml=config/database.yml
entry_name=staging
mycnf=/tmp/.my.cnf.$$
list_flag=0
usage() {
echo "Usage: $0 entry_name"
echo "entry_name must be one of config/database.yml"
}
list_entries() {
awk '/^[A-Za-z0-9_]+:/ { sub(":", ""); print }' $db_yml
}
while getopts c:d:e:l opt
do
case $opt in
"c") command="$OPTARG" ;;
"d") db_yml="$OPTARG" ;;
"e") entry_name="$OPTARG" ;;
"l") list_flag=1 ;;
*) usage 1>&2
exit 1 ;;
esac
done
if [ $list_flag -eq 1 ]; then
list_entries
exit 0
fi
awk '/^'$entry_name':/,/^$/ {
if ($1 == "database:") {
database = $2
} else if ($1 == "username:") {
username = $2
} else if ($1 == "host:") {
host = $2
} else if ($1 == "password:") {
password = $2
}
}
END {
if (password != "") {
system("umask 0077")
printf("[client]\npassword=%s\n", $2) > "'$mycnf'"
system("umask 0022")
mycnf_opt = " --defaults-file='$mycnf'"
} else {
mycnf_opt = ""
}
host_opt = host != "" ? sprintf(" -h %s", host) : ""
cmd = sprintf("'$command'%s -u %s%s %s", mycnf_opt, username, host_opt, database)
system(cmd)
if (password != "") {
system("rm '$mycnf'")
}
}
' $db_yml
適宜改変して使ってください
この例ではdatabase.ymlをオプションで指定するようになっていますが、使用するホスト上のdatabase.ymlのパスをスクリプト内に埋め込んでしまえば、どのディレクトリでも使えて楽そうな気がします。あとはpecoと連携するようにするとか。
Ansibleから使う例
- file: path=~/bin state=directory
- copy: src=mysqlrails dest=~/bin/mysqlrails mode=0755
- shell: ~/bin/mysqlrails -c mysqldump -d /data/app/myapp/current/config/database.yml -e production | gzip -9 > /data/rails_db_production.sql.gz