付録A テンプレート作成の参照

Embedded Ruby (ERB) は、Ruby コードとプレーンテキストを統合するテンプレートをもとに、テキストファイルを生成するためのツールです。Red Hat Satellite は、以下の場合に ERB 構文を使用します。

プロビジョニングテンプレート
詳細は、『プロビジョニングガイド』の「プロビジョニングテンプレートの作成」を参照してください。
リモート実行ジョブのテンプレート
詳細は、9章ホストでのジョブの実行を参照してください。
レポートテンプレート
詳細は、6章レポートテンプレートを使用したホストの監視 を参照してください。
パーティションテーブルのテンプレート
詳細は、『プロビジョニングガイド』の「パーティションテーブルの作成」を参照してください。
スマート変数
詳細は、『Puppet ガイド』の「スマート変数の設定」を参照してください。
スマートクラスパラメーター
Satellite Server に Puppet モジュールを追加する方法の詳細は、『Puppet ガイド』の「Configuring Smart Class Parameters」を参照してください。

このセクションでは、ERB テンプレートで使用可能な Satellite 固有のマクロと変数を使用例と併せて概説します。Red Hat Satellite が提供するデフォルトのテンプレート (ホスト > プロビジョニングテンプレートホスト > ジョブテンプレート監視 > レポートテンプレート ) には、ERB 構文の適切な例も含まれている点にご留意ください。

ホストのプロビジョニング時またはリモートジョブの実行時に、ERB のコードが実行し、変数がホスト固有の値に置き換えられます。このプロセスは、レンダリング と呼ばれています。Satellite Server ではセーフモードのレンダリングオプションがデフォルトで有効になっており、これにより、有害なコードがテンプレートから実行されないようにすることができます。

A.1. ERB テンプレートの作成

以下のタグは最も重要であり、ERB テンプレートで一般的に使用されています。

<% %>

すべての Ruby コードは、ERB テンプレートの <% %> 内に囲まれています。コードはテンプレートのレンダリング時に実行されます。これには Ruby の制御フロー構造と、Satellite 固有のマクロおよび変数を含めることができます。以下に例を示します。

<% if @host.operatingsystem.family == "Redhat" && @host.operatingsystem.major.to_i > 6 %>
systemctl <%= input("action") %> <%= input("service") %>
<% else %>
service <%= input("service") %> <%= input("action") %>
<% end -%>

テンプレートがレンダリングされるときに出力がない点にご留意ください。

<%= %>

これは、<% %> と同じ機能を提供しますが、テンプレートが実行されると、コード出力はテンプレートに挿入されます。これは変数の置き換えに便利です。以下に例を示します。

入力例:

echo <%= @host.name %>

レンダリング例:

host.example.com

入力例:

<% server_name = @host.fqdn %>
<%= server_name %>

レンダリング例:

host.example.com

誤った変数を入力した場合、出力は返されない点にご留意ください。ただし、誤った変数でメソッドを呼び出そうとすると、以下のエラーメッセージが返されます。

入力例:

<%= @example_incorrect_variable.fqdn -%>

レンダリング例:

undefined method `fqdn' for nil:NilClass

<% -%>, <%= -%>

デフォルトでは、行末で閉じられている場合に、改行文字が Ruby ブロックの後に挿入されます。

入力例:

<%= "line1" %>
<%= "line2" %>

レンダリング例:

line1
line2

デフォルトの動作を変更するには、-%> で囲みマークを変更します。

入力例:

<%= "line1" -%>
<%= "line2" %>

レンダリング例:

line1line2

これはレンダリングされるテンプレートの行数を減らすために使用されます (Ruby 構文で許可される場合)。ERB タグの空白は無視されます。

これをレポートテンプレートで使用して、FQDN と IP アドレス間の不要な改行を削除する方法の例を以下に示します。

入力例:

<%= @host.fqdn -%>
<%= @host.ip -%>

レンダリング例:

host.example.com10.10.181.216

<%# %>

テンプレートのレンダリング時に無視されるコメントを囲みます。

入力例:

<%# A comment %>

これは出力を生成しません。

ERB テンプレートのインデント

ERB タグの長さが異なるため、ERB 構文にインデントを入れると見にくい場合があります。ERB 構文は空白を無視します。インデントを処理する方法の 1 つは、新しい行の各行頭に ERB タグを宣言し、ERB タグ内の空白を使用して構文内の関係を説明することです。以下に例を示します。

<%- load_hosts.each do |host| -%>
<%-   if host.build? %>
<%=     host.name %> build is in progress
<%-   end %>
<%- end %>

A.2. ERB テンプレートのトラブルシューティング

Satellite Web UI では、特定ホストについてのテンプレートのレンダリングを検証するための 2 つの方法を提供しています。

  • テンプレートエディターによる直接的な方法 – (ホスト > パーティションテーブルホスト > プロビジョニングテンプレート、または ホスト > ジョブテンプレート 配下の) テンプレートの編集時に、テンプレート タブで プレビュー をクリックしてから、一覧でホストを選択します。次に、選択したホストのパラメーターを使用して、テキストフィールドでテンプレートをレンダリングします。プレビューが失敗した場合は、ここでテンプレートの問題を特定できます。
  • ホストの詳細ページを使用する方法: ホスト > すべてのホスト でホストを選択し、テンプレート タブをクリックして、ホストに関連付けらえたテンプレートを一覧表示します。選択したテンプレートの横にある一覧から 確認 を選択して、そのテンプレートをレンダリングします。

A.3. 一般的な Satellite 固有のマクロ

このセクションでは、ERB テンプレート用の Satellite 固有のマクロを一覧表示します。

以下の表に記載されているマクロは、すべての種類のテンプレートで使用することができます。

表A.1 一般的なマクロ

名前説明

indent(n)

コードブロックを n スペース分インデントします。インデントされていないスニペットテンプレートの使用時に便利です。

foreman_url(kind)

完全な URL を、ホストでレンダリングされた指定タイプのテンプレートに返します。たとえば、「provision」タイプのテンプレートは通常 http://HOST/unattended/provision にあります。

snippet(name)

指定されたスニペットテンプレートをレンダリングします。プロビジョニングテンプレートをネスト化するのに便利です。

snippets(file)

Foreman データベースで、指定したスニペットをレンダリングします。データベースにない場合は unattended/snippets/ ディレクトリーからこれをロードします。

snippet_if_exists(name)

指定されたスニペットをレンダリングし、指定された名前を持つスニペットが見つからない場合は省略します。

A.4. テンプレートマクロ

カスタムテンプレートを作成する場合は、以下のマクロをいくつか使用できます。

テンプレートのタイプに応じて、以下のマクロの一部には異なる要件があります。

レポートテンプレートで利用可能なマクロに関する詳細は、Satellite Web UI で、監視 > レポートテンプレート に移動し、テンプレートの作成 をクリックします。「テンプレートの作成」ウィンドウで、ヘルプ タブをクリックします。

ジョブテンプレートで使用可能なマクロに関する詳細は、Satellite Web UIで、ホスト > ジョブテンプレート に移動し、新しいジョブテンプレート をクリックします。「新しいジョブテンプレート」ウィンドウで、ヘルプ タブをクリックします。

input

input マクロを使用すると、テンプレートで使用できる入力データをカスタマイズできます。ユーザーが使用できる入力名、タイプ、およびオプションを定義できます。レポートテンプレートの場合、ユーザー入力のみを使用できます。新しい入力を定義してテンプレートを保存すると、テンプレート本文の ERB 構文で入力を参照できます。

<%= input('cpus') %>

これは、ユーザー入力 cpus から値をロードします。

load_hosts

load_hosts マクロを使用すると、ホストの完全なリストを生成できます。

<%- load_hosts().each_record do |host| -%>
<%=     host.name %>

load_hosts マクロを each_record マクロと共に使用して、1000 件のレコードを一括でロードし、メモリー消費を減らします。

レポートのホスト一覧をフィルタリングする場合は、オプション search: input(‘Example_Host’) を追加できます。

<% load_hosts(search: input('Example_Host')).each_record do |host| -%>
<%=  host.name %>
<% end -%>

この例では、最初に入力を作成し、次にそれを使用して、load_hosts マクロが取得する検索条件を絞り込みます。

report_row

report_row マクロを使用すると、分析を容易にするためにフォーマットされたレポートを作成できます。report_row マクロは、出力を生成するために report_render マクロを必要とします。

入力例:

<%- load_hosts(search: input('Example_Host')).each_record do |host| -%>
<%-   report_row(
        'Server FQDN': host.name
      ) -%>
<%- end -%>
<%= report_render -%>

レンダリング例:

Server FQDN
host1.example.com
host2.example.com
host3.example.com
host4.example.com
host5.example.com
host6.example.com

別のヘッダーを追加することで、レポートにコラムを追加できます。以下の例では、レポートに IP アドレスを追加します。

入力例:

<%- load_hosts(search: input('host')).each_record do |host| -%>
<%-   report_row(
      'Server FQDN': host.name,
           'IP': host.ip
      ) -%>
<%- end -%>
<%= report_render -%>

レンダリング例:

Server FQDN,IP
host1.example.com,10.8.30.228
host2.example.com,10.8.30.227
host3.example.com,10.8.30.226
host4.example.com,10.8.30.225
host5.example.com,10.8.30.224
host6.example.com,10.8.30.223

report_render

このマクロは、レポートテンプレートでのみ使用できます。

report_render マクロを使用して、レポートの出力を作成します。テンプレートのレンダリングプロセス中に、レポートに使用する形式を選択できます。YAML および CSV 形式がサポートされています。

<%= report_render format: :yaml -%>
render_template()

このマクロは、ジョブテンプレートでのみ使用できます。

このマクロを使用して、特定のテンプレートをレンダリングできます。また、テンプレートに渡す引数を有効化して定義することもできます。

A.5. ホスト固有の変数

以下の変数により、テンプレート内でホストデータを使用できます。ジョブテンプレートは @host 変数のみを受け入れる点にご留意ください。

表A.2 ホスト固有の変数およびマクロ

名前説明

@host.architecture

ホストのアーキテクチャーです。

@host.bond_interfaces

すべてのボンディングインターフェースのアレイを返します。「アレイの解析」 を参照してください。

@host.capabilities

システムプロビジョニングの方法には、ビルド (キックスタートなど) またはイメージのいずれかを使用できます。

@host.certname

ホストの SSL 証明書名です。

@host.diskLayout

ホストのディスクレイアウトです。オペレーティングシステムから継承できます。

@host.domain

ホストのドメインです。

@host.environment

ホストの Puppet 環境です。

@host.facts

Facter からファクトの Ruby ハッシュを返します。たとえば、出力の 'ipaddress' ファクトにアクセスするには、@host.facts['ipaddress'] を指定します。

@host.grub_pass

ホストの GRUB パスワードを返します。

@host.hostgroup

ホストのホストグループです。

host_enc['parameters']

ホストパラメーターの情報が含まれる Ruby ハッシュを返します。たとえば、host_enc['parameters']['lifecycle_environment'] を使用してホストのライフサイクル環境を取得します。

@host.image_build?

ホストがイメージを使用してプロビジョニングされる場合は true を返します。

@host.interfaces

プライマリーインターフェースを含む利用可能なすべてのホストインターフェースのアレイが含まれます。「アレイの解析」 を参照してください。

@host.interfaces_with_identifier('IDs')

指定された ID を持つインターフェースのアレイを返します。複数の ID のアレイを入力として渡すことができます (例: @host.interfaces_with_identifier(['eth0', 'eth1']))。「アレイの解析」 を参照してください。

@host.ip

ホストの IP アドレスです。

@host.location

ホストの位置です。

@host.mac

ホストの MAC アドレスです。

@host.managed_interfaces

管理対象インターフェースのアレイを返します (BMC およびボンディングインターフェースを除く)。「アレイの解析」 を参照してください。

@host.medium

割り当てられたオペレーティングシステムのインストールメディアです。

@host.name

ホストの完全名です。

@host.operatingsystem.family

オペレーティングシステムファミリーです。

@host.operatingsystem.major

割り当てられたオペレーティングシステムのメジャーバージョンの番号です。

@host.operatingsystem.minor

割り当てられたオペレーティングシステムのマイナーバージョンの番号です。

@host.operatingsystem.name

割り当てられたオペレーティングシステムの名前です。

@host.operatingsystem.boot_files_uri(medium_provider)

カーネルおよび initrd への完全パスで、アレイを返します。

@host.os.medium_uri(@host)

プロビジョニングに使用される URI です (インストールメディアに設定されるパス)。

host_param('parameter_name')

指定したホストパラメーターの値を返します。

host_param_false?('parameter_name')

指定したホストパラメーターが false と評価されると、false を返します。

host_param_true?('parameter_name')

指定したホストパラメーターが true と評価されると、true を返します。

@host.primary_interface

ホストのプライマリーインスタンスを返します。

@host.provider

コンピュートリソースプロバイダーです。

@host.provision_interface

ホストのプロビジョニングインターフェースを返します。インターフェースオブジェクトを返します。

@host.ptable

パーティションテーブル名です。

@host.puppet_ca_server

ホストが使用すべき Puppet CA サーバーです。

@host.puppetmaster

ホストが使用すべき Puppet マスターです。

@host.pxe_build?

ホストがネットワークまたは PXE を使用してプロビジョニングされる場合に true を返します。

@host.shortname

ホストの省略名です。

@host.sp_ip

BMC インターフェースの IP アドレスです。

@host.sp_mac

BMC インターフェースの MAC アドレスです。

@host.sp_name

BMC インターフェースの名前です。

@host.sp_subnet

BMC ネットワークのサブネットです。

@host.subnet.dhcp

DHCP プロキシーがこのホストに設定されている場合は true を返します。

@host.subnet.dns_primary

ホストのプライマリー DNS サーバーです。

@host.subnet.dns_secondary

ホストのセカンダリー DNS サーバーです。

@host.subnet.gateway

ホストのゲートウェイです。

@host.subnet.mask

ホストのサブネットマスクです。

@host.url_for_boot(:initrd)

このホストに関連付けられる initrd イメージへの完全パスです。変数を補間しないので推奨されません。

@host.url_for_boot(:kernel)

このホストに関連付けられたカーネルへの完全パスです。変数を補間しないので推奨されません。boot_files_uri が優先されます。

@provisioning_type

プロビジョニングのタイプに応じて「host」または「hostgroup」と等しくなります。

@static

ネットワーク設定が静的な場合、true を返します。

@template_name

レンダリングされるテンプレートの名前です。

grub_pass

md5pass 引数でラップされる GRUB パスワードを返します (例: --md5pass=#{@host.grub_pass})。

ks_console

ポートを使用して組み立てられる文字列、およびカーネル行に追加できるボーレートを返します (例: console=ttyS1,9600)。

root_pass

システムに設定される root パスワードを返します。

一般的な Ruby メソッドのほとんどは、ホスト固有の変数に適用できます。たとえば、ホストの IP アドレスの最後のセグメントを抽出するには、以下を使用できます。

<% @host.ip.split('.').last %>

A.6. キックスタート固有の変数

以下の変数は、キックスタートプロビジョニングテンプレート内で使用されるように設計されています。

表A.3 キックスタート固有の変数

名前説明

@arch

ホストのアーキテクチャー名です。@host.architecture.name と同じです。

@dynamic

使用されているパーティションテーブルが %pre スクリプト (テーブルの最初の行に #Dynamic オプションがある) の場合、true を返します。

@epel

epel-release rpm の正しいバージョンを自動インストールするコマンドです。%post スクリプトで使用されます。

@mediapath

URL コマンドを提供する詳細なキックスタート行です。

@osver

オペレーティングシステムのメジャーバージョンの番号です。@host.operatingsystem.major と同じです。

A.7. 条件付きステートメント

テンプレートでは、存在する値に応じてさまざまなアクションを実行できます。これを実現するには、ERB 構文で条件付きステートメントを使用できます。

以下の例では、ERB 構文は特定のホスト名を検索し、見つかった値に応じて出力を返します。

入力例:

<% load_hosts().each_record do |host| -%>
<% if @host.name == "host1.example.com" -%>
<%      result="positive" -%>
<%  else -%>
<%      result="negative" -%>
<%  end -%>
<%= result -%>

レンダリング例:

host1.example.com
positive

A.8. アレイの解析

テンプレートを作成または変更する際、アレイを返す変数が出てくる場合があります。たとえば、@host.interfaces または @host.bond_interfaces などのネットワークインターフェースに関連するホスト変数は、アレイで分類されるインターフェースデータを返します。特定のインターフェースのパラメーター値を抽出するには、Ruby メソッドを使用してアレイを解析します。

アレイを解析する正しい方法を見つける

以下の手順は、テンプレート内のアレイの解析方法として関連するものを見つけるために使用できる例です。この例では、レポートテンプレートが使用されていますが、この手順は他のテンプレートにも適用できます。

  1. この例では、コンテンツホストの NIC を取得するために @host.interfaces 変数を使用すると、アレイを解析する方法を見つけるために使用できるクラス値が返されます。

    入力例:

    <%= @host.interfaces -%>

    レンダリング例:

    <Nic::Base::ActiveRecord_Associations_CollectionProxy:0x00007f734036fbe0>

  2. 「テンプレートの作成」ウィンドウで、ヘルプ タブをクリックし、ActiveRecord_Associations_CollectionProxy クラスおよび Nic::Base クラスを検索します。
  3. ActiveRecord_Associations_CollectionProxy の場合、許可された方法またはメンバー コラムで、以下のメソッドを表示してアレイを解析できます。

    [] each find_in_batches first map size to_a
  4. Nic::Base の場合、許可された方法またはメンバー コラムで、以下の方法を表示してアレイを解析できます。

    alias? attached_devices attached_devices_identifiers attached_to bond_options children_mac_addresses domain fqdn identifier inheriting_mac ip ip6 link mac managed? mode mtu nic_delay physical? primary provision shortname subnet subnet6 tag virtual? vlanid
  5. インターフェースアレイを繰り返すには、関連する方法を ERB 構文に追加します。

    入力例:

    <% load_hosts().each_record do |host| -%>
    <%    host.interfaces.each do |iface| -%>
      iface.alias?: <%= iface.alias? %>
      iface.attached_to: <%= iface.attached_to %>
      iface.bond_options: <%= iface.bond_options %>
      iface.children_mac_addresses: <%= iface.children_mac_addresses %>
      iface.domain: <%= iface.domain %>
      iface.fqdn: <%= iface.fqdn %>
      iface.identifier: <%= iface.identifier %>
      iface.inheriting_mac: <%= iface.inheriting_mac %>
      iface.ip: <%= iface.ip %>
      iface.ip6: <%= iface.ip6 %>
      iface.link: <%= iface.link %>
      iface.mac: <%= iface.mac %>
      iface.managed?: <%= iface.managed? %>
      iface.mode: <%= iface.mode %>
      iface.mtu: <%= iface.mtu %>
      iface.physical?: <%= iface.physical? %>
      iface.primary: <%= iface.primary %>
      iface.provision: <%= iface.provision %>
      iface.shortname: <%= iface.shortname %>
      iface.subnet: <%= iface.subnet %>
      iface.subnet6: <%= iface.subnet6 %>
      iface.tag: <%= iface.tag %>
      iface.virtual?: <%= iface.virtual? %>
      iface.vlanid: <%= iface.vlanid %>
    <%- end -%>

    レンダリング例:

    host1.example.com
      iface.alias?: false
      iface.attached_to:
      iface.bond_options:
      iface.children_mac_addresses: []
      iface.domain:
      iface.fqdn: host1.example.com
      iface.identifier: ens192
      iface.inheriting_mac: 00:50:56:8d:4c:cf
      iface.ip: 10.10.181.13
      iface.ip6:
      iface.link: true
      iface.mac: 00:50:56:8d:4c:cf
      iface.managed?: true
      iface.mode: balance-rr
      iface.mtu:
      iface.physical?: true
      iface.primary: true
      iface.provision: true
      iface.shortname: host1.example.com
      iface.subnet:
      iface.subnet6:
      iface.tag:
      iface.virtual?: false
      iface.vlanid:

A.9. テンプレートスニペットの例

ホストで Puppet および Puppetlabs が有効化されているかどうかの確認

以下の例では、ホストで Puppet および Puppetlabs リポジトリーが有効化されているかどうかを確認します。

<%
pm_set = @host.puppetmaster.empty? ? false : true
puppet_enabled = pm_set || host_param_true?('force-puppet')
puppetlabs_enabled = host_param_true?('enable-puppetlabs-repo')
%>

ホストのオペレーティングシステムのメジャーバージョンとマイナーバージョンの取得

以下の例では、パッケージ関連の決定に使用できるホストのオペレーティングシステムのマイナーバージョンおよびメジャーバージョンを取得する方法を示します。

<%
os_major = @host.operatingsystem.major.to_i
os_minor = @host.operatingsystem.minor.to_i
%>

<% if ((os_minor < 2) && (os_major < 14)) -%>
...
<% end -%>

テンプレートへのスニペットのインポート

以下の例は、subscription_manager_registration スニペットをテンプレートにインポートし、4 スペース分インデントします。

<%= indent 4 do
snippet 'subscription_manager_registration'
end %>

キックスタートスニペットの条件付きインポート

以下の例では、ホストのサブネットで DHCP ブートモードが有効な場合に kickstart_networking_setup スニペットをインポートします。

<% subnet = @host.subnet %>
<% if subnet.respond_to?(:dhcp_boot_mode?) -%>
<%= snippet 'kickstart_networking_setup' %>
<% end -%>

ホストのカスタムファクトからの値の解析

host.facts 変数を使用して、ホストファクトとカスタムファクトの値を解析できます。

この例では、luks_stat は、ホストファクトである dmi::system::serial_number と同じ方法で解析できるカスタムファクトです。

'Serial': host.facts['dmi::system::serial_number'],
'Encrypted': host.facts['luks_stat'],

この例では、適用可能なエラータレポートテンプレートをカスタマイズして、各ホストのカーネルバージョンに関するカスタム情報を解析できます。

<%-     report_row(
          'Host': host.name,
          'Operating System': host.operatingsystem,
          'Kernel': host.facts['uname::release'],
          'Environment': host.lifecycle_environment,
          'Erratum': erratum.errata_id,
          'Type': erratum.errata_type,
          'Published': erratum.issued,
          'Applicable since': erratum.created_at,
          'Severity': erratum.severity,
          'Packages': erratum.package_names,
          'CVEs': erratum.cves,
          'Reboot suggested': erratum.reboot_suggested,
        ) -%>