この章では、パッケージ作成のさまざまなシナリオを、ケーススタディーとして示します。この章のケーススタディーでは、オブジェクトを条件に応じてインストールしたり、作成するファイル数を実行時に決定したり、パッケージのインストール時および削除時に既存のデータファイルを変更する例を取り上げます。
各ケーススタディーでは、最初に説明を示し、次にパッケージ作成に使用するテクニックのリストと、それらのテクニックを使用する際のアプローチにについて説明したあと、ケーススタディーに関連するサンプルのファイルとスクリプトを示します。
この章で説明するケーススタディーは次のとおりです。
このケーススタディーで使用するパッケージには、3 種類のオブジェクトがあります。インストールするオブジェクトの種類と、インストール先マシン内でオブジェクトを配置する場所は、管理者が選択できます。
このケーススタディーでは、次の手法の実例を示します。
パラメータ型パス名 (オブジェクトのパス名に変数を含めたもの) を使用し、複数のベースディレクトリを確立する
パラメータ型パス名については、「パラメータ型パス名」を参照してください。
request スクリプトを使用して、管理者による入力を要求する
request スクリプトについては、「request スクリプトの書き込み」を参照してください。
インストールパラメータの条件値を設定する。
このケーススタディーで選択的インストールを設定するには、次の作業を完了する必要があります。
インストール可能な各タイプのオブジェクトについてクラスを定義します。
このケーススタディーの場合、オブジェクトのタイプには、パッケージ実行可能ファイル、マニュアルページ、および emacs 実行可能ファイルの 3 種類があります。各タイプには、それぞれ bin、man、および emacs というクラスが定義されています。prototype ファイルでは、すべてのオブジェクトファイルは、これら 3 つのクラスのいずれかに属しています。
pkginfo ファイル内の CLASSES パラメータを null に初期化します。
通常、クラスを定義する場合は、そのクラスを pkginfo ファイルの CLASSES パラメータにリストします。リストしない場合、そのクラスのオブジェクトはインストールされません。このケーススタディーでは、このパラメータは初期値として null に設定されているため、オブジェクトはインストールされません。CLASSES パラメータは、管理者の選択に基づいて、request スクリプトによって変更されます。そうすることで、CLASSES パラメータには、管理者がインストールするように選択したオブジェクトタイプだけが設定されます。
通常は、各パラメータはデフォルト値に設定することをお勧めします。3 つすべてのオブジェクトタイプに共通のコンポーネントがこのパッケージに含まれている場合は、それらのコンポーネントを none クラスに割り当て、CLASSES パラメータを none に設定します。
prototype ファイルにパラメータ型パス名を挿入します。
これらの環境変数は、request スクリプトによって、管理者が指定した値に設定されます。次に、pkgadd コマンドによって、インストール時にこれらの環境変数が解釈処理され、パッケージのインストール先が決定されます。
この例で使用される 3 つの環境変数は、pkginfo ファイルでそれぞれのデフォルト値に設定されます。これらの環境変数の用途は次のとおりです。
$NCMPBIN は、オブジェクト実行可能ファイルの場所を定義します。
$NCMPMAN は、マニュアルページの場所を定義します。
$EMACS は、emacs 実行可能ファイルの場所を定義します。
サンプルの prototype ファイルに、変数を使用してオブジェクトパス名を定義する方法を示します。
管理者に、パッケージのどの部分をインストールし、どこに配置するかを質問する request スクリプトを作成します。
このパッケージ用の request スクリプトは、管理者に対して次の 2 つの質問をします。
パッケージのこの部分をインストールするかどうか
管理者が「y (はい)」 と答えた場合には、適切なクラス名が CLASSES パラメータに追加されます。たとえば、管理者がこのパッケージに関連するマニュアルページをインストールするように選択した場合は、クラス man が CLASSES パラメータに追加されます。
インストールする場合、パッケージのこの部分をどこに配置するか
この質問に対する応答として指定した場所が、該当する環境変数に設定されます。マニュアルページの例では、変数 $NCMPMAN が、応答として指定した値に設定されています。
これら 2 つの質問は、3 つのオブジェクトタイプのそれぞれについて繰り返されます。
request スクリプトの実行が終了すると、これらのパラメータはインストール環境で pkgadd コマンドやその他のパッケージ作成スクリプトを実行する際に使用できるようになります。request スクリプトは、これらの定義を呼び出しユーティリティから指定されたファイルに書き込むことで、パラメータを使用可能にします。このケーススタディーでは、これ以外のスクリプトは使用しません。
このケーススタディーで使用する request スクリプトでは、質問はデータ検証ツールの ckyorn および ckpath によって生成されています。これらのツールについては、ckyorn(1)およびckpath(1)を参照してください。
PKG=ncmp NAME=NCMP Utilities CATEGORY=application, tools BASEDIR=/ ARCH=SPARC VERSION=RELEASE 1.0, Issue 1.0 CLASSES="" NCMPBIN=/bin NCMPMAN=/usr/man EMACS=/usr/emacs |
i pkginfo i request x bin $NCMPBIN 0755 root other f bin $NCMPBIN/dired=/usr/ncmp/bin/dired 0755 root other f bin $NCMPBIN/less=/usr/ncmp/bin/less 0755 root other f bin $NCMPBIN/ttype=/usr/ncmp/bin/ttype 0755 root other f emacs $NCMPBIN/emacs=/usr/ncmp/bin/emacs 0755 root other x emacs $EMACS 0755 root other f emacs $EMACS/ansii=/usr/ncmp/lib/emacs/macros/ansii 0644 root other f emacs $EMACS/box=/usr/ncmp/lib/emacs/macros/box 0644 root other f emacs $EMACS/crypt=/usr/ncmp/lib/emacs/macros/crypt 0644 root other f emacs $EMACS/draw=/usr/ncmp/lib/emacs/macros/draw 0644 root other f emacs $EMACS/mail=/usr/ncmp/lib/emacs/macros/mail 0644 root other f emacs $NCMPMAN/man1/emacs.1=/usr/ncmp/man/man1/emacs.1 0644 root other d man $NCMPMAN 0755 root other d man $NCMPMAN/man1 0755 root other f man $NCMPMAN/man1/dired.1=/usr/ncmp/man/man1/dired.1 0644 root other f man $NCMPMAN/man1/ttype.1=/usr/ncmp/man/man1/ttype.1 0644 root other f man $NCMPMAN/man1/less.1=/usr/ncmp/man/man1/less.1 0644 inixmr other |
trap 'exit 3' 15 # determine if and where general executables should be placed ans=`ckyorn -d y \ -p "Should executables included in this package be installed" ` || exit $? if [ "$ans" = y ] then CLASSES="$CLASSES bin" NCMPBIN=`ckpath -d /usr/ncmp/bin -aoy \ -p "Where should executables be installed" ` || exit $? fi # determine if emacs editor should be installed, and if it should # where should the associated macros be placed ans=`ckyorn -d y \ -p "Should emacs editor included in this package be installed" ` || exit $? if [ "$ans" = y ] then CLASSES="$CLASSES emacs" EMACS=`ckpath -d /usr/ncmp/lib/emacs -aoy \ -p "Where should emacs macros be installed" ` || exit $? fi |
request スクリプトは、ファイルシステム上にファイルを残さずに終了できます。Solaris バージョン 2.5 よりも前のバージョンおよび互換バージョンでインストールを行う場合、checkinstall スクリプトが使用されていない可能性があるので、request スクリプトを使用してファイルシステムのテストを行い、インストールの成功を確認することをお勧めします。request スクリプトがコード 1 で終了すると、インストールはクリーンに終了します。
これらのファイル例では、パラメータ型パスを使用して複数のベースディレクトリを確立する方法が示されています。しかし、pkgadd コマンドによって管理および検証される BASEDIR パラメータを使用する必要が生じる場合もあります。複数のベースディレクトリを使用する際には、同じプラットフォームに複数のバージョンやアーキテクチャーをインストールする場合に備えて、特別な注意を払う必要があります。
このケーススタディーでは、インストール時にデータベースファイルを作成し、パッケージの削除時にデータベースのコピーを保存します。
このケーススタディーでは、次の手法の実例を示します。
クラスおよびクラスアクションスクリプトを使用して、オブジェクトのさまざまなセットに対して特別なアクションを実行する
詳細については、「クラスアクションスクリプトの書き込み」を参照してください。
space ファイルを使用して、このパッケージを正しくインストールするには追加のスペースが必要であることを pkgadd コマンドに通知する
space ファイルについては、「ターゲットシステムでの追加領域の予約」を参照してください。
installf コマンドを使用して、prototype および pkgmap ファイルで定義されていないファイルをインストールする。
このケーススタディーに従って、インストール時にデータベースファイルを作成し、削除時にコピーを保存するには、次の作業を完了する必要があります。
3 つのクラスを定義します。
このケーススタディーで使用するパッケージには、CLASSES パラメータで次の 3 つのクラスを定義しておく必要があります。
標準クラスである none。これには、サブディレクトリ bin にある一連のプロセスが含まれています。
admin クラス。これには、実行可能ファイル config と、データファイルを格納したディレクトリが含まれています。
cfgdata クラス。これには、ディレクトリが含まれています。
パッケージを、全体として再配置可能にします。
prototype ファイルに、スラッシュまたは環境変数で始まるパス名が存在しないことに注目してください。このことは、これらが全体として再配置可能であることを示しています。
データベースファイルに必要なスペースのサイズを計算し、パッケージとともに配信する space ファイルを作成します。このファイルは pkgadd コマンドに対して、パッケージが追加スペースを必要とすることを通知し、そのサイズを指定します。
admin クラス用のクラスアクションスクリプト (i.admin) を作成します。
サンプルのスクリプトでは、admin クラスに属するデータファイルを使用して、データベースを初期化しています。この作業を実行するために、スクリプトは次の処理を実行します。
ソースデータファイルを、その適切なターゲットにコピーします。
config.data という名前の空ファイルを作成し、cfgdata のクラスに割り当てます。
bin/config コマンド (パッケージとともに提供され、すでにインストールされている) を実行し、admin クラスに属するデータファイルを使用して、データベースファイル config.data を生成します。
installf -f コマンドを実行し、config.data のインストールをファイナライズします。
削除時に、admin クラスに対して特別なアクションは必要ないため、削除クラスアクションスクリプトは作成されません。つまり、admin クラスのすべてのファイルとディレクトリは、システムから削除されます。
cfgdata クラス用の削除クラスアクションスクリプト (r.cfgdata) を作成します。
この削除スクリプトは、データベースファイルが削除される前に、そのコピーを作成します。インストール時に、このクラスに対して特別なアクションは必要ないため、インストールクラスアクションスクリプトは必要ありません。
削除スクリプトへの入力は、削除するパス名のリストです。パス名は、常にアルファベットの逆順に表示されます。この削除スクリプトは、ファイルを $PKGSAV というディレクトリにコピーします。すべてのパス名が処理されると、スクリプトは先頭のパス名に戻り、cfgdata クラスに関連付けられたすべてのディレクトリとファイルを削除します。
この削除スクリプトが実行されると、その結果として、config.data が $PKGSAV にコピーされ、次に config.data ファイルとデータディレクトリが削除されます。
PKG=krazy NAME=KrAzY Applications CATEGORY=applications BASEDIR=/opt ARCH=SPARC VERSION=Version 1 CLASSES=none cfgdata admin |
i pkginfo i request i i.admin i r.cfgdata d none bin 555 root sys f none bin/process1 555 root other f none bin/process2 555 root other f none bin/process3 555 root other f admin bin/config 500 root sys d admin cfg 555 root sys f admin cfg/datafile1 444 root sys f admin cfg/datafile2 444 root sys f admin cfg/datafile3 444 root sys f admin cfg/datafile4 444 root sys d cfgdata data 555 root sys |
# extra space required by config data which is # dynamically loaded onto the system data 500 1 |
# PKGINST parameter provided by installation service # BASEDIR parameter provided by installation service while read src dest do cp $src $dest || exit 2 done # if this is the last time this script will be executed # during the installation, do additional processing here. if [ "$1" = ENDOFCLASS ] then # our config process will create a data file based on any changes # made by installing files in this class; make sure the data file # is in class `cfgdata' so special rules can apply to it during # package removal. installf -c cfgdata $PKGINST $BASEDIR/data/config.data f 444 root sys || exit 2 $BASEDIR/bin/config > $BASEDIR/data/config.data || exit 2 installf -f -c cfgdata $PKGINST || exit 2 fi exit 0 |
ここでは、クラスアクションスクリプトで installf が使用される珍しい例が示されています。space ファイルを使用して、対象のファイルシステム上でスペースを予約しているため、この新しいファイルは、pkgmap ファイルに含まれていない場合でも、安全に追加されます。
# the product manager for this package has suggested that # the configuration data is so valuable that it should be # backed up to $PKGSAV before it is removed! while read path do # path names appear in reverse lexical order. mv $path $PKGSAV || exit 2 rm -f $path || exit 2 done exit 0 |
このケーススタディーのパッケージでは、パッケージの互換性と依存関係を定義したり、インストール中に著作権に関するメッセージを表示したりするために、省略可能な情報ファイルを使用しています。
このケーススタディーでは、次の手法の実例を示します。
copyright ファイルを使用する
compver ファイルを使用する
depend ファイルを使用する
これらのファイルについては、「情報ファイルの作成」を参照してください。
この説明での必要条件を満たすには、次の作業を行う必要があります。
copyright ファイルを作成します。
copyright ファイルには、著作権に関するメッセージを記述した ASCII テキストが含まれています。サンプルファイルに示したメッセージは、パッケージのインストール中に画面に表示されます。
compver ファイルを作成します。
次の図に示す pkginfo ファイルでは、このパッケージのバージョンをバージョン 3.0 と定義しています。 compver ファイルではバージョン 3.0 を、バージョン 2.3、2.2、2.1、2.1.1、2.1.3、 および 1.7 と互換性があると定義しています。
depend ファイルを作成します。
depend ファイル内に記載されているファイルは、パッケージをインストールする際に、あらかじめシステムにインストールされている必要があります。サンプルのファイルには、インストール時にあらかじめシステムにインストールされている必要のある 11 のパッケージが記載されています。
PKG=case3 NAME=Case Study #3 CATEGORY=application BASEDIR=/opt ARCH=SPARC VERSION=Version 3.0 CLASSES=none |
Copyright (c) 1999 company_name All Rights Reserved. THIS PACKAGE CONTAINS UNPUBLISHED PROPRIETARY SOURCE CODE OF company_name. The copyright notice above does not evidence any actual or intended publication of such source code |
Version 3.0 Version 2.3 Version 2.2 Version 2.1 Version 2.1.1 Version 2.1.3 Version 1.7 |
P acu Advanced C Utilities Issue 4 Version 1 P cc C Programming Language Issue 4 Version 1 P dfm Directory and File Management Utilities P ed Editing Utilities P esg Extended Software Generation Utilities Issue 4 Version 1 P graph Graphics Utilities P rfs Remote File Sharing Utilities Issue 1 Version 1 P rx Remote Execution Utilities P sgs Software Generation Utilities Issue 4 Version 1 P shell Shell Programming Utilities P sys System Header Files Release 3.1 |
このケーススタディーでは、標準クラスとクラスアクションスクリプトを使用して、パッケージのインストール中に既存のファイルを変更します。ここでは、3 種類の変更方法のうちの 1 つを使用します。ほかの 2 つの方法については、「sed クラスと postinstall スクリプトを使用したファイルの変更」および「build クラスを使用したファイルの変更」を参照してください。変更する対象のファイルは、/etc/inittab です。
このケーススタディーでは、インストールおよび削除クラスアクションスクリプトの使用方法を説明します。詳細については、「クラスアクションスクリプトの書き込み」を参照してください。
クラスおよびクラスアクションスクリプトを使用して、インストール中に /etc/inittab を変更するには、次の作業を完了する必要があります。
クラスを作成します。
inittab という名前のクラスを作成します。このクラスに対して、インストールおよび削除クラスアクションスクリプトを作成する必要があります。pkginfo ファイルの CLASSES パラメータで inittab クラスを定義します。
inittab ファイルを作成します。
このファイルには、/etc/inittab に追加するエントリの情報を格納します。prototype ファイルの図で、inittab は inittab クラスのメンバーで、ファイルタイプは編集可能を表す e となっていることに注目してください。
インストールクラスアクションスクリプト (i.inittab) を作成します。
クラスアクションスクリプトは、実行されるたびに同じ結果を生じる必要があります。このクラスアクションスクリプトは、次の手順を実行します。
このエントリが以前に追加されているかどうかをチェックします。
追加されている場合は、このエントリの以前のバージョンをすべて削除します。
inittab ファイルを編集し、このエントリの出自がわかるようにコメント行を追加します。
一時ファイルを /etc/inittab に戻します。
ENDOFCLASS インジケータを受け取ったときに init q コマンドを実行します。
init q コマンドは、このインストールスクリプトで実行できます。このアプローチでは、1 行だけの postinstall スクリプトは必要ありません。
削除クラスアクションスクリプト (r.inittab) を作成します。
削除スクリプトは、インストールスクリプトと非常によく似ています。インストールスクリプトが追加した情報を削除し、init q コマンドを実行します。
このケーススタディーは、次のケーススタディーよりも複雑です。「sed クラスと postinstall スクリプトを使用したファイルの変更」を参照してください。2 つではなく 3 つのファイルを作成する必要があり、配信された /etc/inittab ファイルは実際には、挿入するエントリの断片を含んだ可変部分に過ぎません。pkgadd コマンドが i.inittab ファイルに渡すファイルを必要としなければ、これは i.inittab ファイルに組み込まれていたかも知れません。また、削除の手順も別個のファイル (r.inittab) に置く必要があります。この方法はうまく行きますが、複数のファイルをインストールする必要のある非常に複雑なケースに最も向いています。「インストール時の crontab ファイルの変更」を参照してください。
「sed クラスと postinstall スクリプトを使用したファイルの変更」で使用されている sed プログラムは、inittab エントリの最後にあるコメントがパッケージのインスタンスに基づいているため、複数のパッケージのインスタンスをサポートします。「build クラスを使用したファイルの変更」のケーススタディーでは、インストール中に /etc/inittab を編集するための、より効率的なアプローチが紹介されています。
PKG=case5 NAME=Case Study #5 CATEGORY=applications BASEDIR=/opt ARCH=SPARC VERSION=Version 1d05 CLASSES=inittab |
i pkginfo i i.inittab i r.inittab e inittab /etc/inittab ? ? ? |
# PKGINST parameter provided by installation service while read src dest do # remove all entries from the table that # associated with this PKGINST sed -e "/^[^:]*:[^:]*:[^:]*:[^#]*#$PKGINST$/d" $dest > /tmp/$$itab || exit 2 sed -e "s/$/#$PKGINST" $src >> /tmp/$$itab || exit 2 mv /tmp/$$itab $dest || exit 2 done if [ "$1" = ENDOFCLASS ] then /sbin/init q || exit 2 fi exit 0 |
# PKGINST parameter provided by installation service while read src dest do # remove all entries from the table that # are associated with this PKGINST sed -e "/^[^:]*:[^:]*:[^:]*:[^#]*#$PKGINST$/d" $dest > /tmp/$$itab || exit 2 mv /tmp/$$itab $dest || exit 2 done /sbin/init q || exit 2 exit 0 |
rb:023456:wait:/usr/robot/bin/setup |
このケーススタディーでは、パッケージのインストール中に、インストール先マシンに存在しているファイルを変更します。ここでは、3 種類の変更方法のうちの 1 つを使用します。ほかの 2 つの方法については、「標準クラスとクラスアクションスクリプトを使用したファイルの変更」および「build クラスを使用したファイルの変更」を参照してください。変更する対象のファイルは、/etc/inittab です。
このケーススタディーでは、次の手法の実例を示します。
sed クラスを使用する
sed クラスの詳細については、「sed クラススクリプト」を参照してください。
postinstall スクリプトを使用する
このスクリプトの詳細については、「手続きスクリプトの書き込み」を参照してください。
インストール時に /etc/inittab を変更するには、sed クラスを使用して、次の作業を完了する必要があります。
sed クラススクリプトを prototype ファイルに追加します。
スクリプトの名前は、編集対象ファイルの名前である必要があります。このケースでは、編集対象のファイルが /etc/inittab であるため、sed スクリプトの名前も /etc/inittab となります。sed スクリプトのモード、所有者、およびグループには必要条件はありません (サンプルの prototype ではクエスチョンマークで表されています)。sed スクリプトのファイルタイプは e (編集可能であることを表す) である必要があります。
CLASSES パラメータに sed クラスを含めます。
例として示したファイルでは、インストールされるクラスは sed だけです。ただし、必要に応じて、任意の数のクラスを指定することができます。
sed クラスアクションスクリプトを作成します。
/etc/inittab は動的ファイルで、パッケージをインストールする時点での内容を知る方法がないため、必要な動作を指定した /etc/inittab のコピーをパッケージで提供することはできません。しかし、sed スクリプトを使用することで、パッケージのインストール時に /etc/inittab ファイルを変更できます。
postinstall スクリプトを作成します。
init q コマンドを実行して、/etc/inittab が変更されたことをシステムに通知する必要があります。この例で、そのアクションを実行できるのは、postinstall スクリプトだけです。サンプルの postinstall スクリプトは、init q コマンドの実行だけを行なっています。
この方法でインストール中に /etc/inittab を編集する場合、欠点が 1 つあります。それは、init q コマンドを実行するだけのために、完全なスクリプト (postinstall スクリプト) を提供する必要があるという点です。
PKG=case4 NAME=Case Study #4 CATEGORY=applications BASEDIR=/opt ARCH=SPARC VERSION=Version 1d05 CLASSES=sed |
i pkginfo i postinstall e sed /etc/inittab ? ? ? |
!remove # remove all entries from the table that are associated # with this package, though not necessarily just # with this package instance /^[^:]*:[^:]*:[^:]*:[^#]*#ROBOT$/d !install # remove any previous entry added to the table # for this particular change /^[^:]*:[^:]*:[^:]*:[^#]*#ROBOT$/d # add the needed entry at the end of the table; # sed(1) does not properly interpret the '$a' # construct if you previously deleted the last # line, so the command # $a\ # rb:023456:wait:/usr/robot/bin/setup #ROBOT # will not work here if the file already contained # the modification. Instead, you will settle for # inserting the entry before the last line! $i\ rb:023456:wait:/usr/robot/bin/setup #ROBOT |
# make init re-read inittab /sbin/init q || exit 2 exit 0 |
このケーススタディーでは、パッケージのインストール中に、インストール先マシンに存在しているファイルを変更します。ここでは、3 種類の変更方法のうちの 1 つを使用します。ほかの 2 つの方法については、「標準クラスとクラスアクションスクリプトを使用したファイルの変更」および「sed クラスと postinstall スクリプトを使用したファイルの変更」を参照してください。変更する対象のファイルは、/etc/inittab です。
このケーススタディーでは、build クラスの使用方法を説明します。build クラスの詳細については、「build クラススクリプト」を参照してください。
このアプローチでは、/etc/inittab を変更するために build クラスを使用します。build クラススクリプトはシェルスクリプトとして実行され、実行されているファイルの新しいバージョンを出力します。つまり、このパッケージに付属するデータファイル /etc/inittab が実行され、その実行の出力が /etc/inittab になります。
build クラススクリプトは、パッケージのインストールおよび削除の際に実行されます。ファイルがインストール時に実行される場合には、引数 install がファイルに渡されます。サンプルの build クラススクリプトでは、この引数をテストすることで、インストールのアクションが定義されています。
build クラスを使用して /etc/inittab を編集するには、次の作業を完了する必要があります。
prototype ファイルで構築ファイルを定義します。
prototype ファイル内の構築ファイルのエントリでは、構築ファイルを build クラスとして指定し、そのファイルタイプを e として定義する必要があります。pkginfo ファイルの CLASSES パラメータが build として定義されていることを確認してください。
build クラススクリプトを作成します。
サンプルの build クラススクリプトは、次の手順を実行します。
/etc/inittab ファイルを編集し、このパッケージに関する既存の変更をすべて削除する。ファイル名 /etc/inittab は、sed コマンドにハードコードされています。
パッケージがインストールされる場合は、/etc/inittab の最後に新しい行を追加する。この新しいエントリには、そのエントリの出自を示すコメントタグが含まれています。
init q コマンドを実行する。
この解決方法は、「標準クラスとクラスアクションスクリプトを使用したファイルの変更」および「sed クラスと postinstall スクリプトを使用したファイルの変更」のケーススタディーで説明した欠点に対応しています。短いファイルがひとつ (pkginfo および prototype ファイル以外に) 必要になるだけです。PKGINST パラメータを使用することにより、このファイルはパッケージの複数のインスタンスを処理することができ、init q コマンドを build クラススクリプトから実行することにより、postinstall スクリプトが不要になります。
PKG=case6 NAME=Case Study #6 CATEGORY=applications BASEDIR=/opt ARCH=SPARC VERSION=Version 1d05 CLASSES=build |
i pkginfo e build /etc/inittab ? ? ? |
# PKGINST parameter provided by installation service # remove all entries from the existing table that # are associated with this PKGINST sed -e "/^[^:]*:[^:]*:[^:]*:[^#]*#$PKGINST$/d" /etc/inittab || exit 2 if [ "$1" = install ] then # add the following entry to the table echo "rb:023456:wait:/usr/robot/bin/setup #$PKGINST" || exit 2 fi /sbin/init q || exit 2 exit 0 |
このケーススタディーでは、パッケージのインストール中に crontab ファイルを変更します。
このケーススタディーでは、次の手法の実例を示します。
クラスおよびクラスアクションスクリプトを使用する
詳細については、「クラスアクションスクリプトの書き込み」を参照してください。
クラスアクションスクリプト内で crontab コマンドを使用する。
インストール中に複数のファイルを編集する最も効率的な方法は、クラスを定義し、クラスアクションスクリプトを作成することです。build クラスによるアプローチを使用した場合は、編集する crontab ファイルごとに 1 つの build クラススクリプトを作成する必要があります。cron クラスを定義する方法は、より汎用性のあるアプローチとなります。このアプローチで crontab ファイルを編集するには、次の作業を行う必要があります。
prototype ファイルで、編集対象の crontab ファイルを定義します。
prototype ファイルで、編集対象の crontab ファイルごとにエントリを作成します。クラスを cron として定義し、ファイルタイプをファイルごとに e として定義します。編集対象とするファイルの実際の名前を使用してください。
パッケージ用の crontab ファイルを作成します。
これらのファイルには、同じ名前の既存の crontab ファイルに追加する情報を格納します。
cron クラス用のインストールクラスアクションスクリプトを作成します。
サンプルの i.cron スクリプトは、次の手順を実行します。
ユーザー ID (UID) を決定する。
i.cron スクリプトは、変数 user を、処理対象の cron クラススクリプトのベース名に設定します。この名前が UID です。たとえば、/var/spool/cron/crontabs/root のベース名は root で、これが UID でもあります。
UID と -l オプションを使用して、crontab を実行します。
-l オプションは、定義されたユーザーの crontab ファイルの内容を標準出力に送信するように、crontab に指示します。
crontab コマンドの出力を、このインストール手法で以前に追加されたすべてのエントリを削除する sed スクリプトにパイプで連結します。
編集された出力を一時ファイルに置きます。
ルート UID のデータファイル (パッケージとともに提供されたもの) を一時ファイルに追加し、これらのエントリの出自を示すタグを追加します。
同じ UID の crontab を実行し、一時ファイルを入力として指定します。
cron クラス用の削除クラスアクションスクリプトを作成します。
r.cron スクリプトは、crontab ファイルに情報を追加する手順がない点を除き、インストールスクリプトと同じです。
これらの手順は、cron クラスのすべてのファイルに対して実行されます。
次に示す i.cron および r.cron スクリプトは、スーパーユーザーによって実行されます。ほかのユーザーの crontab ファイルをスーパーユーザーとして編集すると、予期しない結果が生じる可能性があります。必要な場合は、各スクリプトで次に示すエントリを変更してください。
crontab $user < /tmp/$$crontab ||
から
su $user -c "crontab /tmp/$$crontab" ||
PKG=case7 NAME=Case Study #7 CATEGORY=application BASEDIR=/opt ARCH=SPARC VERSION=Version 1.0 CLASSES=cron |
i pkginfo i i.cron i r.cron e cron /var/spool/cron/crontabs/root ? ? ? e cron /var/spool/cron/crontabs/sys ? ? ? |
# PKGINST parameter provided by installation service while read src dest do user=`basename $dest` || exit 2 (crontab -l $user | sed -e "/#$PKGINST$/d" > /tmp/$$crontab) || exit 2 sed -e "s/$/#$PKGINST/" $src >> /tmp/$$crontab || exit 2 crontab $user < /tmp/$$crontab || exit 2 rm -f /tmp/$$crontab done exit 0 |
# PKGINST parameter provided by installation service while read path do user=`basename $path` || exit 2 (crontab -l $user | sed -e "/#$PKGINST$/d" > /tmp/$$crontab) || exit 2 crontab $user < /tmp/$$crontab || exit 2 rm -f /tmp/$$crontab done exit |
41,1,21 * * * * /usr/lib/uucp/uudemon.hour > /dev/null 45 23 * * * ulimit 5000; /usr/bin/su uucp -c "/usr/lib/uucp/uudemon.cleanup" > /dev/null 2>&1 11,31,51 * * * * /usr/lib/uucp/uudemon.poll > /dev/null |
0 * * * 0-6 /usr/lib/sa/sa1 20,40 8-17 * * 1-5 /usr/lib/sa/sa1 5 18 * * 1-5 /usr/lib/sa/sa2 -s 8:00 -e 18:01 -i 1200 -A |
複数のファイルを編集することにより、ファイルの合計サイズが 10K を超えて増加する場合は、pkgadd コマンドがこの増加に対応できるように、space ファイルを作成してください。space ファイルについては、「ターゲットシステムでの追加領域の予約」を参照してください。
このパッケージでは、ドライバをインストールします。
このケーススタディーでは、次の手法の実例を示します。
postinstall スクリプトを使用して、ドライバをインストールおよびロードする
preremove スクリプトを使用して、ドライバをアンロードする
これらのスクリプトの詳細については、「手続きスクリプトの書き込み」を参照してください。
request スクリプトを作成します。
request スクリプトは、管理者に対してドライバオブジェクトのインストール先を質問し、その答えを $KERNDIR パラメータに割り当てることで、ドライバオブジェクトのインストール先を決定します。
このスクリプトは、CLASSES および KERNDIR の 2 つのパラメータを、インストール環境と postinstall スクリプトで使用できるようにするルーチンを実行して終了します。
postinstall スクリプトを作成します。
postinstall スクリプトは、実際にはドライバのインストールを実行します。ドライバのインストールは、buffer と buffer.conf という 2 つのファイルがインストールされたあとに実行されます。この例で示した postinstall ファイルは、次のアクションを実行します。
add_drv コマンドを使用して、ドライバをシステムにロードします。
installf コマンドを使用して、デバイスのリンクを作成します。
installf -f コマンドを使用して、インストールをファイナライズします。
preremove スクリプトを作成します。
preremove スクリプトは rem_drv コマンドを使用して、システムからドライバをアンロードしたあと、リンク /dev/buffer0 を削除します。
PKG=bufdev NAME=Buffer Device CATEGORY=system BASEDIR=/ ARCH=INTEL VERSION=Software Issue #19 CLASSES=none |
インストール時にドライバをインストールするには、ドライバのオブジェクトおよび構成ファイルを prototype ファイルに含める必要があります。
この例では、ドライバの実行モジュールの名前は buffer です。add_drv コマンドは、このファイルに対して実行されます。カーネルは、構成ファイル buffer.conf をドライバの構成に利用します。
i pkginfo i request i postinstall i preremove f none $KERNDIR/buffer 444 root root f none $KERNDIR/buffer.conf 444 root root |
この例の prototype ファイルを見て、次の点に注意してください。
パッケージオブジェクトについて特別な処理は必要ないため、それらのオブジェクトは標準の none クラスに配置できます。pkginfo ファイルの CLASSES パラメータは none に設定されています。
buffer と buffer.conf のパス名が、変数 $KERNDIR で始まっています。この変数は request スクリプトで設定され、管理者はこの変数によってドライバファイルのインストール先を決定できます。デフォルトのディレクトリは /kernel/drv です。
postinstall スクリプト (ドライバのインストールを実行するスクリプト) のエントリが存在します。
trap 'exit 3' 15 # determine where driver object should be placed; location # must be an absolute path name that is an existing directory KERNDIR=`ckpath -aoy -d /kernel/drv -p \ “Where do you want the driver object installed”` || exit $? # make parameters available to installation service, and # so to any other packaging scripts cat >$1 <<! CLASSES='$CLASSES' KERNDIR='$KERNDIR' ! exit 0 |
# KERNDIR parameter provided by `request' script err_code=1 # an error is considered fatal # Load the module into the system cd $KERNDIR add_drv -m '* 0666 root sys' buffer || exit $err_code # Create a /dev entry for the character node installf $PKGINST /dev/buffer0=/devices/eisa/buffer*:0 s installf -f $PKGINST |
err_code=1 # an error is considered fatal # Unload the driver rem_drv buffer || exit $err_code # remove /dev file removef $PKGINST /dev/buffer0 ; rm /dev/buffer0 removef -f $PKGINST |
このケーススタディーでは、sed クラスと手続きスクリプトを使用してドライバをインストールする方法を説明します。このパッケージは絶対オブジェクトと再配置可能オブジェクトの両方から構成されるため、この方法は前のケーススタディー (「手続きスクリプトによるドライバのインストールと削除」を参照) とは異なります。
このケーススタディーでは、次の手法の実例を示します。
絶対オブジェクトと再配置可能オブジェクトの両方を使用して prototype ファイルを作成する
prototype ファイルの作成の詳細については、「prototype ファイルの作成 」を参照してください。
postinstall スクリプトを使用する
このスクリプトの詳細については、「手続きスクリプトの書き込み」を参照してください。
preremove スクリプトを使用する
このスクリプトの詳細については、「手続きスクリプトの書き込み」を参照してください。
copyright ファイルを使用する
このファイルについては、「著作権に関するメッセージの書き込み」を参照してください。
絶対パッケージオブジェクトと再配置可能パッケージオブジェクトの両方を含んだ prototype ファイルを作成します。
詳細は、「prototype ファイル」を参照してください。
sed クラススクリプトを prototype ファイルに追加します。
スクリプトの名前は、編集対象ファイルの名前である必要があります。このケースでは、編集対象のファイルが /etc/devlink.tab であるため、sed スクリプトの名前も /etc/devlink.tab となります。sed スクリプトのモード、所有者、およびグループには必要条件はありません (サンプルの prototype ではクエスチョンマークで表されています)。sed スクリプトのファイルタイプは e (編集可能であることを表す) である必要があります。
CLASSES パラメータに sed クラスを含めます。
sed クラスアクションスクリプト (/etc/devlink.tab) を作成します。
postinstall スクリプトを作成します。
postinstall スクリプトでは、add_drv コマンドを実行してデバイスドライバをシステムに追加する必要があります。
preremove スクリプトを作成します。
preremove スクリプトでは、パッケージを削除する前に rem_drv コマンドを実行してデバイスドライバをシステムから削除する必要があります。
copyright ファイルを作成します。
copyright ファイルには、著作権に関するメッセージを記述した ASCII テキストが含まれています。サンプルファイルに示したメッセージは、パッケージのインストール中に画面に表示されます。
PKG=SUNWsst NAME=Simple SCSI Target Driver VERSION=1 CATEGORY=system ARCH=sparc VENDOR=Sun Microsystems BASEDIR=/opt CLASSES=sed |
たとえばこのケーススタディーでは、パッケージオブジェクトについて、次の図に示す階層型レイアウトを使用しています。
パッケージオブジェクトは、上に示した pkg ディレクトリ内での場所と同じ場所にインストールされます。ドライバモジュール (sst および sst.conf) は /usr/kernel/drv にインストールされ、インクルードファイルは /usr/include/sys/scsi/targets にインストールされます。sst、sst.conf、および sst_def.h ファイルは絶対オブジェクトです。テストプログラム sstest.c とそのディレクトリ SUNWsst は再配置可能オブジェクトです。それらのインストール場所は BASEDIR パラメータによって設定されます。
パッケージの残りのコンポーネント (すべての制御ファイル) は、開発マシン上でのパッケージの最上位ディレクトリにインストールされますが、sed クラススクリプトだけは例外です。このクラススクリプトは、それが変更するファイルにならって devlink.tab と呼ばれ、etc にインストールされます。このディレクトリには、実際の devlink.tab ファイルが格納されています。
pkg ディレクトリから pkgproto コマンドを次のように実行します。
find usr SUNWsst -print | pkgproto > prototype |
このコマンドによる出力は、たとえば次のようになります。
d none usr 0775 pms mts d none usr/include 0775 pms mts d none usr/include/sys 0775 pms mts d none usr/include/sys/scsi 0775 pms mts d none usr/include/sys/scsi/targets 0775 pms mts f none usr/include/sys/scsi/targets/sst_def.h 0444 pms mts d none usr/kernel 0775 pms mts d none usr/kernel/drv 0775 pms mts f none usr/kernel/drv/sst 0664 pms mts f none usr/kernel/drv/sst.conf 0444 pms mts d none SUNWsst 0775 pms mts f none SUNWsst/sstest.c 0664 pms mts |
この prototype ファイルはまだ完成していません。このファイルを完成するには、次の修正を加える必要があります。
制御ファイルのエントリを挿入します (ファイルタイプ i)。これは、制御ファイルの書式がほかのパッケージオブジェクトとは異なるためです。
ターゲットシステムにすでに存在しているディレクトリのエントリを削除します。
各エントリのアクセス権と所有者を変更します。
絶対パッケージオブジェクトの前にスラッシュを付加します。
最終的な prototype ファイルを次に示します。
i pkginfo i postinstall i preremove i copyright e sed /etc/devlink.tab ? ? ? f none /usr/include/sys/scsi/targets/sst_def.h 0644 bin bin f none /usr/kernel/drv/sst 0755 root sys f none /usr/kernel/drv/sst.conf 0644 root sys d none SUNWsst 0775 root sys f none SUNWsst/sstest.c 0664 root sys |
sed スクリプトのエントリにあるクエスチョンマークは、インストール先マシンの既存ファイルのアクセス権と所有者を変更してはならないことを示します。
ドライバの例では、sed クラススクリプトはドライバのエントリをファイル /etc/devlink.tab に追加するために使用されています。このファイルは、/dev から /devices へのシンボリックリンクを作成するために、devlinks コマンドによって使用されます。sed スクリプトを次に示します。
# sed class script to modify /etc/devlink.tab !install /name=sst;/d $i\ type=ddi_pseudo;name=sst;minor=character rsst\\A1 !remove /name=sst;/d |
pkgrm コマンドは、このスクリプトの削除に関する部分を実行しません。/etc/devlink.tab ファイルからエントリを削除するには、preremove スクリプトに sed を直接実行するための行を追加する必要があります。
この例では、このスクリプトは add_drv コマンドの実行だけを行います。
# Postinstallation script for SUNWsst # This does not apply to a client. if [$PKG_INSTALL_ROOT = "/" -o -z $PKG_INSTALL_ROOT]; then SAVEBASE=$BASEDIR BASEDIR=””; export BASEDIR /usr/sbin/add_drv sst STATUS=$? BASEDIR=$SAVEBASE; export BASEDIR if [ $STATUS -eq 0 ] then exit 20 else exit 2 fi else echo "This cannot be installed onto a client." exit 2 fi |
add_drv コマンドは BASEDIR パラメータを使用するため、スクリプトはこのコマンドを実行する前に BASEDIR の設定を解除し、実行後に復元する必要があります。
add_drv コマンドの動作の 1 つは、devlinks を実行することです。これは、sed クラススクリプトが /etc/devlink.tab に挿入したエントリを使用して、ドライバの /dev エントリを作成します。
postinstall スクリプトの終了コードは重要です。終了コード 20 は pkgadd コマンドに対して、ユーザーにシステムの再起動 (ドライバのインストール後に必要) を要求するように指示します。終了コード 2 は pkgadd コマンドに対して、インストールが部分的に失敗したことをユーザーに知らせるように指示します。
このドライバの例では、このスクリプトは /dev 内のリンクを削除し、ドライバに対して rem_drv コマンドを実行します。
# Pre removal script for the sst driver echo “Removing /dev entries” /usr/bin/rm -f /dev/rsst* echo “Deinstalling driver from the kernel” SAVEBASE=$BASEDIR BASEDIR=””; export BASEDIR /usr/sbin/rem_drv sst BASEDIR=$SAVEBASE; export BASEDIR exit |
このスクリプトは /dev のエントリを削除します。/devices のエントリは、 rem_drv コマンドによって削除されます。
これは、著作権表示のテキストを格納した単純な ASCII ファイルです。著作権表示は、パッケージのインストール開始時に、ファイルに記載されているとおりに表示されます。
Copyright (c) 1999 Drivers-R-Us, Inc. 10 Device Drive, Thebus, IO 80586 All rights reserved. This product and related documentation is protected by copyright and distributed under licenses restricting its use, copying, distribution and decompilation. No part of this product or related documentation may be reproduced in any form by any means without prior written authorization of Drivers-R-Us and its licensors, if any. |