2011年 10月 の投稿一覧

Windows で rsync を使用する

Windowsの場合、サーバとファイルをやり取りする際はWinSCP(ssh)が有名どころだと思いますが、開発環境サーバにソースファイルをアップするときにいちいち、WinSCPを立ち上げてアップするのは少々めんどくさい感じがします。

他には、sambaサーバを立てたり、sshfsでマウントしてアップする方法も有りますが、個人的には開発環境ではコマンド一つでサーバにアップしたいと思っています。

macには、rsyncコマンドがあります。

WindowsでもcwRsyncを使えば、rsyncコマンドを使う事が出来ます。

目次

  • 開発環境に公開鍵認証方式(ssh)の設定をする
  • cwRsyncインストール
  • cwRsyncコマンド実行

開発環境に公開鍵認証方式(ssh)の設定をする

cwRsyncコマンドでパスワード入力無しでコマンド1つで同期する為、公開鍵認証方式(パスフレーズ無し)の設定をします。

開発環境なので全てrootユーザで実行しています。

[root@localhost ~]# ssh-keygen -t rsa ← 公開鍵、秘密鍵の作成(パスフレーズ無し)
[root@localhost ~]# chmod 700 ~/.ssh ← パーミッション設定
[root@localhost ~]# chmod 600 ~/.ssh/*

[root@localhost ~]# cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys ← 公開鍵をリネームコピー

[root@localhost ~]# vi /etc/ssh/sshd_config ← sshdの設定

RSAAuthentication yes ← コメント解除
PubkeyAuthentication yes ← コメント解除
AuthorizedKeysFile .ssh/authorized_keys ← コメント解除

AllowUsers root ← 追加

[root@localhost ~]# service sshd restart ← sshd再起動

秘密鍵「/root/.ssh/id_rsa」をWindowsにコピーしておく。

インストール

Download | ITeF!x. からcwRsyncをダウンロード、インストールします。

今回はC:\cwRsyncにインストールしました。
コピーしておいた秘密鍵「/root/.ssh/id_rsa」C:\cwRsync\192.168.1.3に移動します。

cwrsync.cmdにコマンド例の記述があります。
このファイルに以下を記述して、実行すると開発環境にファイルが同期されます。

C:\cwRsync\bin\rsync.exe -rvz -e "C:\cwRsync\bin\ssh.exe -i /cygdrive/c/cwRsync/192.168.1.3/id_rsa" --block-size=81920 --stats --progress /cygdrive/c/home/sample/ root@192.168.1.3:/home/sample/

ただ、実行すると毎回「Are you sure you want to continue connecting (yes/no)?」と聞かれてしまうので~/.ssh/config

host *
    StrictHostKeyChecking no

を追加して聞かれないようにしました。

VMWare Server の開発環境作り直し

インストールしたもののメモです。

OSインストール

Index of /Linux/centos/5/isos/i386. CentOS5.7を今回は使用しました。
ISOファイルをダウンロードして、最小構成でインストール。

VMWare Toolsインストール

VMWare上のCentOSは時間がずれるのでVMWare Toolsをインストール。
VMWare Serverの管理画面から[Install VMware Tools…]を選択します。
選択すると、CDドライブにインストール用のファイルがセットされます。

[root@localhost ~]# mount /dev/cdrom /mnt/
[root@localhost ~]# cd /mnt/
[root@localhost ~]# /etc/yum.conf
gpgcheck=0 ← 0に変更

[root@localhost ~]# cp VMwareTools-7.7.6-203138.i386.rpm /tmp/
[root@localhost ~]# cd /tmp/
[root@localhost ~]# yum localinstall VMwareTools-7.7.6-203138.i386.rpm
[root@localhost ~]# /etc/yum.conf
gpgcheck=1 ← 元に戻す

一旦、サーバを停止しvmxファイルを変更します。

tools.syncTime = "TRUE" ← TRUEに変更

サーバを再度起動し、grubの設定を変更します。
このパラメータの追加(divider=10)はCentOS5.7では合った方が精度が良いよ?とナレッジに記載あったので追加しました。
VMware KB: Timekeeping best practices for Linux guests.

[root@localhost ~]# vi /boot/grub/grub.conf
kernel /vmlinuz-2.6.18-274.el5 ro root=/dev/VolGroup00/LogVol00 divider=10

ntpdインストール

[root@localhost ~]# yum install ntp
[root@localhost ~]# vi /etc/ntp.conf 
tinker panic 0
restrict 127.0.0.1
restrict default kod nomodify notrap
server 0.vmware.pool.ntp.org
server 1.vmware.pool.ntp.org
server 2.vmware.pool.ntp.org
driftfile /var/lib/ntp/drift

[root@localhost ~]# vi /etc/ntp/step-tickers 
0.vmware.pool.ntp.org
1.vmware.pool.ntp.org

[root@localhost ~]# service ntpd start
[root@localhost ~]# chkconfig ntpd on

インストールと設定

まずはifconfigでipを確認して、puttyまたはpoderosaで接続する。

viコマンドでvimを使うようにする

何かとvimの方が便利なので、aliasで設定

[root@localhost ~]# vi /etc/bashrc 

alias vi='vim' ← 追加

[root@localhost ~]# source /etc/bashrc 

不要なサービス停止

yum自動アップデート停止

[root@localhost ~]# /etc/rc.d/init.d/yum-updatesd stop
yum-updates を停止中:                                      [  OK  ]
[root@localhost ~]# yum remove yum-updatesd

SELinuxを無効化

[root@localhost ~]# vi /etc/sysconfig/selinux
#SELINUX=enforcing
SELINUX=disabled

iptables停止・自動起動無効

[root@localhost ~]# service iptables stop
[root@localhost ~]# chkconfig iptables off

RPMリポジトリを追加

[root@localhost ~]# rpm -import http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka
[root@localhost ~]# vi /etc/yum.repos.d/utterramblings.repo

[utterramblings]
name=Jason's Utter Ramblings Repo
baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/
enabled=0
gpgcheck=1
gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka

enabled=0にしているので、通常のyumコマンドではこのリポジトリは使われない。

使う場合は

[root@localhost ~]# yum --enablerepo=utterramblings install パッケージ
[root@localhost ~]# yum --enablerepo=utterramblings update パッケージ

とする。

再起動

[root@localhost ~]# reboot

Apache,PHP,MySQLインストール

[root@localhost ~]# yum --enablerepo=utterramblings install httpd httpd-devel php php-mbstring php-devel php-mcrypt php-pear php-mysql php-gd mysql-server

Apache,MySQLの起動と自動起動設定

[root@localhost ~]# chkconfig httpd on
[root@localhost ~]# chkconfig mysqld on
[root@localhost ~]# service httpd start
[root@localhost ~]# service mysqld start

MySQLのユーザ設定

rootのパスワードを設定して、パスワードがブランクのユーザを削除

[root@localhost ~]# mysql -u root
mysql> set password for root@localhost=password('password');
mysql> exit

[root@localhost ~]# mysql -u root -p
mysql> DELETE FROM mysql.user WHERE Password = '';
mysql> exit

Apacheの設定

sampleユーザ追加

[root@localhost ~]# adduser sample
[root@localhost ~]# su - sample
[root@localhost ~]# chmod 755 /home/sample/

[sample@localhost ~]$ mkdir ~/public_html

[sample@localhost ~]$ vi ~/public_html/phpinfo.php ← 確認用
<?php
phpinfo();


&#91;sample@localhost ~&#93;$ exit
&#91;/bash&#93;

<h4>バーチャルホスト設定</h4>

[root@localhost ~]# vi /etc/httpd/conf.d/vhosts.conf

NameVirtualHost *:80# sample<VirtualHost *:80>
        DocumentRoot /home/sample/public_html
        ServerName test.sample.com
        <Directory "/home/sample/public_html">
                Options Indexes FollowSymLinks MultiViews Includes ExecCGI
                AddType text/html .shtml
                AddHandler server-parsed .shtml
                AddHandler cgi-script .cgi .pl
                AllowOverride All
                Order allow,deny
                Allow from all
        </Directory>
</VirtualHost>

確認

[root@localhost ~]# httpd -S
VirtualHost configuration:
wildcard NameVirtualHosts and _default_ servers:
*:80                   is a NameVirtualHost
         default server test.sample.com (/etc/httpd/conf.d/vhosts.conf:5)
         port 80 namevhost test.sample.com (/etc/httpd/conf.d/vhosts.conf:5)
Syntax OK

Windowsのhostsファイル変更

C:\Windows\System32\drivers\etc\hosts

192.168.1.3       test.sample.com

http://test.sample.com/phpinfo.phpにアクセスして確認.

ここまでで一通り開発環境が出来ました。
ソースのアップはrsync等で同期すると簡単にできると思います。

Windowsからrsyncを利用する方法も書きました。
suusuke – blog – Windows で rsync を使用する.

追加

ここからは有ると便利な設定等を追記していきます。

PHP Xdebugインストール

gcc,gcc-c++インストール

[root@localhost ~]# yum -y install gcc gcc-c++

Xdebugインストール

既にphp-devel,php-pearはインストールしてある状態なのでpeclコマンドでインストール。

[root@localhost ~]# pecl install xdebug

....


Build process completed successfully
Installing '/usr/lib/php/modules/xdebug.so'
install ok: channel://pecl.php.net/xdebug-2.1.2
configuration option "php_ini" is not set to php.ini location
You should add "extension=xdebug.so" to php.ini

/usr/lib/php/modules/xdebug.soにxdebug.soがインストールされました。

php.iniに追記

/etc/php.ini

zend_extension="/usr/lib/php/modules/xdebug.so"

Time Machine のバックアップディスク変更

Lion にアップデート後バックアップ自体は正常にとれているものの、バックアップ先のインデックスを作成していますという状態が1時間から2時間くらいずっと続き、Time Machine が終わらないという状態になっていました。

Macbook の CPU はそれほど使用されてないので、無視していたのですが NAS の ハードディスクがカリカリうるさいのが気になったので対応することにしました。

結果的に既存のバックアップはそのままにして、バックアップ先を新規に作成してそちらにバックアップするように変更しました。

何が起きているのか?

Lion からTime Machineのバックアップ先もSpotlightがインデックスを作成するようになったようで、どうもそのインデックスを作成する作業で時間がかかっているみたい。

system.logに以下のログが出まくる。。。

com.apple.backupd[2811]: Waiting for index to be ready (100)

試したこと

Time Machineの自動バックアップを解除後、Spotightのインデックスを最作成してみたが状況変わらず。

[suusuke@macbook /]$ sudo mdutil -E /

仕方なく、バックアップ先を変更することに。

一番初めのバックアップは時間かかりましたが、二回目以降は差分だけバックアップ取られてインデックスの作成に時間がかるという事は無くなりました。

サーバが重い時の負荷の正体を突き止める

WEB+DB PRESS Vol.65|gihyo.jp … 技術評論社.

WEB+DB PRESS の特集1「WEBエンジニアが知るべきインフラの基礎知識」が非常にまとまってて良かった。

闇雲にtopコマンドとかネットで調べながら調査してたので今後のためにもメモ。

ロードアベレージ(忙しさの度合い)

uptimeコマンドを使って見る。

[root@suusuke ~]# uptime 
 22:27:30 up 202 days, 18:48,  1 user,  load average: 0.07, 0.15, 0.08

0.07という数字は処理を実行したいが、何かしらの処理で実行できなくて待たされている状態のプロセス数

何かしらの要因とは?

  • 他のプロセスにCPUが使われていて、空くのを待っている状態(CPU使用率)
  • ディスクに読み書き要求を発行してその結果を待っている状態(I/O待ち率)

CPU使用率とI/O待ち状態

sarコマンドを使って見る。

インストール

[root@suusuke ~]# sudo yum install sysstat
[root@suusuke ~]# sudo service sysstat start

CPU使用率のレポート(-u)を3秒ごとに10回表示して終了する。

[root@suusuke ~]# sar -u 3 10
Linux 2.6.18-194.3.1.el5.028stab069.6  	2011年10月24日

22時26分12秒       CPU     %user     %nice   %system   %iowait    %steal     %idle
22時26分15秒       all      0.00      0.00      0.00      0.00      0.00    100.00
22時26分18秒       all      0.17      0.00      0.00      0.00      0.00     99.83
22時26分21秒       all      0.00      0.00      0.00      0.00      0.00    100.00
22時26分24秒       all      0.00      0.00      0.00      0.00      0.00    100.00
22時26分27秒       all      0.00      0.00      0.00      0.00      0.00    100.00
22時26分30秒       all      0.00      0.00      0.00      0.00      0.00    100.00
22時26分33秒       all      0.00      0.00      0.00      0.00      0.00    100.00
22時26分36秒       all      0.00      0.00      0.00      0.00      0.00    100.00
22時26分39秒       all      9.00      0.00      0.33      0.50      0.00     90.17
22時26分42秒       all      0.00      0.00      0.00      0.00      0.00    100.00
平均値:        all      0.92      0.00      0.03      0.05      0.00     99.00
%user
ユーザ空間でCPUが使われた時間の割合
%nice
優先度を変更されたプロセスにより、ユーザ空間でCPUが使われた時間の割合
%system
カーネル空間でCPUが使われた時間の割合
%iowait
CPUがディスクI/Oの結果を待っていた時間の割合
%steal
仮想サーバがCPUを使って待たされていた時間の割合
%idle
ディスクI/O街以外で、CPUが何もしないで待っていた時間の割合

%systemも%userも低く、%iowaitが高い場合

物理搭載メモリ量を超えてスワップが大量に発生している可能性がある。
sar -Wでスワップインとスワップアウトの状況
freeでシステム全体のメモリ使用状況
topでメモリ使用率順でソート後メモリを消費しているプロセスを特定する

%systemが高く、%iowaitも高い場合

「I/O待ち状態」となっている。
psでSTATの項目がDのものを探し特定する。
Dは割り込み不可能な待機状態を意味する。

%userが高い場合

「CPU使用率」が高い。
topでCPU使用率の高い順にソートして特定する。
また、psでプロセスの情報を見る。

[root@suusuke ~]# top

top - 22:33:23 up 202 days, 18:54,  1 user,  load average: 0.20, 0.11, 0.07
Tasks:  26 total,   1 running,  25 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.2%us,  0.0%sy,  0.0%ni, 99.8%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   2097152k total,   272144k used,  1825008k free,        0k buffers
Swap:        0k total,        0k used,        0k free,        0k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND    

負荷のまとめチャート

「体系的に学ぶ 安全なWebアプリケーションの作り方」の仮想マシンを VMware Server で動かす

電子書籍ファンのための出版社直営電子書籍モール「ブックパブ」.

購入して初めはただ読んでいたのですが、折角VMware Playerのイメージも付いているので実行して試してみたくなりました。

既に、Windowsマシンには VMware Server 2 がインストールされているのでそれにイメージを追加すれば動くと思ったのですが、動かず...

次に素直に VMware Player をインストールしようとしましたが何とも共存できない?のか VMware のプロセスを切っている状態でも VMware のプロセスを切って下さいとアラートが出てインストールできない。

そこで、VMware vCenter Converter Standalone Client という素晴らしいソフトが有る事を知ったのでそれで、VMware Server 2 用のイメージに変換してみました。

VMware Player 用のイメージの変換

まずは、VMware vCenter Converter、物理マシンから仮想マシンへの変換. から VMware vCenter Converter Standalone Client をダウンロードインストールします。

「マシンの変換」からソースとなるVMware Player のイメージファイルを指定して、出力は VMware Server 2.0 のイメージを指定してやると1,2分でイメージファイルが出来上がります。

VMware Server にイメージの追加

VMware Server の管理画面(WEB)からイメージを追加します。
Firefox、IE9ではうまく管理画面が動かなかったので、仕方なくIE Testerでイメージを追加しました。

メニューの「Virtual Machine」⇒「Add Virtual Machine To Inventory」から変換したイメージファイルをしてして、イメージを起動します。

IPさえ分かればputtyやpoderosaから操作できるので、IPの確認。

あれ?eth0 が無い。

「体系的に学ぶ 安全なWebアプリケーションの作り方(wasbook)」の仮想マシンを mac の VirtualBox で動かす – techlog.

ViretualBoxで動かす方法を書いてる方が居たのでそちらを参考に。

root@wasbook:~# vi /etc/network/interfaces

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth1 ←eth1に変更
iface eth1 inet dhcp ←eth1に変更

root@wasbook:~# /etc/init.d/networking restart ←network再起動
root@wasbook:~# ifconfig -a
eth1      Link encap:Ethernet  HWaddr 00:0c:29:b4:51:86  
          inet addr:192.168.1.2  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:feb4:5186/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:378 errors:0 dropped:0 overruns:0 frame:0
          TX packets:241 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:38473 (38.4 KB)  TX bytes:32978 (32.9 KB)
          Interrupt:18 Base address:0x2000 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:53 errors:0 dropped:0 overruns:0 frame:0
          TX packets:53 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:17593 (17.5 KB)  TX bytes:17593 (17.5 KB)

poderosaからも無事繋がりましたー。

CakePHPでコンポーネントのテスト

モデルを使用しないコンポーネント用のテストする方法を書きたいと思います。
CakePHPは1.3.5を使用しています。

テスト(Testing) :: CakePHPによる作業の定石 :: マニュアル :: 1.3コレクション.

simpletestインストール

マニュアルにも書いてある通りsimpletestはCakePHPに含まれないのでSimpleTest – Unit Testing for PHP.からダウンロードしてきてvendorsにフォルダをコピーしておきます。
※1.3.5ではsimpletest1.1系は動かないようだったので、1.0系をインストールしました。

モデルを使う場合はapp/config/database.phpにテスト用のデータベースの設定を書いておいた方が良いですが今回は使用しないので特に書きません。

http://text.example.com/test.phpでCakePHPに組み込まれているテストケースを実行できます。
私の場合は、1つCakePHPに複数appをディレクトリ毎に分けているので以下のようにtest.phpを変更しました。

set_time_limit(0);
ini_set('display_errors', 1);
/**
 * Use the DS to separate the directories in other defines
 */
	if (!defined('DS')) {
		define('DS', DIRECTORY_SEPARATOR);
	}
/**
 * These defines should only be edited if you have cake installed in
 * a directory layout other than the way it is distributed.
 * When using custom settings be sure to use the DS and do not add a trailing DS.
 */
    if (PHP_OS == "WIN32" || PHP_OS == "WINNT") {
        define('C', 'C:');
    } else {
        define('C', '');
    }
/**
 * The full path to the directory which holds "app", WITHOUT a trailing DS.
 *
 */
	if (!defined('ROOT')) {
		//define('ROOT', dirname(dirname(dirname(__FILE__))));
		define('ROOT', C.DS.'home'.DS.'example'.DS.'cake_app');
	}
/**
 * The actual directory name for the "app".
 *
 */
	if (!defined('APP_DIR')) {
		//define('APP_DIR', basename(dirname(dirname(__FILE__))));
		define ('APP_DIR', 'user');
	}
/**
 * The absolute path to the "cake" directory, WITHOUT a trailing DS.
 *
 */
	if (!defined('CAKE_CORE_INCLUDE_PATH')) {
		//define('CAKE_CORE_INCLUDE_PATH', ROOT);
		define('CAKE_CORE_INCLUDE_PATH', C.DS.'home'.DS.'example'.DS.'cake_core');
	}

/**
 * Editing below this line should not be necessary.
 * Change at your own risk.
 *
 */
if (!defined('WEBROOT_DIR')) {
	define('WEBROOT_DIR', basename(dirname(__FILE__)));
}
if (!defined('WWW_ROOT')) {
	define('WWW_ROOT', dirname(__FILE__) . DS);
}
if (!defined('CORE_PATH')) {
	if (function_exists('ini_set') && ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get('include_path'))) {
		define('APP_PATH', null);
		define('CORE_PATH', null);
	} else {
		define('APP_PATH', ROOT . DS . APP_DIR . DS);
		define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
	}
}
if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) {
	trigger_error("CakePHP core could not be found.  Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php.  It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
}

$corePath = App::core('cake');
if (isset($corePath[0])) {
	define('TEST_CAKE_CORE_INCLUDE_PATH', rtrim($corePath[0], DS) . DS);
} else {
	define('TEST_CAKE_CORE_INCLUDE_PATH', CAKE_CORE_INCLUDE_PATH);
}

if (Configure::read('debug') < 1) {
	die(__('Debug setting does not allow access to this url.', true));
}

require_once CAKE_TESTS_LIB . 'cake_test_suite_dispatcher.php';

$Dispatcher = new CakeTestSuiteDispatcher();
$Dispatcher->dispatch();

コンポーネントのテスト

coupon.phpという外部APIを使用してクーポン情報を取得するコンポーネントを例にします。
appのルートディレクトリはtest.phpにある通り/home/example/cake_app/user/になります。

ディレクトリ構成は下記のような形になります。

user
│
├─controllers
│ │
│ └─components
│         coupon.php(テスト対象コンポーネント)
└─tests
  ├─cases
     │
     ├─components
          coupon.test.php(テストクラス)

クーポンコードをパラメーターにクーポン情報を取得するCouponComponent->get()が有る場合に正しく取得できたかどうかのテストケースは以下のようになります。

<?php
App::import('Component', 'Coupon');

class CouponComponentTestCase extends CakeTestCase {
    function setUp () {
        $this->component = new CouponComponent();
    }

    function test_get () {
        $result = $this->component->get(array('coupon_code' => 'xxxx'));

        $xml = new Xml($result);
        $data = Set::reverse($xml);

        $this->assertEqual('success', $data['Result']['mstatus']);
    }

}

test.phpから実行確認も可能ですし、コンソールからも実行確認可能です。

よく使うhttpdコマンドのオプション

httpd -t
設定ファイルのシンタックスチェックを行う。『 Syntax OK 』と表示されれば問題なし。
httpd -S
読み込まれるバーチャルホストの設定を一覧表示して、シンタックスチェックを行う。
httpd -M
読み込まれるモジュールを一覧表示して、シンタックスチェックを行う。

個人的に一番使うのはhttpd -Sかな。