BE 間でデータを共有するには、共有データセットと、BE 内のディレクトリ構造からその共有データセットを指すシンボリックリンクを使用します。IPS パッケージが BE 内部でシンボリックリンクを配布します。共有データセットを作成およびマウントする SMF サービスが、同じパッケージまたは別のパッケージから配布されます。パッケージがインストールされている BE から新しい共有データセットへのリンクは、Oracle Solaris での既存の共有内容に示す /var/share へのリンクに似ています。BE で実行されるアプリケーションは、共有領域への書き込みまたは共有領域からの読み取りをリンクを介して実行します。
ベストプラクティスは、異なる BE で実行されている複数のアプリケーションが内容を共有できる 1 つのデータセットを作成することです。共有するデータのディレクトリごとに個別のデータセットを作成すると、各非大域ゾーンに複数のデータセットが作成される結果となりますが、1 つのゾーンに複数のデータセットを作成することは望ましくありません。たとえば /opt/share でマウントする OPTSHARE データセットを作成するとします。さまざまなアプリケーションが、/opt/share 内の異なるディレクトリ内のデータを共有できます。
個別のパッケージとサービスを使用して共有データセットを作成できますが、このようなパッケージは別の BE からはインストールできない点に注意してください。共有データセットを作成したパッケージとサービスが現行 BE にインストールされていない場合でも、その共有データセットが使用可能である場合があります。これらの例に示されているアプリケーションパッケージによって配布されるサービスは、データセットがすでに存在しているかどうかを確認し、まだ存在していない場合はデータセットを作成します。
この手順では、このアプリケーションが複数 BE 内の複数のアプリケーションとデータを共有できるようにするために、共有データセットと、現行 BE からその共有データセットへのリンクを提供する方法を説明します。アプリケーションパッケージは次を配布します。
共有データセットを作成する SMF サービス
現行 BE 内に存在しており、そのターゲットが共有データセット内にあるリンク
この例のパッケージには、共有データセットを作成してその共有データセットにリンクするために必要なアクションだけを示します。実行可能ファイルや構成ファイルなど、アプリケーションのほかのアクションはこの例では省略されています。
BE に必要なディレクトリと、BE 外部の共有領域へのリンクを含む、パッケージ開発のための領域を作成します。
$ mkdir -p proto/lib/svc/manifest/site $ mkdir -p proto/lib/svc/method
$ mkdir -p proto/opt/myapp $ ln -s ../../opt/share/myapp/logfiles proto/opt/myapp/logfiles
proto/lib/svc/method で、次のタスクを実行するスクリプトを作成します。
BE 間で共有される rpool/OPTSHARE データセットを作成します。共有データセットの作成は、プールごとに 1 回だけ行う必要があります。プール内の現行 BE および将来の BE はすべて、そのデータセットにアクセスできます。データセットを作成する前に、そのデータセットがすでに存在しているかどうかを確認します。
共有データセット内に、この例でのリンクのターゲット (/opt/share/myapp/logfiles) を含むディレクトリ構造を作成します。
このスクリプトは、サービスの起動メソッドです。この例では、スクリプトの名前は myapp-share-files.sh です。次の手順でサービスマニフェストを作成するときに、このファイル名が必要になります。
スクリプトには、次のプロトタイプに示されている要素が必要です。デフォルトでは sh が ksh93 である点に注意してください。smf_method_exit には smf_include.sh ファイルが必要です。smf_method_exit の 3 番目の引数は、サービスログファイルと svcs コマンドからの出力に示されます。
#!/bin/sh # Load SMF shell support definitions . /lib/svc/share/smf_include.sh # Create rpool/OPTSHARE with mount point /opt/share if it does not already exist # Create /opt/share/myapp/logfiles if it does not already exist # After this script runs, the service does not need to remain online. smf_method_exit $SMF_EXIT_TEMP_DISABLE done "shared area created"
proto/lib/svc/manifest/site で、svcbundle コマンドを使用してサービスを作成します。これは内部サービスであるため、service-name にカテゴリ site を含めます。start-method の値は、前の手順で作成したスクリプトの名前です。
$ svcbundle -s service-name=site/myapp-share-files \ -s start-method=/lib/svc/method/myapp-share-files.sh -o myapp-share-files.xml
作成されたサービスマニフェストを編集し、common_name と description の情報を template データ領域に追加します。また、documentation とその他のテンプレートデータも追加できます。マイルストーン依存関係や起動メソッドのタイムアウトなど、デフォルト設定の一部を変更することもできます。デフォルトでは、作成されたインスタンスには default という名前が付けられ、有効化されます。
サービスマニフェストが有効であることを確認します。
$ svccfg validate myapp-share-files.xml
pkgsend generate コマンドを使用して、パッケージ開発領域から初期パッケージマニフェストを作成します。
$ pkgsend generate proto | pkgfmt > share.p5m.1 $ cat share.p5m.1 dir path=lib owner=root group=bin mode=0755 dir path=lib/svc owner=root group=bin mode=0755 dir path=lib/svc/manifest owner=root group=bin mode=0755 dir path=lib/svc/manifest/site owner=root group=bin mode=0755 file lib/svc/manifest/site/myapp-share-files.xml \ path=lib/svc/manifest/site/myapp-share-files.xml owner=root group=bin \ mode=0644 dir path=lib/svc/method owner=root group=bin mode=0755 file lib/svc/method/myapp-share-files.sh \ path=lib/svc/method/myapp-share-files.sh owner=root group=bin mode=0755 dir path=opt owner=root group=bin mode=0755 dir path=opt/myapp owner=root group=bin mode=0755 link path=opt/myapp/logfiles target=../../opt/share/myapp/logfiles
パッケージに名前、バージョン、サマリー、および説明を指定します。
opt、lib/svc/manifest/site、および lib/svc/method ディレクトリはほかのパッケージによってすでに配布されているため、これらのディレクトリアクションを削除します。
/lib/svc/manifest 内のほかのマニフェストに対応するように、サービスマニフェストのグループを sys に変更します。
システム上のほかのマニフェストとメソッドに対応するように、サービスマニフェストのモードを 0444 に変更し、サービスメソッドのモードを 0555 に変更します。
メソッドファイルのインストールまたは更新時には常に manifest-import サービスを再起動するようにするため、サービスマニフェストのアクチュエータとメソッドファイルを追加します。
set name=pkg.fmri value=myapp@2.0 set name=pkg.summary value="Deliver shared directory" set name=pkg.description value="This example package delivers a directory \ and link that allows myapp content to be shared across BEs." set name=variant.arch value=$(ARCH) set name=info.classification \ value=org.opensolaris.category.2008:Applications/Accessories <transform dir path=opt$->drop> <transform dir path=lib$->drop> <transform dir path=lib/svc$->drop> <transform dir path=lib/svc/manifest$->drop> <transform dir path=lib/svc/manifest/site$->drop> <transform dir path=lib/svc/method$->drop> <transform file path=lib/svc/manifest/site/myapp-share-files.xml -> \ edit group bin sys> <transform file path=lib/svc/manifest/site/myapp-share-files.xml -> \ edit mode 0644 0444> <transform file path=lib/svc/manifest/site/myapp-share-dir.xml -> \ add restart_fmri svc:/system/manifest-import:default> <transform file path=lib/svc/method/myapp-share-files.sh -> \ edit mode 0755 0555> <transform file path=lib/svc/method/myapp-share-dir.sh -> \ add restart_fmri svc:/system/manifest-import:default>
$ pkgmogrify -DARCH=`uname -p` share.p5m.1 share.mog | pkgfmt > share.p5m.2 $ cat share.p5m.2 set name=pkg.fmri value=myapp@2.0 set name=pkg.summary value="Deliver shared directory" set name=pkg.description \ value="This example package delivers a directory and link that allows myapp content to be shared across BEs." set name=info.classification \ value=org.opensolaris.category.2008:Applications/Accessories set name=variant.arch value=i386 file lib/svc/manifest/site/myapp-share-files.xml \ path=lib/svc/manifest/site/myapp-share-files.xml owner=root group=sys \ mode=0444 file lib/svc/method/myapp-share-files.sh \ path=lib/svc/method/myapp-share-files.sh owner=root group=bin mode=0755 dir path=opt/myapp owner=root group=bin mode=0555 link path=opt/myapp/logfiles target=../../opt/share/myapp/logfiles
pkgdepend コマンドを使用して、パッケージの依存関係を自動的に生成および解決します。依存関係の解決からの出力は、接尾辞 .res が付いたファイルに自動的に保存されます。
この例では、ksh93 の依存関係が生成されます。起動メソッドの処理によっては、追加の依存関係が生成されることがあります。また、サービスとサービスインスタンスが org.opensolaris.smf.fmri で宣言されます。
$ pkgdepend generate -md proto share.p5m.2 | pkgfmt > share.p5m.3 $ pkgdepend resolve -m share.p5m.3
出力 share.p5m.3.res ファイルに次の行が追加されます。
set name=org.opensolaris.smf.fmri value=svc:/site/myapp-share-files \ value=svc:/site/myapp-share-files:default depend fmri=pkg:/shell/ksh93@93.21.0.20110208-0.175.2.0.0.37.1 type=require depend fmri=pkg:/system/core-os@0.5.11-0.175.2.0.0.37.0 type=require
$ pkglint share.p5m.3.res
$ pkgsend -s site publish -d protosl share.p5m.3.res pkg://site/myapp@2.0,5.11:20140417T000014Z PUBLISHED
パッケージをインストールします。
$ pkg install -g ./site myapp
データセットとリンクが存在することを確認します。
$ zfs list rpool/OPTSHARE NAME USED AVAIL REFER MOUNTPOINT rpool/OPTSHARE 38.5K 24.8G 38.5K /opt/share $ ls -l /opt/myapp lrwxrwxrwx 1 root root 21 Apr 16 17:32 logfiles -> /opt/share/myapp/logfiles
パッケージをアンインストールします。/opt/myapp/logfiles リンクが削除され、サービスマニフェストとメソッドスクリプトが削除されているはずです。rpool/OPTSHARE データセットはパッケージ化された内容ではないため、存在している必要があります。これはサービスによって作成されたものです。
この手順は、前述の手順を拡張したものです。この例では、共有する必要がある一部のデータがすでに存在しています。アプリケーションパッケージは、ステージング領域を配布し、共有するデータをステージング領域にコピーします。SMF サービスはステージング領域から共有領域にデータを移動します。
リンクとして再定義されるディレクトリにすでに存在しているパッケージ解除された内容を保存するため、パッケージはリンクに加えステージング領域を BE に配布します。
SMF サービスは、共有データセットを作成するだけでなく、ステージング領域の既存の内容をすべて共有領域に移動します。
logfiles のすべてのオカレンスを logs に変更します。
$ mkdir -p proto/lib/svc/manifest/site $ mkdir -p proto/lib/svc/method $ mkdir -p proto/opt/myapp $ ln -s ../../opt/share/myapp/logs proto/opt/myapp/logs
この例では、myapp@1.0 パッケージが /opt/myapp/logs をディレクトリとしてインストールし、myapp アプリケーションが内容をそのディレクトリに書き込みます。この新しい myapp@3.0 パッケージが /opt/myapp/logs をリンクとしてインストールすると、/opt/myapp/logs ディレクトリの内容はすべて /var/pkg/lost+found に保存されます。代わりにその内容を新しい共有領域に保存するには、その内容のコピーを保持する領域を配布します。
$ mkdir -p proto/opt/myapp/.migrate/logs
このサービスにより BE 内のステージング領域から共有領域に内容が移動されます。
myapp@3.0 パッケージが /opt/myapp/logs に書き込む内容は、前の例で示したようにリンクを介して共有領域に直接移動されます。
前の手順で作成した proto/lib/svc/method/myapp-share-files.sh スクリプトに、「ステージング領域から共有領域への内容の移動」タスクを追加します。
サービスを使用して空のステージング領域を削除しないでください。ステージング領域はパッケージ化された内容であり、パッケージのアンインストールによってのみ削除される必要があります。
#!/bin/sh # Load SMF shell support definitions . /lib/svc/share/smf_include.sh # Create rpool/OPTSHARE with mount point /opt/share if it does not already exist # Create /opt/share/myapp/logfiles if it does not already exist # Move any content from /opt/myapp/.migrate/logs to /opt/share/myapp/logs # After this script runs, the service does not need to remain online. smf_method_exit $SMF_EXIT_TEMP_DISABLE done "myapp shared files moved"
$ svcbundle -s service-name=site/myapp-share-files \ -s start-method=/lib/svc/method/myapp-share-files.sh -o myapp-share-files.xml
svccfg validate コマンドを使用して、サービスマニフェストが有効であることを確認します。
このマニフェストは、前述の例のパッケージマニフェストと同じですが、次の点が変更されています。
logfiles のオカレンスがすべて logs に変更されています。
次の 2 つのアクションが追加されています。
dir path=opt/myapp/.migrate owner=root group=bin mode=0755 dir path=opt/myapp/.migrate/logs owner=root group=bin mode=0755
前述の例の pkgmogrify の share.mog 入力ファイルに、次の行を追加します。salvage-from 属性は、/opt/myapp/logs ディレクトリのパッケージ解除された内容をすべて /opt/myapp/.migrate/logs ディレクトリに移動します。その後サービスが /opt/myapp/.migrate/logs から /opt/share/myapp/logs にその内容を移動します。
<transform dir path=opt/myapp/.migrate/logfiles -> \ add salvage-from /opt/myapp/logfiles>
このパッケージに myapp@3.0 という名前を付けます。
前述の例と同様に pkgmogrify を実行します。
標準ディレクトリとして /opt/myapp/logs を作成し、いくつかのファイルを配置します。
myapp@3.0 パッケージをインストールします。データセットの存在が正しく検出および処理されること、新しいリンクが存在していること、/opt/myapp/logs ディレクトリが空であること、/opt/myapp/.migrate/logs ディレクトリが存在しており空であること、/opt/share/myapp/logs ディレクトリが存在しており、/opt/myapp/logs ディレクトリに最初に保管されていた内容が含まれていることを確認します。