3.6 Oracle VMテンプレート構成スクリプトおよびモジュール

3.6.1 テンプレート構成スクリプトの概要
3.6.2 構成モジュールの有効化および無効化
3.6.3 利用可能な構成モジュールにより使用されるキー/値のペア
3.6.4 構成変更をトリガーする方法
3.6.5 Oracle VMテンプレート構成モジュールを開発する方法

Oracle VM Guest Additionsには、仮想マシンをテンプレートから作成し、初回起動時に自動構成するために役立つ一連のパッケージが含まれます。この機能のマスター・パッケージは、ovm-template-configと呼ばれます。Oracle VMテンプレート構成スクリプトと組み合せてOracle VMメッセージング機能をovmd経由で使用することにより、仮想マシンをリモートから構成できます。

3.6.1 テンプレート構成スクリプトの概要

Oracle VMテンプレート構成スクリプトovm-template-configは、標準のLinux System Vのinit.dおよびchkconfigのスクリプト・モデルと非常に類似した方法で機能する一連のモジュール構成スクリプトと連携して動作します。構成モジュールの実行制御は、ゲストの/etc/template.dディレクトリ内で処理されます。構成モジュール・スクリプトは、/etc/template.d/scripts内に格納されます。

ovm-template-configスクリプトはマスター・スクリプトで、すべての有効なモジュールを制御するために使用されます。--helpパラメータを指定してovm-template-configを実行すると、使用方法の概要が示されます。

ovm-template-config --help
usage: ovm-template-config [option] target

Targets:
  configure, unconfigure, reconfigure, cleanup, suspend, resume, migrate, shutdown

Examples:
  ovm-template-config --enumerate configure
  ovm-template-config --enumerate --script network configure
  ovm-template-config --stdin configure
  ovm-template-config --stdin --script network configure
  ovm-template-config --console-input configure
  ovm-template-config --ovf-transport-iso configure
  ovm-template-config --input >infd< --output >outfd< configure

options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -e, --enumerate       enumerate parameters for target
  --human-readable      print in human readable format when enumerate
                        parameters
  -i INPUT, --input=INPUT
                        input parameters from this file descriptor
  -o OUTPUT, --output=OUTPUT
                        output parameters to this file descriptor
  --stdin               build parameters from stdin
  --console-input       build parameters from console input
  --ovf-transport-iso   build parameters from OVF transport ISO
  -s SCRIPT, --script=SCRIPT
                        specify script
  --logfile=LOGFILE     specify log file
  --loglevel=LOGLEVEL   specify log level

リモート構成では、ovm-template-configovmdを組み合せて使用することにより、Oracle VMメッセージング機能を使用してゲストに送信された構成パラメータを取得できます。この場合、ovm-template-configターゲットは、ovmd--scriptパラメータとして渡されます。

# ovmd -s cleanup
# ovmd -s configure 
重要

リモート構成を実行する場合、ovmdを使用して構成キーを含むメッセージを処理するには、認証モジュールを有効にする必要があります。メッセージの処理が完了するのは、最後のメッセージにrootのユーザー・パスワードが含まれている場合のみです。このパスワードは、他の構成処理を実行するために必要な権限を取得するために認証モジュールにより使用されます。このモジュールの詳細は、3.6.2項「構成モジュールの有効化および無効化」を参照してください。

このスクリプトを直接呼び出す方法の詳細は、3.6.4項「構成変更をトリガーする方法」を参照してください。

3.6.2 構成モジュールの有効化および無効化

モジュールを有効にすると、モジュール・スクリプトへのシンボリックリンクが、モジュールの提供するターゲットの種類に基づいて、/etc/template.d内の他のサブディレクトリに作成されます。この方法は、System Vのinitプロセスが動作する方法とほとんど同じです。モジュールを追加すると、モジュール・スクリプトのヘッダーが読み込まれて、名前、優先順位およびターゲットが検証され、その後、シンボリックリンクが、/etc/template.dの下のサブディレクトリに作成されます。

すべてのモジュールのターゲットの有効化および無効化は、ovm-chkconfigを使用して処理されます。このコマンドの使用方法は、--helpパラメータを指定することにより取得できます。

# ovm-chkconfig --help   
usage: ovm-chkconfig [option] ...

examples:
  ovm-chkconfig --list [name]
  ovm-chkconfig --add name
  ovm-chkconfig --del name
  ovm-chkconfig --target <targets> name <on|off>

options:
  --version        show program's version number and exit
  -h, --help       show this help message and exit
  --list           list script status
  --add            add new script
  --del            delete script
  --target=TARGET  specify the targets, separated by comma, e.g.:
                   "configure,unconfigure"

--listパラメータを指定してovm-chkconfigコマンドを使用することにより、利用可能なモジュールとそれらのターゲットの実行時状態を確認できます。

# ovm-chkconfig --list
name              configure  unconfigure reconfigure cleanup  suspend  resume  migrate  shutdown 
authentication    on:90      off         off         off      off      off     off      off     
datetime          on:50      off         off         off      off      off     off      off     
firewall          on:41      off         off         off      off      off     off      off     
network           off        off         off         off      off      off     off      off     
selinux           off        off         off         off      off      off     off      off     
ssh               off        off         off         off      off      off     off      off     
system            off        off         off         off      off      off     off      off     
user              off        off         off         off      off      off     off      off

モジュールによりサポートされるすべてのターゲットを有効にするには、--addパラメータを使用します。

# ovm-chkconfig --add authentication

モジュールによりサポートされるすべてのターゲットを無効にするには、--delパラメータを使用します。

# ovm-chkconfig --del datetime

あるモジュールに対して特定のターゲットを有効化または無効化することもできます。これを行うには、次のコマンドを実行します。

ovm-chkconfig --target=cleanup user off

3.6.3 利用可能な構成モジュールにより使用されるキー/値のペア

ovm-template-config構成モジュールを通して構成変更をトリガーするために使用されるすべてのキー・ペアの完全なリストを取得するには、ovm-template-configがインストールされているゲスト・システムで次のコマンドを実行します。

# ovm-template-config --human-readable --enumerate configure

このコマンドからの出力は、解析しやすく、理解しやすいPythonデータ構造として印刷されます。出力内容は、--scriptパラメータを次のように指定することにより、特定の構成モジュールに関連する情報に限定できます。

# ovm-template-config --human-readable --enumerate configure --script datetime        
        [('50',
  'datetime',
  [{u'description': u'System date and time in format year-month-day-hour-minute-second, e.g.,
                     "2011-4-7-9-2-42".',
    u'hidden': True,
    u'key': u'com.oracle.linux.datetime.datetime'},
   {u'description': u'System time zone, e.g., "America/New_York".',
    u'hidden': True,
    u'key': u'com.oracle.linux.datetime.timezone'},
   {u'description': u'Whether to keep hardware clock in UTC: True or False.',
    u'hidden': True,
    u'key': u'com.oracle.linux.datetime.utc'},
   {u'description': u'Whether to enable NTP service: True or False.',
    u'hidden': True,
    u'key': u'com.oracle.linux.datetime.ntp'},
   {u'description': u'NTP servers separated by comma, e.g., 
                     "time.example.com,0.example.pool.ntp.org".',
    u'hidden': True,
    u'key': u'com.oracle.linux.datetime.ntp-servers'},
   {u'description': u'Whether to enable NTP local time source: True or False.',
    u'hidden': True,
    u'key': u'com.oracle.linux.datetime.ntp-local-time-source'}])]

出力には、トリガーされた構成モジュールとトリガー時の実行レベルおよび受け付けられたキーと値が明確に示されます。すべてのキー名は構造化されており、独自の目的のために開発することが意図されているカスタム・モジュールとの競合を避けるために、com.oracleのプレフィックスが付加されることに注意してください。

キー/値のペアは、実際には、JSON形式でovm-template-configに渡されます。

{"com.oracle.linux.datetime.ntp":"True"}
{"com.oracle.linux.datetime.ntp-servers":"0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org"}
{"com.oracle.linux.root-password":"mysecret"}

3.6.4 構成変更をトリガーする方法

様々な方法を使用することにより、ovm-template-configを使用する構成変更をトリガーできます。最も一般的な方法としては、enable-initial-configモードを使用して実行するようにovmdサービスを設定します。こうすることで、仮想マシンは次回起動後に、構成パラメータがコンソール経由またはovmdメッセージング機能経由で渡されるまで待機します。これは、テンプレートとして動作する仮想マシンを構成する般的な方法です。

ovmdがメッセージをovm-template-configスクリプトに渡すように手動で強制するには、単純に--scriptパラメータを指定してovmdを実行し、ovm-template-configターゲットの1つをポイントするようにします。

# ovmd --list
{"com.oracle.linux.datetime.ntp":"True"}
{"com.oracle.linux.datetime.ntp-servers":"0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org"}
{"com.oracle.linux.root-password":"mysecret"}
# ovmd -s configure
注意

メッセージング・パラメータとovm-template-configを使用して操作を実行するには、認証モジュールが有効にされており、最後のメッセージにキー/値のペアの形式で認証要求が含まれている必要があります。

{"com.oracle.linux.root-password":"mysecret"}

このようにovmdを実行すると、ovmdは2つのパイプ(infdおよびoutfd)を準備し、次のコマンドを使用してバックグラウンドでovm-template-configスクリプトを透過的に呼び出します。

# ovm-template-config --input <infd> --output <outfd> configure

テスト時には、構成情報をコマンドラインでSTDINからスクリプトに直接渡す方法が役立つことがあります。これを行うには、--stdinパラメータを使用してスクリプトを直接呼び出します。

# ovm-template-config --stdin configure <<EOF
> {"com.oracle.linux.selinux.mode": "disabled"}
> {"com.oracle.linux.root-password": "ovsroot"}
> EOF

構成は、--console-inputを指定してスクリプトを実行することにより、コンソールから直接行うこともできます。この方法を行う場合、有効化されたすべてのモジュールに対して定義される必要のあるキーごとに値を入力します。

# ovm-template-config --console-input configure

3.6.5 Oracle VMテンプレート構成モジュールを開発する方法

提供されるモジュール・スクリプトは、Pythonで開発されています。理論的には、入力、出力および引数の処理が同じである場合にかぎり、モジュール・スクリプトを別の言語で開発できます。この項で提供されている例は、Pythonプログラミング言語を使用しています。

各モジュールは、次の2つの主要部品で構成されます。

  1. スクリプト・ヘッダー。スクリプト名、ターゲット、優先順位、説明などの情報を含みます。

  2. 実際のスクリプト。パラメータの小さなセットを処理します。

機能するモジュール・スクリプトの例は、/etc/template.d/scriptsディレクトリの既存のモジュールを参照してください。

モジュール・スクリプト・ヘッダー

モジュール・スクリプト・ヘッダーでは、ovm-chkconfigがスクリプト機能の有効化および無効化を処理するために、非常に特殊なコメント・ブロックを必要とします。スクリプト・ヘッダーの形式は、次のとおりです。

### BEGIN PLUGIN INFO
# name: [script name]
# [target]: [priority]
# [target]: [priority]
# description: a description that can
#   cross multiple lines.
### END PLUGIN INFO

独自のモジュール・スクリプトを開発する場合、正確に同じ形式に従うヘッダーを含める必要があります。ovm-chkconfigを呼び出すときに使用する独自のスクリプト名、スクリプトがサポートするターゲットおよびスクリプトの優先順位を提供します。優先順位は、スクリプトの実行順序を指定します。すべてのターゲットを実装する必要はありません。構成ターゲットがあり、クリーンアップ・ターゲットがない場合も、受け付けられます。構成ターゲットは、仮想マシンの初回起動時、または最初の起動が発生したときに呼び出されます。クリーンアップ・ターゲットは、仮想マシンでクリーンアップを手動で開始したとき、または仮想マシンをその元の状態に復元したい場合に発生します。ネットワーク・モジュールのスクリプト・ヘッダーの例を、次に示します。

### BEGIN PLUGIN INFO
# name: network
# configure: 50
# cleanup: 50
# description: Script to configure template network.
### END PLUGIN INFO

モジュール・スクリプト本体

モジュール・スクリプト本体は、1つ以上のターゲット・パラメータを受け付けることが、その主要な要件となります。ovm-template-configureスクリプトにより表示されるターゲット・パラメータを次に示します。

  • configure

  • unconfigure

  • reconfigure

  • cleanup

  • suspend

  • resume

  • migrate

  • shutdown

スクリプトでは、必要な他の任意の引数も処理できます。実装に役立つオプション・パラメータが1つあります。それは-eまたは--enumerateです。ovm-template-configはこのパラメータを使用して、スクリプトによりサポートされるターゲットのパラメータを列挙またはリストします。

スクリプト本体で使用するための非常に基本的なテンプレートを、次に示します。

try:
    import json
except ImportError:
    import simplejson as json
from templateconfig.cli import main


def do_enumerate(target):
    param = []
    if target == 'configure':
        param += []
    elif target == 'cleanup':
        param += []
    return json.dumps(param)


def do_configure(param):
    param = json.loads(param)
    return json.dumps(param)


def do_cleanup(param):
    param = json.loads(param)
    return json.dumps(param)


if __name__ == '__main__':
    main(do_enumerate, {'configure': do_configure, 'cleanup': do_cleanup})

このスクリプトは構成ターゲットおよびクリーンアップ・ターゲットをサポートします。

スクリプト全体に独自のコードを記述できます。たとえば、do_enumerate関数の場合、スクリプト内で各ターゲット用にサポートされるパラメータを記述できます。ファイアウォール・モジュールの例を、次に示します。

def do_enumerate(target):
    param = []
    if target == 'configure':
        param += [{'key': 'com.oracle.linux.network.firewall',
                   'description': 'Whether to enable network firewall: True or False.',
                   'hidden': True}]
    return json.dumps(param)

各ターゲット関数は、スクリプトに渡されるJSONパラメータを、param = json.loads(param)文を使用して読み込むことから始めます。この場所では、スクリプトが受け取ることを期待するキーの値に基づいて操作を実行するコードを記述できます。ファイアウォール・モジュールからの例を、再び次に示します。

def do_configure(param):
    param = json.loads(param)
    firewall = param.get('com.oracle.linux.network.firewall')
    if firewall == 'True':
        shell_cmd('service iptables start')
        shell_cmd('service ip6tables start')
        shell_cmd('chkconfig --level 2345 iptables on')
        shell_cmd('chkconfig --level 2345 ip6tables on')
    elif firewall == 'False':
        shell_cmd('service iptables stop')
        shell_cmd('service ip6tables stop')
        shell_cmd('chkconfig --level 2345 iptables off')
        shell_cmd('chkconfig --level 2345 ip6tables off')
    return json.dumps(param)

モジュール・スクリプトのパッケージ化

1つ以上の構成モジュール・スクリプトを記述したら、それらを他のシステムに展開できるRPMとしてパッケージ化することをお薦めします。テンプレート構成スクリプトをインストールおよび構成するには、特定のネーミング規則を使用して、それらをRPMにパッケージ化する必要があります。スクリプトをovm-template-config-[スクリプト名]としてパッケージ化します。理想的には、RPMのインストール後に、# /usr/sbin/ovm-chkconfig --add [スクリプト名]を実行して、スクリプトを自動的に追加することをお薦めします。スクリプトまたはRPMをアンインストールするときは、アンインストール時に# /usr/sbin/ovm-chkconfig --del [スクリプト名]を使用して削除します。これは、使用可能なRPM specファイルの次のサンプルに説明されています。

Name: ovm-template-config-example
Version: 3.0
Release: 1%{?dist}
Summary: Oracle VM template example configuration script.
Group: Applications/System
License: GPL
URL: http://www.oracle.com/virtualization
Source0: %{name}-%{version}.tar.gz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
BuildArch: noarch
Requires: ovm-template-config

%description
Oracle VM template example configuration script.

%prep
%setup -q

%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT

%clean
rm -rf $RPM_BUILD_ROOT

%post
if [ $1 = 1 ]; then
    /usr/sbin/ovm-chkconfig --add example
fi

%preun
if [ $1 = 0 ]; then
    /usr/sbin/ovm-chkconfig --del example
fi

%files
%defattr(-,root,root,-)
%{_sysconfdir}/template.d/scripts/example

%changelog
* Tue Mar 22 2011 John Smith  - 3.0-1
- Initial build.

独自のスクリプト名を参照するように、サンプルのspecファイルを必ず編集してください。

RPMを作成するためには、rpmbuildをインストールする必要があります。

# yum install rpm-build

次のサンプルMakefileは、ビルド・プロセスの自動化に役立ちます。

DESTDIR=
PACKAGE=ovm-template-config-example
VERSION=3.0

help:
@echo 'Commonly used make targets:'
@echo '  install    - install program'
@echo '  dist       - create a source tarball'
@echo '  rpm        - build RPM packages'
@echo '  clean      - remove files created by other targets'

dist: clean
mkdir $(PACKAGE)-$(VERSION)
tar -cSp --to-stdout --exclude .svn --exclude .hg --exclude .hgignore \
--exclude $(PACKAGE)-$(VERSION) * | tar -x -C $(PACKAGE)-$(VERSION)
tar -czSpf $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)-$(VERSION)
rm -rf $(PACKAGE)-$(VERSION)

install:
install -D example $(DESTDIR)/etc/template.d/scripts/example

rpm: dist
rpmbuild -ta $(PACKAGE)-$(VERSION).tar.gz

clean:
rm -fr $(PACKAGE)-$(VERSION)
find . -name '*.py[cdo]' -exec rm -f '{}' ';'
rm -f *.tar.gz

.PHONY: dist install rpm clean

独自のスクリプトを参照するように、このMakefileを必ず編集してください。

作業ディレクトリを作成して、スクリプト、specファイルおよびMakefileをそこにコピーします。次を実行します。

# make dist

これで、コードのsrc tarballが作成されます。続いて、次を実行します。

# make rpm

これにより、作業ディレクトリ内のRPMS/noarchディレクトリにRPMが生成されます。たとえば、RPMS/noarch/ovm-template-config-test-3.0-1.el6.noarch.rpmが生成されます。