harry’s memorandum

おれおれメモ

CentOS6.2のtcshはいまいち

Centos6.2 の tcsh 仕様変更だそうです。*1

Technical Notes:
This package fixes the return value of the "status" (or"$?") variable in the case of pipelines and backquoted
commands. The "anyerror" variable, which selects thebehavior, has been added to retain backward compatibility.

https://bugzilla.redhat.com/show_bug.cgi?id=658190

パイプ時やバッククォートのコマンドのステータス処理に変更があったと。

$ cat no-exist | wc -l
cat: no-exist: No such file or directory
0
$ echo $?
0
$ set anyerror
$ cat no-exist | wc -l
cat: no-exist: No such file or directory
0
$ echo $?
1

最後のコマンドは成功しているのだからステータスは 0 を返すべきだ、ということですか。保険で下位互換の set anyerror を設定すれば昔の振る舞いをするんだね。

$ unset anyerror
$ set stdout=`cat no-exist`
cat: no-exist: No such file or directory
$ echo $?
0

でも、これが正常になるのはなんでだろう?

$ which set
set: shell built-in command.

setがコマンド(ビルトイン)だから、変数に代入したらコマンド成功!ということで、ステータスは 0 を返すってことにしておこう。

追記(2012-05-28)

元に戻ったらしい。
挙動を変える変数をanyerrorからtcsh_posix_statusに変えたらしい。シェル変数?なのかな。anyerrorの時もそうだけど環境変数にしないと意味なくね。

Previously, the "anyerror" variable could be selected to set the tcsh exit value behavior. However, "anyerror" is a shell variable and therefore was not propagated to subshells, and could not globally affect csh scripts. This update modifies the tcsh exit value behavior to the default behavior of csh: the new "tcsh_posix_status" variable is now available instead of "anyerror" to allow behavior similar to the POSIX standard.

https://bugzilla.redhat.com/show_bug.cgi?id=784510

*1:tcsh-6.17-14.el6.x86_64

リバースプロキシ経由でUserminにアクセスする方法

外部からUserminやWebminにアクセスしたい。自分がやりたいことの場合、公式サイトに書いてある方法だけだと中途半端に失敗する。

目的はこんな感じ。

f:id:dharry:20120109053922p:image

構成

Userminサーバ (Userminの設定)

Centos6.2で試しているので RPMのUserminパッケージをダウンロードします。

$ yum install perl-Net-SSLeay.x86_64
$ yum --enablerepo=rpmforge install perl-Authen-PAM.x86_64
$ rpm -ivh usermin-1.500-1.noarch.rpm

/etc/usermin/config に追加。*1

ssl=0
webprefix=/usermin
webprefixnoredir=1

/etc/usermin/miniserv.conf にオレオレ設定を追加。*2

front_url=http://proxy.example.com/usermin/

userminを再起動。ついでに自動起動。

$ sudo /etc/init.d/usermin restart
$ sudo /sbin/chkconfig --level 345 usermin on

Userminサーバ (UserminのWebサーバのminiserv.confを修正)

一応バックアップ

$ cd /usr/libexec/usermin/
$ sudo cp -p miniserv.pl miniserv.pl.backup

合っているかどうか自信ないけど、まあいいよね。*3

# diff -c  miniserv.pl miniserv.pl.backup
*** miniserv.pl Tue Jan 24 16:30:10 2012
--- miniserv.pl.backup  Sun Jan 22 10:46:59 2012
***************
*** 3919,3929 ****
                else {
                        &write_data("Set-Cookie: $sidname=$sid; path=/$sec\r\n");
                        }
!               if ($header{'referer'} =~ /$config{'front_url'}/) {
!                       &write_data("Location: $config{'front_url'}\r\n");
!               } else {
!                       &write_data("Location: $prot://$host$portstr$in{'page'}\r\n");
!               }
                &write_keep_alive(0);
                &write_data("\r\n");
                &log_request($acpthost, $authuser, $reqline, 302, 0);
--- 3919,3925 ----
                else {
                        &write_data("Set-Cookie: $sidname=$sid; path=/$sec\r\n");
                        }
!               &write_data("Location: $prot://$host$portstr$in{'page'}\r\n");
                &write_keep_alive(0);
                &write_data("\r\n");
                &log_request($acpthost, $authuser, $reqline, 302, 0);

Userminサーバ (Apache Reverse Proxyの設定)

http://localhost:20000/にするとログアウトアイコンがでなくなってしまうので、http://usermin.example.com:20000/ にする。

<IfModule mod_proxy.c>
ProxyRequests Off
ProxyVia Off
</IfModule>

NameVirtualHost *:80
<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyPass         /usermin/     http://usermin.example.com:20000/
    ProxyPassReverse  /usermin/     http://usermin.example.com:20000/
    ServerName        usermin.example.com
    <Proxy *>
       allow from all
    </Proxy>
</VirtualHost>

フロントサーバ (Apache Reverse Proxyの設定)

<IfModule mod_proxy.c>
ProxyRequests Off
ProxyVia Off
</IfModule>

NameVirtualHost *:80
<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyPass         /usermin/     http://usermin.example.com/usermin/
    ProxyPassReverse  /usermin/     http://usermin.example.com/usermin/
    ServerName        proxy.example.com
    <Proxy *>
       allow from all
    </Proxy>
</VirtualHost>

あとは細かい設定を見なおして、公開する範囲を絞って、SSLに対応するだけかな。

*1:httpsはReverseProxy側でラップするつもりなのでssl=0にする

*2:ReverseProxy側でhttpsする場合はオレオレ設定のfront_url=http://usermin.example.com/usermin/にする

*3:ReverseProxy経由で認証成功した後に Location: http://proxy.example.com:20000/ されるので書き換えます

たぶん使わないであろうBashのデバッグ方法

http://d.hatena.ne.jp/dharry/20101121/1290273723
とりあえずBash好きなので、前に覚えたことの復習も兼ねてもう一回書いておきます。

setでデバッグ

’-x’, ’-v’ デバッグは基本ですよね。オプションつけて実行するとスクリプトがストリーキングになります。

$ cat foo.sh
for x in `seq 2`; do
  echo $x
done
$ bash -x foo.sh
++ seq 2
+ echo 1
1
+ echo 2
2

でもストリーキング愛好家の中には一部だけ露出したいという人もいます。そんなフェティシズムをお持ちでしたら内部で set をすれば OK です。

$ cat foo.sh
[ ${1}x = "-dx" ] && \
set -x
for x in `seq 2`; do
  echo $x
done
set +x
$ ./foo.sh
1
2
$ ./foo -d
++ seq 2
+ for x in '`seq 2`'
+ echo 1
1
+ for x in '`seq 2`'
+ echo 2
2
+ set +x

BASH_COMMANDをtrap

Bashには色々な疑似シグナルがあります。

疑似シグナル タイミング
EXIT シェルがスクリプトを終了した
ERR コマンド、シェル関数から0ではない終了ステータスが返された
DEBUG シェルが文を実行した
RETURN source または . で実行されたシェル関数/スクリプトが終了した

またBashには予約されたシェル変数があります。そのひとつが "BASH_COMMAND"です。 *1 BASH_COMMANDは実行しようとしているコマンドが変数に入っています。

BASH_COMMAND
The command currently being executed or about to be executed, unless the shell is executing a command as the result of a trap, in which case it is the command executing at the time of the trap.

http://linux.die.net/man/1/bash

DEBUGシグナルを使うとシェルが文を実行するたびにtrapできるので、スクリプトはヌーディストのようになります。
以下コードはスクリプトの特定の箇所をステップ実行します。trap - DEBUG とすればステップ実行の設定は解除されます。

$ cat foo.sh
if [ ${1}x = "-dx" ]; then
  set -x
  trap 'read -p "$0($LINENO) $BASH_COMMAND"' DEBUG
fi

while :
do
  dice=$((${RANDOM}%6+1))
  case  $dice in
    1) echo one;;
    2) echo two;;
    3) echo three;;
    4) echo four;;
    5) echo five;;
    6) echo six; break;;
  esac
done
trap - DEBUG

echo ok

$ ./foo.sh -d
++ trap 'read -p "$0($LINENO) $BASH_COMMAND"' DEBUG
+++ read -p './foo.sh(6) :'
./foo.sh(6) :
++ :
+++ read -p './foo.sh(8) dice=$((${RANDOM}%6+1))'
./foo.sh(8) dice=$((${RANDOM}%6+1))
++ dice=6
++ case $dice in
+++ read -p './foo.sh(9) case $dice in '
./foo.sh(9) case $dice in
+++ read -p './foo.sh(15) echo six'
./foo.sh(15) echo six
++ echo six
six
+++ read -p './foo.sh(15) break'
./foo.sh(15) break
++ break
+++ read -p './foo.sh(18) trap '\'''\'' DEBUG'
./foo.sh(18) trap '' DEBUG
++ trap '' DEBUG
++ echo ok
ok

bashdb

ステップ実行ができるのなら gdb ぽく解剖もできるんじゃね?と。案の定 bashdb というgdb風のデバッガがあったりします。
まずはインストール。パッケージがあればパッケージマネージャでインストール。

$ sudo apt-get install bashdb

なければソースからビルドします。 ここからダウンロード (http://sourceforge.net/projects/bashdb/files/)

$ tar xvzf bashdb-3.1-0.09.tar.gz
$ cd bashdb-3.1-0.09
$ ./configure
$ make
$ make install

見事にステップ実行できます。マジに素晴らしいです。

$ bashdb foo.sh
Bourne-Again Shell Debugger, release bash-3.1-0.09
Copyright 2002, 2003, 2004, 2006, 2007 Rocky Bernstein
This is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.

(/root/foo.sh:1):
1:      if [ ${1}x = "-dx" ]; then
bashdb<0> s
(/root/foo.sh:6):
6:      while :
bashdb<1> s
(/root/foo.sh:8):
8:      dice=$((${RANDOM}%6+1))

bashdb は bash で書かれています。

$ file /usr/local/bin/bashdb
/usr/local/bin/bashdb: Bourne-Again shell script text executable

もちろん BASH_COMMAND を trap しています。

$ grep BASH_COMMAND /usr/local/share/bashdb/*
/usr/local/share/bashdb/bashdb-main.inc:trap '_Dbg_debug_trap_handler 0 "$BASH_COMMAND" "$@"' DEBUG
/usr/local/share/bashdb/bashdb-trace:      trap '_Dbg_debug_trap_handler 0 "$BASH_COMMAND" "$@"' DEBUG
/usr/local/share/bashdb/bashdb-trace:      trap '_Dbg_debug_trap_handler 0 "$BASH_COMMAND" "$@"' DEBUG
/usr/local/share/bashdb/bashdb-trace:  trap '_Dbg_debug_trap_handler 0 "$BASH_COMMAND" "$@"' DEBUG
/usr/local/share/bashdb/dbg-fns.inc:  trap '_Dbg_debug_trap_handler 0 "$BASH_COMMAND" "$@"' DEBUG
/usr/local/share/bashdb/dbg-main.inc:trap '_Dbg_debug_trap_handler 0 "$BASH_COMMAND" "$@"' DEBUG
/usr/local/share/bashdb/dbg-sig.inc:    trap '_Dbg_exit_handler "$BASH_COMMAND"' EXIT
/usr/local/share/bashdb/dbg-sig.inc:    local trap_cmd="trap '_Dbg_sig_handler $signum \"\$BASH_COMMAND\" \"\$@\"' $name"

その他に、プロンプトを書き換えたり、functraceを設定したり、とても普通のbashでは使うことがないことが盛り沢山です。

$ grep PS4 /usr/local/share/bashdb/*
/usr/local/share/bashdb/dbg-cmds.inc:  # We've reset some variables like IFS and PS4 to make eval look
/usr/local/share/bashdb/dbg-fns.inc:  PS4='+ dbg (${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]}\n'
$ grep functrace /usr/local/share/bashdb/*
/usr/local/share/bashdb/bashdb-trace:  set -o functrace

*1:env LANG=C man bash

シェルスクリプトをコンパイルできるshcで遊んでみた

使うことはないかもしれない。でも面白いです。

shcをインストール

 $ sudo apt-get install shc

なかったらソースをダウンロードしてコンパイルしてください。

 $ wget http://www.datsi.fi.upm.es/~frosal/sources/shc-3.8.7.tgz
 $ tar xvzf shc-3.8.7.tgz
 $ cd shc-3.8.7/
 $ make

shcでコンパイル

テストで /usr/bin/ldd を使用。 なんで lddってshell script ってイメージがないんだろう。

$ file /usr/bin/ldd
/usr/bin/ldd: Bourne-Again shell script text executable
$ cp -p /usr/bin/ldd .
$ ./shc  -v -r -T -f ./ldd
shc shll=bash
shc [-i]=-c
shc [-x]=exec '%s' "$@"
shc [-l]=
shc opts=
shc: cc  ./ldd.x.c -o ./ldd.x
shc: strip ./ldd.x
shc: chmod go-r ./ldd.x
$ file ./ldd.x
./ldd.x: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped
$ ./ldd.x /bin/ls
        linux-vdso.so.1 =>  (0x00007fff0d9ff000)
        libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f2ed8878000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f2ed8670000)
        libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007f2ed8467000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2ed80d3000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f2ed7ecf000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f2ed8a9f000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f2ed7cb0000)
        libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007f2ed7aab000)

foo.x.c というCのソースができるので、中身を眺めてみるのもオツなものです。

checkinstallは最新のものをmakeするのがいいです

checkinstall便利。Centos6とかで標準のリポジトリに入れて欲しいです。

$ git clone http://www.asic-linux.com.mx/~izto/checkinstall/checkinstall.git
$ cd checkinstall/
$ make
$ make install
$ mkdir -p ~/rpmbuild/SOURCES
$ checkinstall

Scientific Linux 6.0 で libvirtを野良ビルドしてVMware ESXiにアクセスしてみた。

Scientific Linux 6.0 で libvirtを使ってesxにアクセスして遊んでみようとしたのですが...
世の中は思うようにいかないです。

$ virsh -c esx://192.168.1.5/?no_verify=1
Enter username for 192.168.1.5 [root]:
Enter root's password for 192.168.1.5:
error: internal error Expecting VI API major/minor version '2.5' or '4.0' but found '4.1'
error: failed to connect to the hypervisor

少しlibvritが古いのか esx4.1 は受け付けないと怒られてしまいました。

$ rpm -aq | grep libvirt
libvirt-0.8.1-27.el6_0.6.x86_64
libvirt-client-0.8.1-27.el6_0.6.x86_64

公式サイトをみたところ「Since 0.8.3」からサポートのようです。

The libvirt VMware ESX driver can manage VMware ESX/ESXi 3.5/4.x and VMware GSX 2.0, also called VMware Server 2.0, and possibly later versions. Since 0.8.3 the driver can also connect to a VMware vCenter 2.5/4.x (VPX).

http://libvirt.org/drvesx.html


仕方が無いのでScientific Linux 6.1がリリースされるまで、でRHEL6.1のsrc.rpmを野良ビルドして我慢してみました。

libvirtのビルド

まずはrhel6.1のsrc.rpmをダウンロード。

$ wget ftp://ftp.nluug.nl/pub/os/Linux/distr/RedHat/ftp/redhat/linux/enterprise/6Server/en/os/SRPMS/libvirt-0.8.7-18.el6.src.rpm

このぐらいで大丈夫だろう、と前もって入れておいたのですが...

$ sudo yum install rpm-build gcc gdb make 

かなり怒られました。

$ rpmbuild --rebuild libvirt-0.8.7-18.el6.src.rpm
Installing libvirt-0.8.7-18.el6.src.rpm
warning: user mockbuild does not exist - using root
warning: group mockbuild does not exist - using root
error: Failed build dependencies:
        python-devel is needed by libvirt-0.8.7-18.el6.x86_64
        autoconf is needed by libvirt-0.8.7-18.el6.x86_64
        automake is needed by libvirt-0.8.7-18.el6.x86_64
        libtool is needed by libvirt-0.8.7-18.el6.x86_64
        libxml2-devel is needed by libvirt-0.8.7-18.el6.x86_64
        xhtml1-dtds is needed by libvirt-0.8.7-18.el6.x86_64
        readline-devel is needed by libvirt-0.8.7-18.el6.x86_64
        ncurses-devel is needed by libvirt-0.8.7-18.el6.x86_64
        gettext is needed by libvirt-0.8.7-18.el6.x86_64
        gnutls-devel is needed by libvirt-0.8.7-18.el6.x86_64
        augeas is needed by libvirt-0.8.7-18.el6.x86_64
        libudev-devel >= 145 is needed by libvirt-0.8.7-18.el6.x86_64
        libpciaccess-devel >= 0.10.9 is needed by libvirt-0.8.7-18.el6.x86_64
        yajl-devel is needed by libvirt-0.8.7-18.el6.x86_64
        libpcap-devel is needed by libvirt-0.8.7-18.el6.x86_64
        libnl-devel is needed by libvirt-0.8.7-18.el6.x86_64
        avahi-devel is needed by libvirt-0.8.7-18.el6.x86_64
        libselinux-devel is needed by libvirt-0.8.7-18.el6.x86_64
        radvd is needed by libvirt-0.8.7-18.el6.x86_64
        cyrus-sasl-devel is needed by libvirt-0.8.7-18.el6.x86_64
        parted-devel is needed by libvirt-0.8.7-18.el6.x86_64
        device-mapper-devel is needed by libvirt-0.8.7-18.el6.x86_64
        numactl-devel is needed by libvirt-0.8.7-18.el6.x86_64
        libcap-ng-devel >= 0.5.0 is needed by libvirt-0.8.7-18.el6.x86_64
        netcf-devel >= 0.1.4 is needed by libvirt-0.8.7-18.el6.x86_64
        libcurl-devel is needed by libvirt-0.8.7-18.el6.x86_64
        audit-libs-devel is needed by libvirt-0.8.7-18.el6.x86_64
        systemtap-sdt-devel is needed by libvirt-0.8.7-18.el6.x86_64

足りないものは潰す。

$ sudo yum install python-devel autoconf automake libtool libxml2-devel xhtml1-dtds readline-devel ncurses-devel gettext gnutls-devel augeas libudev-devel libpciaccess-devel yajl-devel libpcap-devel libnl-devel avahi-devel libselinux-devel radvd cyrus-sasl-devel parted-devel device-mapper-devel numactl-devel libcap-ng-devel netcf-devel libcurl-devel audit-libs-devel systemtap-sdt-devel gnutls-utils

もう一度rpmbuildして完成。

$ rpmbuild --rebuild libvirt-0.8.7-18.el6.src.rpm

so.2()(64bit) libxslt.so.1()(64bit) libyajl.so.1()(64bit) libz.so.1()(64bit) python(abi) = 2.6 rtld(GNU_HASH)
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/foo/rpmbuild/BUILDROOT/libvirt-0.8.7-18.el6.x86_64
Wrote: /home/foo/rpmbuild/RPMS/x86_64/libvirt-0.8.7-18.el6.x86_64.rpm
Wrote: /home/foo/rpmbuild/RPMS/x86_64/libvirt-client-0.8.7-18.el6.x86_64.rpm
Wrote: /home/foo/rpmbuild/RPMS/x86_64/libvirt-devel-0.8.7-18.el6.x86_64.rpm
Wrote: /home/foo/rpmbuild/RPMS/x86_64/libvirt-python-0.8.7-18.el6.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.VinqCn
+ umask 022
+ cd /home/foo/rpmbuild/BUILD
+ cd libvirt-0.8.7
+ rm -fr /home/foo/rpmbuild/BUILDROOT/libvirt-0.8.7-18.el6.x86_64
+ exit 0
Executing(--clean): /bin/sh -e /var/tmp/rpm-tmp.uE2shc
+ umask 022
+ cd /home/foo/rpmbuild/BUILD
+ rm -rf libvirt-0.8.7
+ exit 0

野良ビルドしたlibvirtをインストール

$ sudo rpm -Uvh *rpm
Preparing...                ########################################### [100%]
   1:libvirt-client         ########################################### [ 25%]
   2:libvirt                ########################################### [ 50%]
   3:libvirt-python         ########################################### [ 75%]
   4:libvirt-devel          ########################################### [100%]

念のため再起動

$ sudo /etc/init.d/libvirtd restart
Stopping libvirtd daemon:                                  [  OK  ]
Starting libvirtd daemon:                                  [  OK  ]

libvirtでesxにアクセス

$ virsh -c esx://192.168.1.5/?no_verify=1
Enter username for 192.168.1.5 [root]:
Enter root's password for 192.168.1.5:
Welcome to virsh, the virtualization interactive terminal.

Type:  'help' for help with commands
       'quit' to quit
ゲスト一覧
virsh # list
 Id Name                 State
----------------------------------
 16 windows2000          running
 32 ubuntu11.04          running
208 centos5              running
224 cern6                running
esxの構成情報
virsh # nodeinfo
CPU model:           Intel Core i5 CPU M 460 @ 2.53G
CPU(s):              2
CPU frequency:       2526 MHz
CPU socket(s):       1
Core(s) per socket:  2
Thread(s) per core:  2
NUMA cell(s):        1
Memory size:         5954024 kB
ゲストのシャットダウン
virsh # shutdown 32
Domain 32 is being shutdown

virsh # list
 Id Name                 State
----------------------------------
 16 windows2000          running
208 centos5              running
224 cern6                running
ゲストOSの情報
virsh # dominfo 208
Id:             208
Name:           centos5
UUID:           564dc12a-363f-d01f-2863-606774e120fa
OS Type:        hvm
State:          running
CPU(s):         2
Max memory:     1048576 kB
Used memory:    1048576 kB
Persistent:     yes


まったくもって素晴らしい。野良ビルドって本当にいいですね。
しかし、まだまだESXサポートしているAPIは少ないのが現状っぽいですね。
http://libvirt.org/hvsupport.html

virsh # dommemstat 16
error: Failed to get memory statistics for domain 16
error: this function is not supported by the connection driver: virDomainMemoryStats

XenServerのコマンドラインインターフェイス xe-cli の便利を実感してみた

XenServer使っていますか?私はVMwareよりXenServerの方が気に入っています。気に入っているその理由の1つとして、VMwareSDK認証が重くて*1時折寝てしまうことがありますが、XenServerのSDKは軽いです。機能は少ないですがやっぱり軽快なのは嬉しいです。

SDK

http://community.citrix.com/display/xs/Download+SDKs

  • XenServer.NET: The XenServer SDK for C#.NET
  • XenServer.NET: Old-style XenServer SDK for C#.NET
  • XenServerJava: The XenServer SDK for Java
  • libxenserver: The XenServer SDK for C
  • XenServerPSSnapIn: The XenServer SDK for PowerShell
  • XenAPI.py: The XenServer Python module

XML-RPCを叩けばいいってことなので、rubyで実装している人もいます。


ここではお手軽な xe-cli を使ったサンプルをメモします。(XenServer5.6fp1で試しています)

xe-cliをインストール

XenServerにログインすればxe-cliは使えます。でもリモートで管理するのなら xe-cli を別のサーバにインストールしたほうが便利です。XenServer-5.6.1-fp1-linux-cd.iso の 中に xe-cli-5.6.100-39153p.i686.rpm があるのでインストールします。

$ sudo rpm -ivh xe-cli-5.6.100-39153p.i686.rpm

xs-tools

VMにxs-toolsはインストールしておきましょう。インストールしていないと取得できない場合があります。

パスワードファイルを作成

cliを実行中にpsでパスワードが生でみえてしまうので、パスワードファイルを作成します。1行目ユーザ、2行目パスワードです。

$ cat passwordfile.txt
user
password

VMの一覧を表示

$ xe -s <xenserver> -pwf ./<passwordfile.txt> vm-list | grep -v "^$"
uuid ( RO)           : 6136b9a8-c32a-b361-14eb-fc33337b2387
     name-label ( RW): Centos5
    power-state ( RO): running
uuid ( RO)           : e918bb8c-16eb-78ed-4aad-2a5f7f8e7d10
     name-label ( RW): WindowsXP
    power-state ( RO): running
uuid ( RO)           : 4ee28767-7423-4ee0-9cc8-8420c45c55cd
     name-label ( RW): Control domain on host: epitaph
    power-state ( RO): running
uuid ( RO)           : fb9f1fe1-ec48-bf32-0f03-9621a61f01b7
     name-label ( RW): Windows2003
    power-state ( RO): halted
uuid ( RO)           : 55c19dd9-cb27-129a-be8e-723a5d72b830
     name-label ( RW): Centos5-1
    power-state ( RO): halted

VMをリブート

$ xe -s <xenserver> -pwf ./<passwordfile.txt> vm-reboot uuid=<uuid>

VMのネットワーク情報

VMに割り当てられているIPアドレスを取得できます。

$ xe -s <xenserver> -pwf ./<passwordfile.txt> vm-param-get param-name=networks uuid=<uuid>
0/ip: 192.168.1.101

VMのスナップショット取得

成功するとスナップショットのuuidが返ってきます。

$xe -s <xenserver> -pwf ./<passwordfile.txt> vm-snapshot new-name-label="snapshot-001" uuid=<uuid>
bbe3a3be-5ace-462d-9005-ba1bbc226e1d

VMのOSの情報

$ xe -s <xenserver> -pwf ./<passwordfile.txt> vm-param-get param-name=os-version uuid=<uuid>
name: CentOS release 5.5 (Final); uname: 2.6.18-194.3.1.el5.centos.plusxen; distro: centos; major: 5; minor: 5

VMのvCPUの使用率

vCPU数が複数であればcpu-id単位で使用率が表示されます。

$ xe -s <xenserver> -pwf ./<passwordfile.txt> vm-param-get param-name=VCPUs-utilisation uuid=<uuid>
0: 0.002; 1: 0.000

VMの色々な情報取得

$ xe -s <xenserver> -pwf ./<passwordfile.txt> vm-param-list uuid=<uuid>

VMのメモリ情報

vm-param-listの情報にはメモリの使用量が存在しない。色々調べたところcitrixのフォーラムにありました。まず vm-data-source-list で情報をみます。name_label は memory と memory_internal_freeです。どちらもenable: true になっていることを確認。falseの場合はxs-toolsをインストールしていない可能性が高いです。

$ xe -s <xenserver> -pwf ./<passwordfile.txt> vm-data-source-list uuid=<uuid>
name_label          : memory
    name_description: Memory currently allocated to VM
             enabled: true
            standard: true
                 min: 0.000
                 max: nan
               units:


name_label          : memory_internal_free
    name_description: Memory used as reported by the guest agent
             enabled: true
            standard: true
                 min: 0.000
                 max: nan
               units:

メモリの総割り当てサイズ (byte)。メモリの総割り当てサイズはバイト(byte)、メモリの使用量はキロバイト(kbyte)で返ってくるので注意が必要。

$ xe -s <xenserver> -pwf ./<passwordfile.txt> vm-data-source-query data-source=memory uuid=<uuid>
419430400.000000

メモリの使用量 (kbyte)。

$ xe -s <xenserver> -pwf ./<passwordfile.txt> vm-data-source-query data-source=memory_internal_free uuid=<uuid>
124456.000000

VMのネットワークトラフィック

メモリと同じく vm-data-source-list で情報をみます。name_label は vif_0_tx と vif_0_tx 。descriptionに「virtual interface number '0'」とあるように最初の'0'のVirtual NICです。et1 なら vif_1_tx と vif_1_txになります。

xe -s <xenserver> -pwf ./<passwordfile.txt> vm-data-source-list uuid=<uuid>
name_label          : vif_0_tx
    name_description: Bytes per second transmitted on virtual interface number '0'
             enabled: true
            standard: true
                 min: 0.000
                 max: nan
               units:


name_label          : vif_0_rx
    name_description: Bytes per second received on virtual interface number '0'
             enabled: true
            standard: true
                 min: 0.000
                 max: nan
               units:

送信サイズ(byte)

$ xe -s <xenserver> -pwf ./<passwordfile.txt> vm-data-source-query data-source=vif_0_tx uuid=<uuid>
15.835249

受信サイズ(byte)

$ xe -s <xenserver> -pwf ./<passwordfile.txt> vm-data-source-query data-source=vif_0_rx uuid=<uuid>
15.835249

VMの操作系

VMをshutdown/rebootしても黄色いアイコンのまま停止してくれない場合の強制適用の方法。
対象のVMのuuidを調べ、list_domainsでid調べ(Hが付く)、xenops destroy_domainで殺すという感じです。

$ xe vm-list
$ list_domains | grep <uuid>
<id> | <uuid> | H
$ /opt/xensource/debug/xenops destroy_domain –domid <id>

*1:これは嘘でした。