hnakamur’s blog

ものすごい勢いで忘れる私のために未整理でもいいからとりあえずメモ

2010-12-29

ddでbs=1Mとbs=1Gの速度比較

$ time dd if=/dev/zero of=20G_by_1M.img bs=1M count=20480
20480+0 records in
20480+0 records out
21474836480 bytes (21 GB) copied, 533.695 seconds, 40.2 MB/s

real 8m56.525s
user 0m0.097s
sys 2m26.717s

$ time dd if=/dev/zero of=20G_by_1G.img bs=1G count=20
20+0 records in
20+0 records out
21474836480 bytes (21 GB) copied, 682.891 seconds, 31.4 MB/s

real 11m31.144s
user 0m0.001s
sys 2m53.768s

$ ls -l *.img
-rw-rw-r-- 1 hnakamur hnakamur 21474836480 Dec 29 19:01 20G_by_1G.img
-rw-rw-r-- 1 hnakamur hnakamur 21474836480 Dec 29 18:50 20G_by_1M.img

bs=1Gは大きすぎなんですかね。
仮想イメージのようにGB単位のときはbs=1Gのほうがわかりやすいので、多少遅くても我慢するか悩むところです。

sshのauthorized_keysでのアクセス元IP制限

Manual Pages: sshd(8)
http://www.openbsd.org/cgi-bin/man.cgi?query=sshd&sektion=8

行頭にfrom="pattern-list"をつけておけばよい。
・ホスト名またはIPアドレス
・192.168.0.*などのパターン
・192.168.0.0/24などのCIDR表記(OpenSSH5.1以降 www.openssh.org/txt/release-5.1

CentOS5.5のopensshは4.3p2-41.el5_5.1であるため、CIDR記法で書いてもログインできませんでした。
CentOS5.5で試したところホスト名では
Permission denied (publickey,gssapi-with-mic).
が出てしまいました。IPアドレスならOKでした。実運用でもIPアドレスを指定するほうが確実そうなので放置することにします。

chkconfig --addを忘れて/etc/rc0.d/K*が作られずはまった件のメモ

例としてfooというサービスの場合、chkconfig --add fooをしなくてもchkconfig foo onだけで起動時に実行されてしまうが、/etc/rc0.d/K*fooは作られないためシャットダウン時には実行されない。忘れずにchkconfig --add fooを実行すること。

2010-12-22

CentOS x86_64で*.i386をインストール対象外にする

/etc/yum.confの[main]に以下の行を追加。
exclude=*.i?86

既にインストールされてしまっているパッケージは以下のコマンドで削除。
yum remove \*.i386

2010-12-19

CentOSのKVMのゲストOSに2枚目のネットワークカードを追加

ゲストOSが1枚のネットワークカードでブリッジで動いていることとホスト側では2枚のネットワークカードの両方をブリッジに設定済みであることを前提とします。
なお、この方法は試しにやってみたらできたという手順なので、もっとよい手順があるかもしれません。

ゲストOSで/etc/sysconfig/network-scripts/ifcfg-eth0をコピーしてifcfg-eth1を作成し、適宜編集。MACアドレスを適当に変更(但し頭の54:52:00:は変えずに下3オクテットのみを変えます。上3オクテットはKVMで決まっている値のため(ソース失念))。
また/etc/sysconfig/networkのGATEWAYも編集(hnakamur’s blog: CentOSでネットワークカード2枚挿しの場合のゲートウェイの設定を参照)。

ゲストOSをシャットダウン。

ホストOSでドメインのxml(/etc/libvirt/qemu/<ドメイン名>.xml)を編集。interfaceのタグをコピペして、mac addressを先程ゲストOSでeth1に割り当てた値にし、bridgeをホストのもう一つのブリッジデバイス(br1)にします。
<domain type='kvm'>
  …(略)…
  <devices>
    …(略)…
    <interface type='bridge'>
      <mac address='54:52:00:4f:0a:85'/>
      <source bridge='br0'/>
    </interface>
    <interface type='bridge'>
      <mac address='54:52:00:4f:0a:86'/>
      <source bridge='br1'/>
    </interface>
    …(略)…
  </devices>
</domain>

以下のコマンドで設定を反映。
# virsh define /etc/libvirt/qemu/<ドメイン名>.xml

CentOSでネットワークカード2枚挿しの場合のゲートウェイの設定

この説明ではeth0をLAN側、eth1をWAN側とします。
GATEWAYの設定は/etc/sysconfig/network-scripts/のifcfg-eth0とifcfg-eth1ではコメントアウトして/etc/sysconfig/networkにeth1のGATEWAYを書く(GATEWAYDEVは書かなくても大丈夫でした)。
DNS1、DNS2の設定は/etc/sysconfig/network-scripts/のifcfg-eth0ではコメントアウトしてifcfg-eth1では有効にする。

その後以下のコマンドで設定を反映。
# /etc/init.d/network reload

参考:
Reference Guide
ルータにするための基本設定

CentOSでネットワークをブリッジにする手順

bridge-utilsのインストール

bridge-utilsをインストールするのを忘れずに。
# yum install bridge-utils

設定ファイルの編集

以下の説明のMACアドレスとIPアドレスは実際の環境に合わせて適宜読み替えてください。
/etc/sysconfig/network-scripts/以下のifcfg-eth0を修正し、ifcfg-br0を作成します。

修正前

/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
HWADDR=00:01:02:03:04:05
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.100
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
DNS1=192.168.0.1


修正後

/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
HWADDR=00:01:02:03:04:05
ONBOOT=yes
BRIDGE=br0
#BOOTPROTO=static
#IPADDR=192.168.0.100
#NETMASK=255.255.255.0
#DNS1=192.168.0.1
#GATEWAY=192.168.0.1

/etc/sysconfig/network-scripts/ifcfg-br0
DEVICE=br0
TYPE=Bridge
ONBOOT=yes
BRIDGE=br0
BOOTPROTO=static
IPADDR=192.168.0.100
NETMASK=255.255.255.0
DNS1=192.168.0.1
#HWADDR=00:01:02:03:04:05


設定を反映

# /etc/init.d/network reload
リモートから操作している場合は端末の接続が切れるので、端末を閉じて別途開きなおします。
ただしすぐには繋がりませんでした。20~30秒待ってから接続すると大丈夫でした。

"Shutting down interface br0:"で表示が10秒程度止まりますが、その後"Bringing up interface br0:"も表示されて元の端末で引き続き作業可能でした。

2010-12-18

CentOS x86_64でphpをソースからビルド

Apacheもソースからビルドして/usr/local/apache2に入れた場合の話です。

sudo yum install mysql-devel.x86_64
tar jxf php-5.3.4.tar.bz2
cd php-5.3.4
./configure --with-apxs2=/usr/local/apache2/bin/apxs --enable-mbstring --with-libdir=lib64 --with-mysql --with-pdo-mysql

2010-12-16

LVMを使用しているKVMのゲストのディスクイメージ拡張

参考:
あやの日常あるいは平穏な日々: 【CI鯖】LVM拡張を試みる
CentOS で LVM 物理/論理ボリュームサイズを縮小する - maruko2 Note.
2010-12-29追記:こちら↑を参考にスワップパーティションは一旦削除してから拡張してその後スワップパーティションを作り直すほうがよいです。そうしない場合system-config-lvmで見るとLogVol00の物理領域がLogVol01を挟んで2つに分かれてしまいました。

イメージファイルの拡張


まずイメージファイルのフォーマットを確認します。
# qemu-img info /var/lib/libvirt/images/vm1.img
実行結果はこんな感じ。
image: /var/lib/libvirt/images/vm1.img
file format: raw
virtual size: 10G (10737418240 bytes)
disk size: 7.5G
もしfile format: rawとなっていなければ、qemu-img convertでrawに変換します。

10Gに6G追加する場合は以下のようにします。イメージファイルのバックアップをとった上で、ddのseekを使って末尾に6Gの領域を追加します。
# cd /var/lib/libvirt/images
# cp vm1.img vm1.img.bak
# dd if=/dev/zero of=vm1.img bs=1G count=6 seek=10


# cd /var/lib/libvirt/images
# mv vm1.img vm1.img.bak
# dd if=/dev/zero of=zero6G.img bs=1G count=6
# cat vm1.img.bak zero6G.img > vm1.img



hnakamur’s blog: KVMのゲストのHDDをマウントしてLive CDからブートの手順でLive CDからブートします。

テキストモード「Boot (text mode)」を選択し、ログインプロンプトが出たらrootでパスワード無しでログインします。

fdisk /dev/hda
Linux LVMのパーティションを一旦削除して、サイズを拡大して作り直し、パーティションタイプをLinux LVM(8e)にします。
/dev/hda2がLinux LVMの場合は、p、d、2、n、p、2、Enter、Enter、t、2、8e、w、qとなります。

再起動します。
# reboot

物理ボリュームの拡張


テキストモード「Boot (text mode)」を選択し、ログインプロンプトが出たらrootでパスワード無しでログインします。

現在の物理ボリュームの状態を確認します。
# pvs

/dev/hda2を拡張します。
# pvresize /dev/hda2

変更後の物理ボリュームの状態を確認します。
# pvs

論理ボリュームの拡張


ここではVolGroup00/LogVol00を拡張します。私の環境ではこれがルートパーティションになっています。

現在の論理ボリュームの状態を確認します。
# lvs

論理ボリュームを拡張します。
# lvextend -L+6G /dev/VolGroup00/LogVol00

変更後の論理ボリュームの状態を確認します。
# lvs

ファイルシステムの拡張


マウント解除。
# umount /dev/VolGroup00/LogVol00

ファイルシステムチェック。
# e2fsck -f /dev/VolGroup00/LogVol00

ファイルシステムのリサイズ。
# resize2fs /dev/VolGroup00/LogVol00

Live CDをシャットダウン

# shutdown -h now

KVMのゲストのHDDをマウントしてLive CDからブート

Live CDの入手と配備

CentOS-5.5-x86_64-LiveCD.isoをCentOSミラーサイトからダウンロードして/var/lib/libvirt/images/に置きます(場所はどこでも可)。

KVMでゲストを起動

libvirtで起動しようと試みましたが失敗(後述)したので、qemu-kvmコマンドで起動します。
/usr/libexec/qemu-kvm -m 1024 -smp 1 -boot d \
-drive file=/var/lib/libvirt/images/vm1.img,if=ide \
-cdrom /var/lib/libvirt/images/CentOS-5.5-x86_64-LiveCD.iso \
-vnc localhost:1

この後UltraVNCなどのvncviewerで接続します。

(失敗メモ) libvirtでCD-ROMからブートを試みるも失敗


/etc/libvirt/qemu/vm1.xmlを以下のように書き換えます。
<domain type='kvm'>
  <name>ora1</name>
  <uuid>97f129e6-9b87-9998-0247-d573d774be81</uuid>
  <memory>2097152</memory>
  <currentMemory>2097152</currentMemory>
  <vcpu>1</vcpu>
  <os>
    <type arch='x86_64' machine='rhel5.4.0'>hvm</type>
    <boot dev='cdrom'/>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <pae/>
  </features>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/libexec/qemu-kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' cache='none'/>
      <source file='/var/lib/libvirt/images/vm1.img'/>
      <target dev='hda' bus='ide'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu'/>
      <source file='/var/lib/libvirt/images/CentOS-5.5-x86_64-LiveCD.iso'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
    </disk>
    <interface type='network'>
      <mac address='54:52:00:54:37:df'/>
      <source network='default'/>
    </interface>
    <serial type='pty'>
      <target port='0'/>
    </serial>
    <console type='pty'>
      <target port='0'/>
    </console>
    <input type='mouse' bus='ps2'/>
    <graphics type='vnc' port='5901' autoport='no'/>
  </devices>
</domain>
変更内容は
<boot dev='cdrom'/>

<disk type='file' device='cdrom'>
      <driver name='qemu'/>
      <source file='/var/lib/libvirt/images/CentOS-5.5-x86_64-LiveCD.iso'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
    </disk>
の追加です。


上記の定義を反映。
# virsh define /etc/libvirt/qemu/vm1.xml

起動してコンソールに接続
# virsh start vm1; virsh console vm1

gparted-live-0.7.1-1.isoもダウンロードして/var/lib/libvirt/images/に配置し、
<source file='/var/lib/libvirt/images/CentOS-5.5-x86_64-LiveCD.iso'/>

<source file='/var/lib/libvirt/images/gparted-live-0.7.1-1.iso'/>
に変えてみても同じでした。

おそらくCentOS-5.5-x86_64-LiveCD.isoとgparted-live-0.7.1-1.isoはシリアルコンソールで繋がるように作られていないということなのかと思います。

2010-12-15

Oracleのデータベースをsysアカウントでエクスポートするときのコマンド

単にシングルクォートで囲むのはエラーになりました。Linux x86環境での話。
exp \"SYS/oraAdmin AS SYSDBA\" full=y file=db1.dmp log=exp_db1.log

2010-12-13

CentOSでheartbeatでVIP引き継ぎ(その2)

hnakamur’s blog: CentOSでheartbeatでVIP引き継ぎをまたやってみて少し知識が増えたので追記。

heartbeatのインストール時エラーの回避方法


heartbeatのインストール時にエラーになる件は、一旦heartbeat-pilsとheartbeat-stonithを入れてからheartbeatを入れれば回避できるとのこと。
sudo yum install heartbeat-pils heartbeat-stonith
sudo yum install heartbeat

参考:ベリラボ - wiki - CentOS52_heardbeatインストール、初期設定


/etc/ha.d/haresources

以下のようにネットワークアドレスのビット数やデバイスも指定可能。詳しくはサンプルファイル(/usr/share/doc/heartbeat-2.1.3/haresources)参照。
vm1 IPaddr::192.168.101.20/24/eth0

なお、このIPaddrは/etc/ha.d/resource.d/に置かれているスクリプト名で、手動でも実行可能です。

手動VIP追加
sudo /etc/ha.d/resource.d/IPaddr 192.168.101.20/24/eth0 start
手動VIP削除
sudo /etc/ha.d/resource.d/IPaddr 192.168.101.20/24/eth0 stop

ERROR: Setup problem: Couldn't find utility /bin/gawkの対処法

CentOSをインストール時にBaseのチェックもはずして最小構成にした場合の話です。

heartbeatの実行中に/var/log/ha-logに以下のエラーが発生しました。
ResourceManager[2873][2943]: 2010/12/13_16:08:00 info: Running /etc/ha.d/resource.d/IPaddr 192.168.101.20 start
IPaddr[2962][2976]: 2010/12/13_16:08:00 ERROR: Setup problem: Couldn't find utility /bin/gawk
IPaddr[2945][2977]: 2010/12/13_16:08:00 ERROR:  Program is not installed
R

gawkが無いとインストールしようとしましたが、すでに入っていました。

ググるとこちらに対処法が載ってました。
VIP not appearing when heartbeat starts | Linux-HA | Users

whichをインストールすれば解決します。
sudo yum install which

実験用監視スクリプト


#!/bin/sh

url=http://192.168.101.20/
timeout=2

while :
do
  response=`curl -s -S --connect-timeout $timeout $url`
  if [ $? -ne 0 ]
  then
    break
  fi

  echo "`date +%Y-%m-%dT%k:%M:%S` $response"

  sleep 1
done

2010-12-07

手動でVIP切り替え実験

192.168.0.0/24のネットワークで
192.168.0.11 host1
192.168.0.12 host2
192.168.0.12 host3
で192.168.0.10をVIPとして使う場合。
(実際は他のネットワークで実験したのを読み替えてこの記事を書いているので間違っている可能性もあります)

まず、host1にVIPを追加。
host1# ip addr add 192.168.0.10/24 dev eth0

確認。
host1# ip addr show

host3$ curl http://192.168.0.10/
# ⇒host1のページが表示される

VIPをhost1で削除して、host2に追加。
host1# ip addr del 192.168.0.10/24 dev eth0
host2# ip addr add 192.168.0.10/24 dev eth0
host2# arping -q -A -I eth0 -c 1 192.168.0.10
arpingでGratuitous ARPをうつ方法は
http://linux-ip.net/html/ether-arp.html
の"Example 2.2. Gratuitous ARP reply frames"を参考にしました。
send_arpというコマンドもあるそうですが標準ではインストールされていないのに対して、arpingはインストールされているのでこちらを使うほうがいいです。

確認。
host3$ curl http://192.168.0.10/
# ⇒host2のページが表示される

2010-12-04

CentOS5.5でext3ファイルシステムをext4に変換

参考:
[1] FractalizeR’s WebSite » CentOS: Migrating root (and any other) filesystem from ext3 to ext4
[2] Ext4 Howto - Ext4

# yum update
# yum install e4fsprogs

まずはrootパーティション以外で実験。/etc/fstabを編集し対象パーティションのファイルシステムタイプをext3からext4に修正。ext3のファイルシステムはext4としてもマウントできる。ext4 - Wikipedia参照。
# vi /etc/fstab

ext4対応のinitrdを作成。
# mv /boot/initrd-`uname -r`.img /boot/initrd-`uname -r`.img.old
# mkinitrd -v --with=ext4 /boot/initrd-`uname -r`.img `uname -r`

作成したinitrdを使うため再起動。
# reboot

再起動したら対象のパーティション(ここでは/dev/sdc2とします)をアンマウントして、ext4に変換。tune2fsではなくtune4fsを使用していることに注意。オプションの意味は[1]参照。
# umount /dev/sdc2
# tune4fs -O extents,uninit_bg,dir_index,flex_bg -m 1 /dev/sdc2
"Please run e4fsck on the filesystem."と言われるので実行します。[1]ではe4fsckではなくfsckにしていますが、ここではe4fsckにしてみます。オプションは[1]を真似します。
# e4fsck -pvfDC0 /dev/sdc1
/dev/sdc1: One or more block group descriptor checksums are invalid.  FIXED.
/dev/sdc1: Group descriptor 0 checksum is invalid.

/dev/sdc1: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
        (i.e., without -a or -p options)
すると[1]に書かれていた通り、-pオプションを外すように言われるので外して再実行。
# e4fsck -vfDC0 /dev/sdc1
すると
e4fsck 1.41.9 (22-Aug-2009)
One or more block group descriptor checksums are invalid.  Fix?
と聞かれるのでyを押します。あとはしばらく待ちます。
無事変換が終わったらマウントします。
# mount /dev/sdc1

TeraTermでの操作ログを接続先・日付毎に保存する

Tera Termでの自動ログインのように接続先毎にショートカットを作るのが前提です。あとは、接続先毎にログファイルの設定を変えたiniファイルを作っておいてtterm.exeの/Fオプションで指定すればOKです。

以下はsunshine11というホスト名用の設定です。

[Setup]/[Additional Settings]
[Log]タブ
Default log file name:tterm_sunshine11-%Y-%m-%d.log
Default log save folder:C:\Users\hnakamur\Documents\TeraTerm
Auto start logging:チェックオン
[Setup]/[Save setup]でC:\Users\hnakamur\Documents\TeraTerm\tterm_sunshine11.iniに保存します。

tterm.exeのショートカットは以下のようにします。
"C:\Program Files (x86)\teraterm\ttermpro.exe" /M=C:\Users\hnakamur\Documents\TeraTerm\sunshine11_local.ttl /F=C:\Users\hnakamur\Documents\TeraTerm\tterm_sunshine11.ini

tterm_sunshine11.iniの内容は以下の通りです。
connect '192.168.11.101:22 /ssh /2 /auth=pageant /user=hnakamur'

Linuxのscreenのログと違って、色つきlsのエスケープシーケンスは省いてログ出力されるので後から参照する際に便利そうです。

2010-11-19

KVMでブリッジを使う設定でCentOSをインストール

参考:CentOS/KVMによるサーバ仮想化 - OSSでLinuxサーバ構築


前提

DNSサーバ兼DHCPサーバがLAN内に存在。IPアドレスは192.168.0.1とします。

ホスト、ゲストとも固定IPを使用。IPアドレスはそれぞれ192.168.0.2、192.168.0.3とします。


ホスト側のネットワーク変更


/etc/sysconfig/network-scripts/ifcfg-br0を作成。

# Bridge
DEVICE=br0
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.0.2
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
DNS1=192.168.0.1
TYPE=Bridge
DELAY=0

/etc/sysconfig/network-scripts/ifcfg-eth0を編集(HWADDRは編集前の値をそのまま残す)。

DEVICE=eth0
TYPE=Ethernet
HWADDR=00:00:00:00:00:00
ONBOOT=yes
BRIDGE=br0


以下のコマンドを実行してネットワーク再起動。

# /etc/init.d/network restart

ゲストのブリッジ用にホストのiptablesを変更。これを忘れるとゲストで名前解決が出来ないので注意。

/etc/sysctl.confを編集して以下の設定を追加または変更。

net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0

以下のコマンドを実行して設定を即座に反映。

# sysctl -p /etc/sysctl.conf
# /etc/init.d/libvirtd reload

以下のコマンドでゲストOSをインストール(一旦DHCPでインストールします)。

# virt-install --connect qemu:///system -n vm1 -r 512 --vcpus=1 \
 --disk path=/var/lib/libvirt/images/vm1.img,size=100 \
 --os-type linux --accelerate \
 --bridge=br0 \
 --location='http://ftp.riken.jp/Linux/centos/5.5/os/x86_64' \
 --extra-args='console=tty0 console=ttyS0,115200n8'

インストールが終わったら、virsh consoleなどで繋いで、ゲストの/etc/sysconfig/network-scripts/ifcfg-eth0を以下のように書き換え(HWADDRは編集前の値をそのまま残す)。

DEVICE=eth0
BOOTPROTO=none
HWADDR=00:00:00:00:00:00
ONBOOT=yes
NETMASK=255.255.255.0
IPADDR=192.168.0.3
GATEWAY=192.168.0.1
DNS1=192.168.0.1
TYPE=Ethernet

以下のコマンドでゲストのネットワークを再起動。

# /etc/init.d/network restart

UltraVNCのvncviewrとPuttyのplinkでVNCサーバに接続する手順

前提

  • user1でhost1に接続する。
  • pageantを使用。
  • vncサーバはlocalhostだけlistenするようにしておく。

準備

C:\Program Files\PuTTY\plink.exeのショートカットを作成し、プロパティでリンク先を以下のように編集。

"C:\Program Files\PuTTY\plink.exe" -ssh -agent -N -L 5900:localhost:5900 user1@host1

-Lの引数はローカルポート、リモートホスト、リモートポート。vncサーバはlocalhostだけlistenするようにしてある前提なのでhost1ではなくlocalhostを指定する必要あり。


UltraVNCのダウンロードページからvncviewer最新版をダウンロードしてzipを展開。


接続手順

  1. 上記で作成したplinkのショートカットを起動。
  2. vncviewer.exeを起動して以下のように入力し「Connect」を押す。
    • VNC Server:にはlocalhostと入力。
    • 初回のみ「Options」押す→「Japanese Keyboard」にチェック→「OK」押す→「Save connection settings as default」チェック

切断手順

  1. vncviewerのウィンドウを閉じる。
  2. plinkのウィンドウを閉じる。

CentOSにvncでGUIログインする設定

参考1: HowTos/VNC-Server - CentOS Wiki

参考2: CentOSでxinetdでVNCサーバーでGUIログイン - bufferings


「GNOME デスクトップ環境」パッケージグループがインストール済みであることが前提(ログイン後GNOME環境を使いたいので)。確認は以下のコマンドで。

# env LANG=C yum grouplist hidden

Installed Groups:のセクションにGNOME Desktop Environmentがあればインストール済み。なければ以下のコマンドでインストール。

# yum groupinstall "GNOME Desktop Environment"

gdmが入っていなければインストール。

# yum install gdm

vnc-serverパッケージをインストール。

# yum install vnc-server

パッケージではHowTos/VNC-Server - CentOS Wikiの「2. Configuring un-encrypted VNC」に説明されているようなVNCの利用者毎にポートを分けるような設定になっている。この方式ではVNCのパスワードを入れるとGUIでログイン済みの状態になる。しかし、ユーザ毎にサーバ側を設定する必要があり面倒。

ここでは「5. Remote login with vnc-ltsp-config」に書かれている方式を使うことにした。ただし、vnc-ltsp-configパッケージは使わずに、CentOSでxinetdでVNCサーバーでGUIログイン - bufferingsを参考に手動で設定を行う。


xinetdからvncサーバを実行するのでvncserverは止めて自動起動も止める。

# /etc/init.d/vncserver stop
# chkconfig vncserver off

xinetdパッケージをインストール。

# yum install xinetd

/etc/servicesに以下の行を追加。

vnc-5900        5900/tcp                        # vnc

以下の内容で/etc/xinetd.d/vncを作成。

service vnc-5900
{
        disable = no
        socket_type     = stream
        wait            = no
        user            = nobody
        group           = tty
        server          = /usr/bin/Xvnc
        server_args     = -inetd -query localhost -once -geometry 1024x768 -depth 16 -securitytypes=none
        log_on_failure  += USERID
}

xinetd再起動。

# /etc/init.d/xinetd restart

OS起動時のランレベルを5(GUI)に変更。


/etc/inittabを編集して、id:の後の数字を5に変更。

# Default runlevel. The runlevels used by RHS are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
#
id:5:initdefault:

ランレベル3の状態で起動していたら、以下のコマンドで5に変更。

# init 5

/etc/gdm/custom.confを編集。編集箇所のみ抜粋。

[daemon]
RemoteGreeter=/usr/libexec/gdmgreeter

[security]
DisallowTCP=false

[xdmcp]
Enable=true

gdm再起動

# gdm-restart

Tera Termでの自動ログイン

参考1:Tera Termマクロ活用入門(1):各種ログインを自動化する - SourceForge.JP Magazine : オープンソースの話題満載

参考2:Tera Termのヘルプ([Help]/[Index]メニュー)


user1というユーザでhost1というホストに接続する例。pageantを使う前提。

以下の内容でC:\Program Files\teraterm\user1@host1.ttlというファイルを作成。

connect 'host1 /ssh /2 /auth=pageant /user=user1'

C:\Program Files\teraterm\ttermpro.exeのショートカットを作成し、プロパティのリンク先を以下のように変更。

"C:\Program Files\teraterm\ttermpro.exe" /M=user1@host1.ttl

pageantを起動済みなら、このショートカットを起動するだけでログインまで完了します。

2010-10-14

WindowsマシンにsvnsyncでSubversionレポジトリをミラーリングする手順

Windows用のsvnsyncを用意

Windows用SubversionはCollabNet Subversionダウンロードからダウンロードできます。svnsyncはCollabNet Subversion Command-Line Clientには含まれないので、CollabNet Subversion Edge(サーバー)をダウンロード、インストールする必要があります。

ミラー先レポジトリの作成とセットアップ

C:\svn_repo>svnadmin create PROJ
C:\svn_repo>echo exit 0 > PROJ\hooks\pre-revprop-change.bat
C:\svn_repo>svnsync init file:///svn_repo/PROJ https://remote-subversion-server.example.com/svn/PROJ

なお、file:///にfile://C:/のようにドライブを含めるとエラーになりました。試した感じではfile:///でカレントドライブのディレクトリを見ているようです。

ミラーリング実行

C:\svn_repo>svnsync sync file:///svn_repo/PROJ

ロックが残ってしまった場合の削除方法

ミラーリング実行中にCtrl+Cで止めた場合は、ロックが残ってしまい再度ミラーリングしようとすると以下のようなエラーが出ます。

C:\svn_repo>svnsync sync file:///svn_repo/PROJ
Failed to get lock on destination repos, currently held by ...

以下のコマンドでロックを開放します。

svn pdel --revprop -r 0 svn:sync-lock file:///lac_svn_repo/TECS


参考:Malachi's Server: Failed to get lock on destination repos, currently held by....

2010-10-01

CentOS5.5のyumレポジトリリストにrpmforgeを追加

hnakamur’s blog: CentOSのyumレポジトリにrpmforgeを追加の時からURLが変わってました。

参考:
RPMforge/Using - RPMRepo Wiki
AdditionalResources/Repositories/RPMForge - CentOS Wiki
http://wiki.centos.org/AdditionalResources/Repositories/RPMForge?action=show&redirect=Repositories%2FRPMForge


yum-prioritiesを導入

# yum install yum-priorities
# vi /etc/yum.repos.d/CentOS-Base.repo
[base], [addons], [updates], [extras] ... priority=1
[contrib] ... priority=2
[centosplus] needs the same priority as [base], ... but should be left disabled (enabled=0)
Third Party Repos such as rpmforge ... priority=N (where N is > 10 and based on your preference)

rpmforgeのセットアップ

# wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.1-1.el5.rf.i386.rpm
pm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt
# rpm -i rpmforge-release-0.3.6-1.el5.rf.i386.rpm
# vi /etc/yum.repos.d/rpmforge.repo

変更内容

--- /etc/yum.repos.d/rpmforge.repo      2009/08/21 09:08:58     1.1
+++ /etc/yum.repos.d/rpmforge.repo      2009/08/21 09:09:11
@@ -9,3 +9,4 @@
 protect = 0
 gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rpmforge-dag
 gpgcheck = 1
+priority = 11

設定の確認

$ sudo yum check-update

rpmforgeの行が出ればOK。

CentOSのvmにVMware Toolsのインストール

コンロールでログインした状態で[ツールのインストール]ボタンを押す。

# yum install perl
# mkdir /media/cdrom
# mount /dev/cdrom /media/cdrom
# cd /tmp
# tar zxf /media/cdrom/VMwareTools-8.4.4-301548.tar.gz
# cd vmware-tools-distrib
# ./vmware-install.pl

いろいろ聞かれるので全てリターンでデフォルト値を選択します。その後以下のコマンドを実行します。

# /etc/init.d/network stop
# rmmod pcnet32
# rmmod vmxnet
# modprobe vmxnet
# /etc/init.d/network start

表示されるメッセージによるとVMware Toolsをアンインストールしたいときは/usr/bin/vmware-uninstall-tools.plを実行すればよいそうです。

VMware Playerでvmのビープ音を消す

VMware Playerでvmのビープ音を消すには*.vmxにmks.noBeep="TRUE"を追加してvm再起動でOKです。

試したVMware Playerのバージョンは3.1.2 build-301548です。

C:\Documents and Settings\[User Name]\Application Data\VMware\preferences.iniにmks.noBeep="TRUE"を追加してVMware Playerを再起動する方法は効きませんでした。

vmwareのイメージのコピー

  1. コピー対象のゲストOSは停止しておく
  2. マイドキュメントの"My Virtual Machines"以下にあるフォルダをコピーしてリネーム
  3. VMware Playerで[ファイル]/[仮想マシンを開く]メニューで作成したフォルダ内の*.vmxを開く
  4. 追加されたvmを選んで[仮想マシン設定の編集]ボタン⇒[オプション]タブの[仮想マシン名]を適宜変更⇒[OK]ボタン
  5. [仮想マシンの再生]ボタン⇒[コピーしました]ラジオボタンを選んで[OK]ボタン

vmの順序を並び替えたい場合は、登録済みのvmを[ファイル]/[仮想マシンを開く]メニューで一番上に来るのでそれで頑張れば出来る。

2010-09-25

CentOS: PostgreSQLインストール

PostgreSQLは以前はPostgreSQL: Linux packagesの通りレポジトリを追加してインストールしていましたが、8.4ならupdatesレポジトリにあったのでそちらから入れてみました。

# yum install postgresql84-server
# /sbin/service postgresql initdb
# /etc/init.d/postgresql start
# /sbin/chkconfig postgresql on
# /sbin/chkconfig postgresql --list
postgresql      0:off   1:off   2:on    3:on    4:on    5:on    6:off

PostgreSQLのユーザとデータベース作成

# sudo su - postgres
-bash-3.2$ createuser -DRSEP user
Enter password for new role:
Enter it again:
-bash-3.2$ createdb -E utf8 -O user userdb

# vi /var/lib/pgsql/data/pg_hba.conf

127.0.0.1のidentの前の行にmd5メソッドを追加

host    all         all         127.0.0.1/32          md5
host    all         all         127.0.0.1/32          ident

# /etc/init.d/postgresql restart

接続テスト

$ psql -h localhost -U user -W userdb
Password for user user:
psql (8.4.4)
Type "help" for help.

userdb=>

CentOS: screen設定メモ

# yum install screen

$ mkdir ~/log
$ vi ~/.screenrc

escape ^Zz
autodetach on
logfile "/home/hnakamur/log/screen-%H-%Y%m%d-%n.log"
deflog on

$ vi ~/.bash_profile

以下の1行を追加

screen

参考:screenで覚えたことメモ - 半無限長キープ

CentOS: keychainでssh-agentを管理

# yum install keychain

ログイン時に実行するコマンドを設定

$ vi ~/.bash_profile

以下の2行を追加

/usr/bin/keychain ~/.ssh/id_rsa
source ~/.keychain/$HOSTNAME-sh

一旦ログアウトしてログインしてみる(PuTTYの例)。

login as: hnakamur
Authenticating with public key "imported-openssh-key" from agent
Last login: Sat Sep 25 15:49:51 2010 from 192.168.11.2

 * keychain 2.7.0 ~ http://www.funtoo.org
 * Found existing ssh-agent: 3594
 * Adding 1 ssh key(s): /home/hnakamur/.ssh/id_rsa
Enter passphrase for /home/hnakamur/.ssh/id_rsa: パスワードを入力
 * ssh-add: Identities added: /home/hnakamur/.ssh/id_rsa

[hnakamur@sunshine12 ~]$ ssh vm01
Last login: Sat Sep 25 15:47:14 2010 from 192.168.122.1
[hnakamur@vm01 ~]$ パスワード入力せずにログインできた

参考:keychain: Set Up Secure Passwordless SSH Access For Backup Scripts

virt-cloneでvmをコピー

例としてvm01からvm02にコピーするとします。

libvirtのネットワーク設定を編集します。

# vi /etc/libvirt/qemu/networks/default.xml

vm02用の固定IPのエントリを追加します。

<network>
  <name>default</name>
  <uuid>bdb361fe-cea5-45a0-b6d9-b862ab49ad07</uuid>
  <forward mode='nat'/>
  <bridge name='virbr0' stp='on' forwardDelay='0' />
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.2' end='192.168.122.99' />
      <host mac='52:54:00:43:62:2F' name='vm01' ip='192.168.122.101' />
      <host mac='52:54:00:43:62:30' name='vm02' ip='192.168.122.102' />
    </dhcp>
  </ip>
</network>

編集した内容を反映させます。

# virsh net-define /etc/libvirt/qemu/networks/default.xml
# virsh net-destroy default
# virsh net-start default

状態確認

# ps ww -C dnsmasq
  PID TTY      STAT   TIME COMMAND
 3096 ?        S      0:00 /usr/sbin/dnsmasq --strict-order --bind-interfaces
 --pid-file=/var/run/libvirt/network/default.pid --conf-file=
  --listen-address 192.168.122.1 --except-interface lo
 --dhcp-range 192.168.122.2,192.168.122.99 --dhcp-lease-max=98
 --dhcp-host 52:54:00:43:62:2F,vm01,192.168.122.101
 --dhcp-host 52:54:00:43:62:30,vm02,192.168.122.102

コピー

# virt-clone --original vm01 --name vm02 --file /var/lib/libvirt/images/vm02.img --mac 52:54:00:43:62:30

ホストの/etc/hostsに作成したvmのエントリ追加

# vi /etc/hosts

以下の行を追加

192.168.122.102         vm02

2010-09-18

CentOS5.5でkvm

qemuを入れずにkvm-qemu-imgを入れる。
# yum install kvm-qemu-img kvm libvirt virt-manager
# modprobe kvm-amd
# /etc/init.d/libvirtd start
# virt-install --connect qemu:///system -n vm01 -r 512 --vcpus=1 \
 --disk path=/var/lib/libvirt/images/vm01.img,size=10 \
 --os-type linux --accelerate \
 --os-variant=virtio26 \
 --network network:default \
 --location='http://ftp.riken.jp/Linux/centos/5.5/os/i386' \
 --extra-args='console=tty0 console=ttyS0,115200n8'

http://www.centos.org/modules/newbb/viewtopic.php?topic_id=25077&forum=41
http://www.listware.net/201007/centos-virt/101980-centos-virt-virt-install-error-on-centos-54-64bit-and-kvm.html

virt-install \
 --connect qemu:///system \
 --name vm02 \
 --ram 512 \
 --vcpus=1 \
 --file /var/lib/libvirt/images/vm02.img \
 --file-size=10 \
 --nographics \
 --os-type=linux \
 --os-variant=virtio26 \
 --network network:default \
 --accelerate \
 --location='http://ftp.riken.jp/Linux/centos/5.5/os/x86_64' \
 --extra-args='ks=http://192.168.122.1/vm02-ks.cfg console=tty0 console=ttyS0,115200n8'

2010-09-17

CentOS5.5でnginx

参考:http://serverfault.com/questions/114895/why-is-nginx-more-popular-than-lighttpd
nginxは軽量級のウェブサーバーで、ロードバランサーとしてもリバースプロキシーとしても使えるそうです。


http://articles.slicehost.com/2008/12/17/centos-installing-nginx-via-yum
によるとEPELにもパッケージがあるそうなのですが、
http://download.fedora.redhat.com/pub/epel/5/x86_64/repoview/nginx.html
バージョン0.6.39と古いのでnginxホームページからソースを落としてインストールすることにします。

NginxHttpSslModuleによるとSSLを使うにはconfigureで--with-http_ssl_moduleオプションを指定しておく必要があります。

$ wget http://sysoev.ru/nginx/nginx-0.8.50.tar.gz
$ sudo yum install openssl-devel pcre-devel
$ tar zxf nginx-0.8.50.tar.gz
$ cd nginx-0.8.50
$ ./configure --with-http_ssl_module
$ make
$ sudo /usr/local/sbin/checkinstall
Requiresにopenssl, pcreを追加
$ sudo rpm -i /usr/src/redhat/RPMS/x86_64/nginx-0.8.50-1.x86_64.rpm

http://articles.slicehost.com/2009/2/20/centos-nginx-configuration
http://503.mydns.jp/2010/06/nginx/
を参考にしつつ設定。

iptables設定

# /sbin/iptables -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 80 -j ACCEPT
# /sbin/iptables -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 443 -j ACCEPT
# /etc/init.d/iptables save
# /etc/init.d/iptables restart

グループとユーザ作成

# /usr/sbin/groupadd -g 201 nginx
# /usr/sbin/useradd -u 201 -g nginx -d / -s /sbin/nologin nginx

# mkdir /usr/local/nginx/conf.d
# mkdir /var/log/nginx
# vi /usr/local/nginx/conf/nginx.conf

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /usr/local/nginx/conf/mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;
    gzip  on;
    gzip_comp_level 2;
    gzip_proxied any;
    gzip_types      text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    include /usr/local/nginx/conf.d/*.conf;

    server {
        listen 80;
        server_name sunshine12;
        location / {
            root /usr/local/nginx/html;
            index index.html index.htm;
        }
    }
    server {
        listen 443 ssl;
        ssl_certificate /usr/local/nginx/conf/server.crt;
        ssl_certificate_key /usr/local/nginx/conf/server.key;
        server_name sunshine12;
        location / {
            root /usr/local/nginx/html;
            index index.html index.htm;
        }
    }
}

# vi /etc/init.d/nginx

#!/bin/bash
#
# nginx        Startup script for the nginx Web Server
#
# chkconfig: - 85 15
# description: nginx is a World Wide Web server.  It is used to serve \
#              HTML files and CGI.
# processname: nginx
# config: /usr/local/nginx/conf/nginx.conf
# pidfile: /usr/local/nginx/logs/nginx.pid

# Source function library.
. /etc/rc.d/init.d/functions

# Path
nginx='/usr/local/nginx/sbin/nginx'
prog=nginx
RETVAL=0

start() {
        echo -n $"Starting $prog: "
        daemon $nginx
        RETVAL=$?
        echo
        return $RETVAL
}

stop() {
        echo -n $"Stopping $prog: "
        killproc $nginx
        RETVAL=$?
        echo
        return $RETVAL
}

reload() {
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
    return $RETVAL
}

# See how we were called.
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        stop
        start
        ;;
  reload)
        reload
        ;;
  *)
        echo $"Usage: $prog {start|stop|restart|reload}"
        exit 1
        ;;
esac

exit $RETVAL


# chmod +x /etc/init.d/nginx

CentOSでcheckinstallを使う

$ sudo yum install gcc make gettext rpm-build
$ wget http://asic-linux.com.mx/~izto/checkinstall/files/source/checkinstall-1.6.2.tar.gz

$ tar zxf checkinstall-1.6.2.tar.gz
$ cd checkinstall-1.6.2
$ make
$ sudo make install
$ sudo ln -s /usr/local/lib/installwatch.so /usr/local/lib64/installwatch.so
$ sudo /usr/local/sbin/checkinstall

checkinstall 1.6.2, Copyright 2009 Felipe Eduardo Sanchez Diaz Duran
           This software is released under the GNU GPL.

The checkinstallrc file was not found at:
/usr/local/sbin/../checkinstallrc

Assuming default values.

The package documentation directory ./doc-pak does not exist.
Should I create a default set of package docs?  [y]: y

Preparing package documentation...OK

Please choose the packaging method you want to use.
Slackware [S], RPM [R] or Debian [D]? R
...
$ sudo rpm -i /usr/src/redhat/RPMS/x86_64/checkinstall-1.6.2-1.x86_64.rpm

パッケージとしてインストールされたことを確認

$ rpm -qi checkinstall

参考:http://d.hatena.ne.jp/massat/20100817/1282044839

CentOSでselinuxをオフにする

# sed -i -e '/^SELINUX=/s/=.*/=disabled/' /etc/selinux/config
# reboot

2010-09-11

CentOS5.5のクリーンインストール

今まではKVMを使うときにホストをUbuntuでゲストをCentOSにしていたのですが、CentOS5.5も出たことだし、ホストもCentOSに変えようと思い立ちクリーンインストールしました。そのときのメモです。

  • ネットワークインストールのISOイメージをダウンロード。
  • http://ftp.riken.jp/Linux/centos/5.5/isos/x86_64/CentOS-5.5-x86_64-netinstall.iso
  • CD-Rに焼く。Windows 7だとダウンロードしたファイルをエクスプローラで選びポップアップメニューの[ディスクイメージの書き込み]でOK。
  • CD-Rで起動して、パッケージインストール元は以下のように設定。場所は別マシンでブラウザで開いて確認しておきます。
  • タイプ:ftp、ホスト:ftp.riken.jp、ディレクトリ:/Linux/centos/5.5/os/x86_64/
  • パッケージ選択ではBaseも含めて全てのチェックを外して回る。全部外しても起動できます(今まで知らなかった)。必要なものはあとから随時インストールするということで。→kvmのゲストOSセットアップ時にDHCPでうまくいかないので結局yum install @baseでベースはインストールした。
  • ネットワークの設定。IPv6はオフに。IPv4で固定アドレスを設定するときは一旦DHCPで進んでから戻って設定するとゲートウェイとネットマスクが入力済みになっていて楽。
  • インストールが終わって起動したらログインして不要なサービスを停止

まず現状を確認
# chkconfig --list
haldaemon 0:off 1:off 2:off 3:on 4:on 5:on 6:off
ip6tables 0:off 1:off 2:on 3:on 4:on 5:on 6:off
iptables 0:off 1:off 2:on 3:on 4:on 5:on 6:off
kudzu 0:off 1:off 2:off 3:on 4:on 5:on 6:off
lvm2-monitor 0:off 1:on 2:on 3:on 4:on 5:on 6:off
mcstrans 0:off 1:off 2:on 3:on 4:on 5:on 6:off
messagebus 0:off 1:off 2:off 3:on 4:on 5:on 6:off
multipathd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
netconsole 0:off 1:off 2:off 3:off 4:off 5:off 6:off
netfs 0:off 1:off 2:off 3:on 4:on 5:on 6:off
netplugd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
network 0:off 1:off 2:on 3:on 4:on 5:on 6:off
rawdevices 0:off 1:off 2:off 3:on 4:on 5:on 6:off
rdisc 0:off 1:off 2:off 3:off 4:off 5:off 6:off
restorecond 0:off 1:off 2:on 3:on 4:on 5:on 6:off
sshd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
syslog 0:off 1:off 2:on 3:on 4:on 5:on 6:off
tcsd 0:off 1:off 2:off 3:off 4:off 5:off 6:off

不要なサービス停止
# chkconfig haldaemon off;
chkconfig kudzu off;
chkconfig lvm2-monitor off;
chkconfig mcstrans off;
chkconfig messagebus off;
chkconfig netfs off;
chkconfig rawdevices off;
chkconfig restorecond off

変更後の状態確認
# chkconfig --list
haldaemon 0:off 1:off 2:off 3:off 4:off 5:off 6:off
ip6tables 0:off 1:off 2:on 3:on 4:on 5:on 6:off
iptables 0:off 1:off 2:on 3:on 4:on 5:on 6:off
kudzu 0:off 1:off 2:off 3:off 4:off 5:off 6:off
lvm2-monitor 0:off 1:on 2:off 3:off 4:off 5:off 6:off
mcstrans 0:off 1:off 2:off 3:off 4:off 5:off 6:off
messagebus 0:off 1:off 2:off 3:off 4:off 5:off 6:off
multipathd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
netconsole 0:off 1:off 2:off 3:off 4:off 5:off 6:off
netfs 0:off 1:off 2:off 3:off 4:off 5:off 6:off
netplugd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
network 0:off 1:off 2:on 3:on 4:on 5:on 6:off
rawdevices 0:off 1:off 2:off 3:off 4:off 5:off 6:off
rdisc 0:off 1:off 2:off 3:off 4:off 5:off 6:off
restorecond 0:off 1:off 2:off 3:off 4:off 5:off 6:off
sshd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
syslog 0:off 1:off 2:on 3:on 4:on 5:on 6:off
tcsd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
あとはiptablesやsshdの設定などをするのですが、ここでは記述を省略。

ちなみにディスクの使用量はこんな感じでした。合計86MB使用。
# df -k
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
                     141376216    845368 133233416   1% /
/dev/sda1               101086     12635     83232  14% /boot
tmpfs                  4089468         0   4089468   0% /dev/shm
追加でインストールするパッケージ

  • vim-common
  • sudo
  • man
  • which

2010-01-31

AndroidのViewSwitcherのサンプル

参考URL

メモ

  • 上のブログ記事ではJavaからaddView()を呼んでいますが、代わりに以下のサンプルのようにリソースで子要素にしてもよいです。
  • APIレフェレンスに書いてある通りViewSwitcherは子要素を2つか持てません。3つ目の子要素を定義するとRuntimeExceptionが出ました。
  • リソースのXML内でandroid:inAnimation="@android:anim/fade_in"のように属性を指定すればアニメーションできます。ただし、これをつけるとEclipseでLayoutタブに切り替えたときにNotFoundException: Could not find anim resource matching value 0x01A0000 (resolved name: fade_in) in current configuration.と表示されてプレビューが表示できません。まあ、どのみちxmlのタブでソースを直接編集しますので致命的ではないです。

src/sample/viewswitcher2.ViewSwitcher2.java

package sample.viewswitcher2;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ViewSwitcher;

public class ViewSwitcher2 extends Activity implements OnClickListener {
    private ViewSwitcher mSwitcher1;
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mSwitcher1 = (ViewSwitcher) findViewById(R.id.switcher1);
        
        Button showAnswerButton = (Button) findViewById(R.id.switch_button);
        showAnswerButton.setOnClickListener(this);

        Button goNextButton = (Button) findViewById(R.id.next_button);
        goNextButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mSwitcher1.showPrevious();
            }
        });
    }

    @Override
    public void onClick(View v) {
        // 2つ目のビューでshowPrevious()を呼ばずにshowNext()を呼んでも1つ目に戻る。
        mSwitcher1.showNext();
    }
}

res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ViewSwitcher android:id="@+id/switcher1"
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:inAnimation="@android:anim/fade_in" android:outAnimation="@android:anim/fade_out">
        <Button android:id="@+id/switch_button" android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:text="@string/show_answer" />
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical" android:layout_width="fill_parent"
            android:layout_height="fill_parent">
            <TextView android:layout_width="fill_parent"
                android:layout_height="wrap_content" android:text="@string/this_is_the_answer" />
            <Button android:id="@+id/next_button" android:layout_width="wrap_content"
                android:layout_height="wrap_content" android:text="@string/go_next" />
        </LinearLayout>
        <!-- TextView android:layout_width="fill_parent"
            android:layout_height="wrap_content" android:text="third view" / -->
    </ViewSwitcher>
</LinearLayout>

res/values/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">ViewSwitcher2</string>
    <string name="show_answer">Show Answer</string>
    <string name="this_is_the_answer">This is the answer!</string>
    <string name="go_next">Go Next</string>
</resources>

ブログ アーカイブ