NTP サーバの同期設定方法
先日、保守しているサイトの本番サーバの時刻がずれていたので、ntp サーバの設定をしました。
yum list で確認すると、NTP サーバ自体は本番サーバ(以下、hoge サーバとします)にインストールされていたので、設定から。
/etc/ntp.conf を修正
- NTP サーバの設定を追加します。
- 日本標準時を提供している NTP サーバと時刻の同期をとるように設定します。
- 外部の NTP サーバと、hoge サーバにある NTP サーバと同期をとる、という感じです。たぶん。
# 修正前 server 0.rhel.pool.ntp.org server 1.rhel.pool.ntp.org server 2.rhel.pool.ntp.org # 修正後 server -4 ntp.nict.jp server -4 ntp.jst.mfeed.ad.jp
hoge サーバ内の NTP サーバが起動しているか確認
- 下記コマンドで確認できます。どっちをつかっても OK です。
- /etc/init.d/ntpd status
- ps aux | grep ntpd
ps aux | grep ntpd # こんな感じででれば起動中 ntp 2675 0.0 0.8 4392 4392 ? SLs 2010 0:07 ntpd -u ntp:ntp -p /var/run/ntpd.pid -g
NTP サーバが起動してたら一旦止める
- 停止している状態ならこのコマンドは実行しなくて OK です。
/etc/init.d/ntpd stop
手動で時刻を合わせる
- 30 分くらい時刻がずれていたので、手動で時刻を合わせてから、NTP サーバと同期をとるようにします。
- NTP サーバ起動時に大幅に時刻がズレていると、NTP サーバが起動できないそうです。
- ■NTPサーバーインストール に書いてありました。
ntpdate -b ntp.nict.jp
- もし NTP サーバが起動中だった場合、下記のようなエラーになります。
21 Apr 13:01:44 ntpdate[9659]: the NTP socket is in use, exiting
NTP サーバを起動
- 時刻を合わせたら、下記コマンドで NTP サーバを起動します。
/etc/init.d/ntpd start
少し待って、同期しているか確認
- ntpq -p を実行して、参照同期中のサーバを表すアスタリスクが表示されていれば OK です。
>ntpq -p remote refid st t when poll reach delay offset jitter ============================================================================== *ntp-b2.nict.go. .NICT. 1 u 5 64 377 3.366 28.289 8.686 +ntp2.jst.mfeed. 210.173.160.86 2 u 9 64 377 1.436 31.315 6.857 LOCAL(0) .LOCL. 10 l 12 64 377 0.000 0.000 0.001
【補足】ntpq -p の見方
- * 参照同期中のサーバーを表している
- + クロック誤り検査に合格したサーバー
- " " 左に何も表示されない場合(空欄)、サーバーを参照していない
php-gd のインストールではまったこと
本番にはあるけどステージング環境に GD モジュールがない!という状況に陥ったので、インストールすることにしました。
(ステージング環境がちゃんと動き出したのが最近で、全部の機能が動くことを確認出来ていなくて、今日まで気付かなかった…。)
php-gd のインストール
yum を使う
色々回り道したけど、結局は yum を使って一発インストール。(迷走した記録は後述します。)
一応インストールする gd ライブラリを確認してから実行しました。
$ yum list | grep gd $ yum install php-gd.i386
迷走した記録(読まなくて OK)
結局作業自体は上記の手順で良かったのですが、それにいたるまでいろいろ迷走しました。
また同じようなことではまらないように、書いておきます。
imagecreatetruecolor() がない
最初は、下記のようなエラーログが出力されていました。調べてみると GD モジュールがない疑惑が生じました。
Fatal error: Call to undefined function imagecreatetruecolor()
GD モジュールの確認
GD モジュールは、PHP 5.2.0 以上の場合標準でインストールされているとのことです。
じゃあ PHP のバージョンが低いの?と思って調べてみると、5.1.6 でした…。
$ php -v PHP 5.1.6 (cli) (built: Nov 29 2010 16:47:37)
念のため GD モジュールが存在するのか確認したけど、やっぱりない。
やっぱり別にインストールする必要がありました。
今まで確認する時って、画面に phpinfo(); とかで表示してたけど、コマンドで確認する方法を覚えました。
- i オプション:phpinfo の実行結果をコマンドライン形式で表示する。
- m オプション:読み込まれているモジュールの一覧を表示する。
# 実行はこんな感じで $ php -i | grep gd $ php -m | grep gd
GD モジュールのインストール
GDライブラリのインストール を参考にしてインストールすることにしました。
ファイルを wget で取得したところまでは良かったのですが、make 時にエラーが起こりました。
$ cd /usr/local/src $ wget http://www.libgd.org/releases/gd-2.0.35.tar.gz $ cd gd-2.0.35 $ ./configure $ make cd . && /bin/sh /usr/local/src/gd-2.0.35/config/missing --run aclocal-1.9 -I config aclocal:configure.ac:64: warning: macro `AM_ICONV' not found in library cd . && /bin/sh /usr/local/src/gd-2.0.35/config/missing --run automake-1.9 --foreign Makefile.am:18: Libtool library used but `LIBTOOL' is undefined Makefile.am:18: Makefile.am:18: The usual way to define `LIBTOOL' is to add `AC_PROG_LIBTOOL' Makefile.am:18: to `configure.ac' and run `aclocal' and `autoconf' again. make: *** [Makefile.in] Error 1
エラーの原因?
よくわからないんですが、libgdのmakeでエラー を見ると同じような状態になっている人がいました。
libiconv を入れれば動くのかな…?と思いつつ、もう嫌になってきました。
周りの人に助けを求めたら、「yum でインストールできるんじゃない?」といわれてショックをうけつつ、上記の方法でインストールしたのでした。
post-receive-email を使って、push 時にメールを飛ばす
今まで自作で作った微妙なメール送信スクリプトを使ってたんですが、post-receive-email というものがあると知って、hollyなblog:git post-receive-email を参考に、こっちに移行しました。
これだとソースの diff がメールで見れないけど、commit 時にもメールを飛ばすようにしてるし、そこでは diff 見れるから OK ということで。
環境は下記とします。
- メール送信スクリプト:/usr/local/src/git-1.6.5.7/contrib/hooks/post-receive-email
- 共有リポジトリ:/var/git/sendmail.git
post-receive の準備
まず、コミット後に実行されるスクリプト(post-receive)を準備します。post-receive は hooks の下に post-receive.sample という形であるので、コピーして使います。
cd /var/git/sendmail.git/hooks cp post-receive.sample post-receive
post-receive を編集
次にpost-receive の中身を編集します。post-receive-email のパスがコメントアウトしてあると思うので、コメントアウトを外して、パスを変更します。
### これを↓ ### #. /usr/share/doc/git-core/contrib/hooks/post-receive-email ### こうする↓ ### . /usr/local/src/git-1.6.5.7/contrib/hooks/post-receive-email
メールが文字化けすることがあるので、文字コードの設定をしておきます。これは、post-receive-email を修正します。
### 197 行目あたりに追加 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" ### 684 行目あたりを編集 generate_email $oldrev $newrev $refname | nkf -w80 | send_mail
git config をいじる
このままだと、メールの送信先が設定されないので、git config で設定します。ついでに、prefix と差出人も設定しておきます。
複数共有リポジトリを作ったときに毎回設定するのが面倒なので、今回は global で設定しました。
git config --global hooks.mailinglist "XXXXXX@gmail.com" git config --global hooks.emailprefix "[git commit]" git config --global hooks.envelopesender "XXXXXX@gmail.com"
description を編集
もう一点。私は description の存在を知らなかったので、メールが飛ぶと「UNNAMED PROJECT」とかでちゃってました。
description は、/var/git/sendmail.git/description というファイルで、ここにプロジェクト名を設定できるみたいです。(post-receive-email を読んだら、description の設定がなかったら UNNAMED ... になるみたいでした。)
UNNAME は格好悪いので、description を編集。これでメールのタイトルや本文に UNNAMED ... が出なくなります。
#### 編集内容これだけ↓ ### sendmail_repo
hooks 用の共有リポジトリを作成
複数共有リポジトリがあると、それぞれに hooks の設定をしなきゃいけないのがめんどくさかったので、hooks のリポジトリをつくってしまうことにしました。
共有リポジトリを作成してコピーします。
これで今後共有リポジトリを作成したら、hooks を hooks.git から clone して使うようにすればOK です。
cd /var/git git init --bare hooks.git ### clone して sendmail.git の hooks たちをコピー ### git clone hooks.git cp -rp /var/git/sendmail.git/hooks/* /var/git/hooks ### git commit して git push する ###
Oracle メモ
最近 Oracle を使うようになりました。というか、ちゃんと SQL を書き始めたのが最近なので、忘れないようにいろいろメモ。
オラクルは空文字は null になる
- 最初知らなくて困った。Oracle SQL 特殊な値NULL 入門その1
ADD_MONTHS
- ADD_MONTHS(<基準となる日付>, <加算する月数>)
- 日付を加算する
- 加算する月数をマイナスにすると、前の月が取得できる
- ADD_YEARS みたいなのはないみたい
# 3ヵ月前と比較 AND TO_CHAR(UPD_DATE, 'YYYYMM') < TO_CHAR(ADD_MONTHS(SYSDATE, -3), 'YYYYMM')
CONCAT
- CONCAT(文字列1, 文字列2)
- セルのデータを結合できる
## TIME と TIME_CLASS がくっついて表示 SELECT CONCAT(TIME, TIME_CLASS) AS TIME FROM TIME_TABLE
START WITH
- 階層問い合わせ ができるみたい。詳細はここ → Oracleの階層問い合わせ(1)
CASE
- switch 文みたいなことができる。詳細はここ → CASE式のススメ
- CASE 式の評価は、真になる WHEN 句が見つかった時点で打ち切られて、残りの WHEN 句は無視される
/etc/grub.conf の設定を削除して再起動したら起動できなかった話
普段、/etc の下のファイルなんてそうそういじったりするわけじゃないんですが。
ちなみに、起動できなくなってしまったのは GuestOS(CentOS 5.4)です。なので、HostOS から入ってなんとか起動できました。
発端は、以前 GuestOS の時計が狂いまくっていて、HostOS と時間の同期とるという設定をこのファイルに追加したためでした。
その設定をしたのが半年くらい前で、その時使用していた Redmine のチケットに「下記設定を追加」と書いていたので、すべて新規で追加したと思ってしまったんです。で、まるごと消しちゃったんです。(よく見れば分かりそうなのに…)
/etc の下を、etckeeper とかでちゃんとバージョン管理していなかったのも悪かったのです。反省。
# 設定を追加したとかかれていた部分↓ kernel /vmlinuz-2.6.18-164.el5 ro root=/dev/VolGroup00/LogVol00 rhgb quiet divider=10 clocksource=acpi_pm
それで reboot かけたらいつまでたっても立ち上がらない…。HostOS からコンソールを開いて確認するとなんか変な画面で止まってる。おかしいなぁと思って調べてみると、「/etc/grub.confの設定に従い,Linuxカーネルが読み込まれます。」とか書いてあるサイトを発見。
そこでやっと気づきました。まるごと消しちゃいけなかったんだって。よく考えたら kernel 読み込むところ削除してるし。そりゃ起動しないよ。
7GNU GRUB を使用してシステムを起動する方法 を参考にすると、grub.conf に書かれている設定を一行ずつ実行していけばいいっぽい。でも、そのファイルに何が書かれていたのか分からない…終わった…。と絶望しかけたとき、そういえば他のプロジェクトで使ってるサーバも、バージョン一緒だったことを思い出しました。急いで接続し、その内容を起動しなくなった方のサーバで下記のように実行しました。
# 起動パーティションを指定 grub>root (hd0,0) # Linuxカーネルを読み込む grub>kernel /vmlinuz-2.6.18-164.el5 ro root=/dev/VolGroup00/LogVol00 rhgb quiet # initrd を展開 grub>initrd /initrd-2.6.18-164.el5.img # 読み込んだカーネルを使用し、システムを起動 grub>boot
成功!よかったよかった。冷や汗かきました。/etc の下をいじるときは、もっと慎重にならないとダメですね。あとバージョン管理の大切さが身にしみました。
今回はじめて initrd とかを知りました。こんなの今まで何も考えてなかったので、勉強になりました。
参考 : initrdとは
git-svn から git への移行方法
前回 git-svn を使って、Subversion のリポジトリと連携 の続きです。
git-svn を使っていたのですが、私が最初に設定をエレコマのリポジトリ(Subversion)の trunk 以下を取得するようにしていたんですね。でも、エレコマの開発者の方は、最新のソースを branch にコミットしたりしていて。そうすると、私たちのチームで開発中のソースと、最新のソースのマージが出来ないわけです。そんな状態で途方にくれていたら、エレコマの開発者の方が、リポジトリを Git に移行してくれました。
ただ、ここからが問題。ただエレコマのソースを取得するだけなら git clone で済みますが、すでに git-svn で取得したエレコマのソースに手を入れている状況です。エレコマのリポジトリが Subversion の時は、変更を git-svn rebase で取得できましたが、今度はエレコマの Git のリポジトリから git pull して取得するようにしたいのです。でも、それってできるの?ということで行き詰まりました。
いろんな方法を試して、できたのが下記の手順です。
ローカルに取得しているリビジョン番号を指定して、master ブランチにマージする
git-svn で取得していた最新のリビジョンにあたる、エレコマの Git リポジトリのリビジョンを、最新ソース取得用のリポジトリ(/var/git/elecoma)にマージします。いきなりマージしてしまうとコンフリクトが起こりまくるので、一旦 git fetch してからマージを行います。
まず、master ブランチを エレコマの Git リポジトリと同様にする必要があるので、master ブランチに checkout してから作業を行います。
[root@hoge ~]# cd /var/git/elecoma # master ブランチに移動 [root@hoge elecoma]# git checkout master # エレコマの Git リポジトリから、ソースを取得 [root@hoge elecoma]# git fetch git://git.sourceforge.jp/gitroot/elecoma/elecoma.git master # ローカルに取得しているリビジョン番号(git log とかで確認しておく)を指定してマージ [root@hoge elecoma]# git merge 55be40069b3d3e837836d9260fbdb7d2c9be6ba2 Merge made by recursive.
FETCH_HEAD を master ブランチにマージする
ちなみに FETCH_HEAD とは、最後にフェッチされたブランチの先頭の簡略記法。フェッチ操作の直後にだけ有効。というものなので、先ほどフェッチしてきたものを、最新ソース取得用のリポジトリ(/var/git/elecoma)にマージする事になります。
[root@hoge elecoma]# git merge FETCH_HEAD Merge made by recursive. app/controllers/cart_controller.rb | 1 + config/locales/translation_ja.yml | 3 +++ spec/controllers/cart_controller_spec.rb | 8 +------- spec/fixtures/customers.yml | 2 ++ spec/fixtures/products.yml | 5 +++++ 5 files changed, 12 insertions(+), 7 deletions(-)
最新になった master ブランチを dev ブランチに取り込む
今度は、私たちが開発している dev ブランチとのマージです。ここまでくればただ単に master ブランチと dev ブランチをマージするだけです。
# dev ブランチに移動 [root@hoge elecoma]# git checkout dev [root@hoge elecoma]# git merge master Auto-merging app/controllers/cart_controller.rb Auto-merging config/locales/translation_ja.yml Auto-merging spec/controllers/cart_controller_spec.rb Auto-merging spec/fixtures/customers.yml Auto-merging spec/fixtures/products.yml Merge made by recursive. app/controllers/cart_controller.rb | 1 + config/locales/translation_ja.yml | 3 +++ spec/controllers/cart_controller_spec.rb | 8 +------- spec/fixtures/customers.yml | 1 + spec/fixtures/products.yml | 5 +++++ 5 files changed, 11 insertions(+), 7 deletions(-)
これでコンフリクトなく、完了!長い道のりでした。ほんとに。
下記はメモです。今回参考になりました。
◆FETCH_HEAD リモートリポジトリが使われている場合は、git fetch はフェッチしたブランチの先頭をすべて、.git/FETCH_HEAD に記録します。FETCH_HEAD は、最後にフェッチされたブランチの先頭の簡略記法であり、フェッチ操作の直後にだけ有効です。 ブランチに特定の名前をつけない匿名フェッチの場合でも、このシンボリック参照を使って git fetch されたコミットから HEAD を見つけることができます。 ●git fetch リモートリポジトリから、オブジェクトとそれに関連したメタデータを取得します。 ●git pull git fetch と似ていますが、それに加え、対応するブランチに変更をマージします。 ●git push オブジェクトとそれに関連したメタデータをリモートリポジトリに転送します。 ●git ls-remote リモート内の参照を表示します。
git-svn を使って、Subversion のリポジトリと連携
ちょっと前に エレコマ という EC サイト構築パッケージを利用して、ショッピングサイトを作ることになったのですが、エレコマのリポジトリが Subversion でした。
私のいるプロジェクトで使おうと決めたバージョン管理システムは Git だったので、Subversion リポジトリと連携できる git-svn というコマンドを使ってソースを取得することにしました。
下記の環境で行います。
- 共有リポジトリ(bare なリポジトリ)と、最新ソース取得用リポジトリ
- ローカルリポジトリ
- OS は WindowsXP(クライアントPC)
- git は msysGit で、バージョンは 1.6.5.1.1367.gcd48
共有リポジトリの作成と、sourceforge から エレコマのソースを取得
hoge サーバ上に開発用の共有リポジトリ(bare なリポジトリ)と、エレコマの最新ソースを取得してマージするためのリポジトリそれぞれ作成します。
リポジトリの役割はまとめるとこんな感じです。
- /var/git/elecoma.git : 開発用リポジトリ
- /var/git/elecoma : git-svn コマンドで、sourceforge からソースを取得するリポジトリ
[root@hoge ~]# cd /var/git # sourceforge にあるリポジトリから、trunk のみ取得するよう指定 # 自動的に elecoma というディレクトリ名で取得される [root@hoge git]# git svn clone --prefix svn/ --trunk trunk -s http://svn.sourceforge.jp/svnroot/elecoma/ # 共有リポジトリを作成 [root@hoge git]# git init --bare elecoma.git # 共有リポジトリの master ブランチに sourceforge から取得したソースを push [root@hoge git]# cd elecoma [root@hoge elecoma]# git push /var/git/elecoma.git master
開発用ブランチの作成
リポジトリには master の他に dev というブランチを作成することにします。私たちのプロジェクトで行う開発は dev ブランチで作業し、master ブランチについては 手を加えていないエレコマのソース、というように使い分けます。
# 共有リポジトリに移動して、dev ブランチを作成 [root@hoge elecoma]# cd ../elecoma.git [root@hoge elecoma.git]# git branch dev # elecoma リポジトリにも dev ブランチを作成し、dev ブランチにいるときは必ず dev へ push するよう設定 [root@hoge elecoma.git]# cd ../elecoma [root@hoge elecoma]# git checkout --track origin/dev
エレコマの最新ソースを取得してマージするスクリプトを作成
エレコマは結構頻繁にアップデートされているので、sourceforge から最新のソースを取得して、開発中のソースとマージするスクリプトを作成しました。cron で毎日 0:00 に動くように設定します。
Subversion から git-svn で更新されたソースを取得するには、git svn rebase を使います。
ちなみに、バッチは勢いで書いたので、ログの出力内容とかいろいろひどいです。一応動きますが、コピーはオススメしません。
- バッチ : /var/git/elecoma/tmp/update/update_elecoma.sh
#!/bin/sh ROOT=/var/git ELECOMA_REPO=$ROOT/elecoma.git ELECOMA=$ROOT/elecoma UPDATE=$ELECOMA/tmp/update LOG=$UPDATE/logs cd $ELECOMA # 共有リポジトリの最新を取得 git pull $ELECOMA_REPO dev # http://svn.sourceforge.jp/svnroot/elecoma/ から最新のソースを取得 git checkout master git svn rebase git push $ELECOMA_REPO master git checkout dev git merge master if [ $? -eq 0 ] then git push $ELECOMA_REPO dev if [ $? -eq 0 ] then echo 'finish' else # push に失敗した場合ログ出力 echo "[`date +"%Y-%m-%dT%T"` #$$] INFO -- : 共有リポジトリ(elecoma.git)>への push に失敗しました。コンフリクトしている可能性があります。" >> $LOG/batch.log exit 1 fi else # merge に失敗した場合ログ出力 echo "[`date +"%Y-%m-%dT%T"` #$$] INFO -- : master との merge に失敗しました。コン フリクトしている可能性があります。" >> $LOG/batch.log
- cron の設定方法
crontab -e # vi でファイルを開くので、下記を記述して保存。cron のログも吐くよう設定。 PATH=/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 0 0 * * * /var/git/elecoma/tmp/update/update_elecoma.sh >> /var/git/elecoma/tmp/update/logs/cron.log 2>&1
ローカル環境での設定
hoge サーバに共有リポジトリを作成したので、ローカル環境で下記のようにリポジトリを clone します。
- 共有リポジトリから clone し、リモートブランチをコピー
git clone ssh://yun_kichi@hoge.co.jp/var/git/elecoma.git elecoma cd elecoma git checkout --track origin/dev
この設定をしておけば、自分のローカルのブランチは常に dev を見るようになります。push するときも dev に push してくれるようになります。
次回は、git-svn 取得しているソースを、git に移行する手順を書こうと思います。