5.6. Anaconda アドオンの作成
以下のセクションでは、Hello World という名前のサンプルアドオンを作成およびテストするプロセスについて説明します。このサンプルアドオンは、全インターフェイス (Kickstart、GUI および TUI) をサポートします。このサンプルアドオンのソースは rhinstaller/hello-world-anaconda-addon リポジトリーから取得できます。このリポジトリーをクローンするか、ウェブインターフェイスでソースを開くことが推奨されます。
もう 1 つ確認するリポジトリーは、rhinstaller/anaconda です。ここにはインストーラーのソースコードがあり、本セクションでこのコードの一部が参照されます。
アドオン自体の開発を開始する前に、次の説明に従ってディレクトリー構造を作成することから始めます。「Anaconda アドオンの構造」 .次に、「キックスタートのサポート」、キックスタートのサポートはすべてのアドオンで必須です。その後、オプションで続行できます「グラフィカルユーザーインターフェイス」と「テキスト形式のユーザーインターフェイス」必要に応じて。
5.6.1. キックスタートのサポート
Kickstart サポートはアドオンで最初に開発すべき点です。グラフィカルおよびテキストベースのインターフェイスのサポートなど他のパッケージはこれに依存します。まず、これまでに作成した
com_example_hello_world/ks/
ディレクトリーに移動し、__init__.py
ファイルがあることを確認して、さらに hello_world.py
という名前の Python スクリプトを追加します。
ビルトインの Kickstart コマンドとは異なり、アドオンは独自の セクション で使用されます。Kickstart ファイル内でのアドオンの使用はそれぞれ %addon ステートメントで開始され、%end で終了します。%addon 行にはアドオンの名前 (%addon com_example_hello_world など) と、オプションで引数一覧も含めます (アドオンがこれらに対応している場合)。
Kickstart ファイルでのアドオンの使用例は以下のようになります。
例3 Kickstart ファイルでのアドオンの使用
%addon ADDON_NAME [arguments] first line second line ... %end
アドオンのキックスタートサポートのキークラスは
AddonData
と呼ばれます。このクラスは pyanaconda.addons で定義され、キックスタートファイルからのデータを解析および保存するためのオブジェクトを表します。
引数は、
AddonData
クラスから継承されたアドオンクラスのインスタンスに、リストとして渡されます。最初の行と最後の行の間にあるものはすべて、一度に一行ずつアドオンのクラスに渡されます。Hello World のアドオンサンプルをシンプルにするために、このブロック内のすべての行を単一行にまとめ、元の行を空白で区切ります。
サンプルのアドオンでは、%addon 行からの引数リストの処理のメソッドとセクション内の行を処理するメソッドのあるクラスを
AddonData
から継承する必要があります。pyanaconda/addons.py
モジュールにはこれに使用可能な以下の 2 つのメソッドが含まれています。
handle_header
: %addon 行のリスト (およびエラー報告用の行番号) を取ります。handle_line
: %addon と %end のステートメント間のコンテンツの単一行を取ります。
以下では、上記のメソッドを使用する Hello World アドオンの例を表示します。
例4 handle_header と handle_line の使用
from pyanaconda.addons import AddonData from pykickstart.options import KSOptionParser # export HelloWorldData class to prevent Anaconda's collect method from taking # AddonData class instead of the HelloWorldData class # :see: pyanaconda.kickstart.AnacondaKSHandler.__init__ __all__ = ["HelloWorldData"] HELLO_FILE_PATH = "/root/hello_world_addon_output.txt" class HelloWorldData(AddonData): """ Class parsing and storing data for the Hello world addon. :see: pyanaconda.addons.AddonData """ def __init__(self, name): """ :param name: name of the addon :type name: str """ AddonData.__init__(self, name) self.text = "" self.reverse = False def handle_header(self, lineno, args): """ The handle_header method is called to parse additional arguments in the %addon section line. :param lineno: the current linenumber in the kickstart file :type lineno: int :param args: any additional arguments after %addon <name> :type args: list """ op = KSOptionParser() op.add_option("--reverse", action="store_true", default=False, dest="reverse", help="Reverse the display of the addon text") (opts, extra) = op.parse_args(args=args, lineno=lineno) # Reject any additoinal arguments. Since AddonData.handle_header # rejects any arguments, we can use it to create an error message # and raise an exception. if extra: AddonData.handle_header(self, lineno, extra) # Store the result of the option parsing self.reverse = opts.reverse def handle_line(self, line): """ The handle_line method that is called with every line from this addon's %addon section of the kickstart file. :param line: a single line from the %addon section :type line: str """ # simple example, we just append lines to the text attribute if self.text is "": self.text = line.strip() else: self.text += " " + line.strip()
この例では、必要なメソッドのインポートと
__all__
変数の定義から始めます。これは、Anaconda の collect メソッドがアドオン固有の HelloWorldData
ではなく AddonData
クラスを取得しないようにするのに必要な変数を定義します。
この例は、親の
__init__
を呼び出して、self.text
と self.reverse
属性を False
に初期化する __init__
メソッドで、AddonData
から継承したクラス HelloWorldData
の定義を示しています。
self.reverse
属性が handle_header
メソッドに反映され、self.text
が handle_line
に反映されます。handle_header
メソッドは pykickstart
が提供する KSOptionParser
のインスタンスを使用して、%addon 行で使用される追加オプションを解析し、handle_line
は各行の最初と終了時に空白のコンテンツ行を取り除き、self.text
に追加します。
上記のコードは、 Kickstart ファイルからデータを読み取るという、インストールプロセスにおけるデータライフサイクルの第 1 フェーズをカバーしています。次のステップは、そのデータを使用してインストールプロセスを進めることです。この場合、事前定義された方法が 2 つあります。
setup
: インストール処理の開始前に呼び出され、インストールランタイム環境の変更に使用されます。execute
: 処理の最後に呼び出され、ターゲットシステムの変更に使用されます。
これら 2 つのメソッドを使用するには、新たなインポートと定数をモジュールに追加する必要があります。例を示します。
例5 setup および execute メソッドのインポート
import os.path from pyanaconda.addons import AddonData from pyanaconda.constants import ROOT_PATH HELLO_FILE_PATH = "/root/hello_world_addon_output.txt"
setup
および execute
メソッドを含む Hello World アドオンの更新例を以下に示します。
例6 setup および execute メソッドの使用
def setup(self, storage, ksdata, instclass, payload): """ The setup method that should make changes to the runtime environment according to the data stored in this object. :param storage: object storing storage-related information (disks, partitioning, bootloader, etc.) :type storage: blivet.Blivet instance :param ksdata: data parsed from the kickstart file and set in the installation process :type ksdata: pykickstart.base.BaseHandler instance :param instclass: distribution-specific information :type instclass: pyanaconda.installclass.BaseInstallClass :param payload: object managing packages and environment groups for the installation :type payload: any class inherited from the pyanaconda.packaging.Payload class """ # no actions needed in this addon pass def execute(self, storage, ksdata, instclass, users, payload): """ The execute method that should make changes to the installed system. It is called only once in the post-install setup phase. :see: setup :param users: information about created users :type users: pyanaconda.users.Users instance """ hello_file_path = os.path.normpath(ROOT_PATH + HELLO_FILE_PATH) with open(hello_file_path, "w") as fobj: fobj.write("%s\n" % self.text)
上記の例では、
setup
メソッドは何もせず、Hello World アドオンはインストールランタイム環境に変化を加えません。execute
メソッドは、保存したテキストを、ターゲットシステムのルート (/
) ディレクトリーで作成したファイルに書き込みます。
上記の例で最も重要な情報は、それら 2 つのメソッドに渡される引数の量と意味です。これらは、例の中の docstring に記載されています。
データライフサイクルの最終フェーズ、およびキックスタートサポートを提供するモジュールで必要なコードの最後の部分は、インストール時に設定された値を含む新しいキックスタートファイルを、説明したようにインストールプロセスの最後に生成します。の「Anaconda のアーキテクチャー」.これは、インストールデータを格納するツリーのような構造構造で
__str__
メソッドを呼び出すことで実行されます。つまり、AddonData
から継承されたクラスは、有効なキックスタート構文で保存されたデータを返す独自の __str__
メソッドを定義する必要があります。この返されるデータは、pykickstart
を使用して再度解析する必要があります。
Hello World の例では、
__str__
メソッドを以下の例のようになります。
例7 __str__ メソッドの定義
def __str__(self): """ What should end up in the resulting kickstart file, i.e. the %addon section containing string representation of the stored data. """ addon_str = "%%addon %s" % self.name if self.reverse: addon_str += "--reverse" addon_str += "\n%s\n%%end" % self.text return addon_str
キックスタートサポートモジュールに必要なメソッドすべて (
handle_header
、handle_line
、setup
、execute
、および __str__
) が含まれると、有効な Anaconda アドオンになります。次のセクションに進み、グラフィカルおよびテキストベースのユーザーインターフェイスのサポートを追加するか、次のセクションに進むことができます。「Anaconda アドオンのデプロイおよびテスト」アドオンをテストします。