7 ERB 模板 #
ERB 模板用于在 AutoYaST 配置文件内嵌入 Ruby 代码,以在安装期间修改配置文件。利用此方法,您可以通过设置值、添加或跳过某些部分等方式,来检查系统并调整配置文件。
  要激活 ERB 处理,配置文件的扩展名必须为 .erb(例如 autoyast.xml.erb)。之后,它将无法合并规则/类和 ERB 模板。
 
7.1 什么是 ERB? #
ERB 即嵌入式 Ruby (Embedded Ruby)。ERB 使用 Ruby 编程语言的功能来生成不同种类的内容。利用 ERB,您可以在配置文件中包含一些 Ruby 代码,以在运行时根据安装系统调整配置文件。
   使用 ERB 时,需要将 Ruby 代码包含在 <% 和 %> 符号之间。使用等号 = 可在最终的配置文件中包含命令输出。
  
<bootloader>
  <% require "open-uri" %>
  <%= URI.open("http://192.168.1.1/profiles/bootloader-common.xml").read %>
</bootloader> <!-- this line gets replaced with the content of bootloader-common.xml -->
   可以利用 Ruby 便利性来运行任意命令。如果想获得命令的输出,请将其包含在两个反引号之中。如果想知道命令成功与否,请使用 system 函数运行该命令。
  
<% files = `ls` %> <!-- files contains the output of the command (for instance "file1\nfile2\nfile3") -->
<% success = system("dmidecode | grep some-model") %> <!-- success contains true or false -->此外,您还可使用更高级的 Ruby 代码结构(例如条件和循环)。
<% ip_forward = File.read("/proc/sys/net/ipv4/ip_forward").strip %>
<% if ip_forward == "1" %>
  <!-- something -->
<% end %>
<% files = `ls /tmp/config/*.xml` %>
<% files.split.each do |file| %>
  <%= file.read %>
<% end %>
   AutoYaST 提供了一些帮助程序函数,用于从底层系统中检索信息,例如 disks 或 network_cards。您可以在第 7.2 节 “模板帮助程序”中查看帮助程序及值列表。
  
7.2 模板帮助程序 #
模板帮助程序是 Ruby 方法的集合,可用于配置文件中以检索安装系统的相关信息。
7.2.1 boot_efi? #
boot_efi? 是布尔帮助程序,将返回系统是否使用 EFI 引导的信息。在下面的示例中,配置文件会根据当前引导模式配置引导加载程序。
   
<% if env.boot_efi? %> <loader_type>grub2-efi</loader_type> <% else %> <loader_type>grub2</loader_type> <% end %>
7.2.2 disks #
disks 帮助程序可返回检测到的磁盘列表。列表的每个元素包含一些基本信息,例如设备名称或大小。
   
| 键 | 类型 | 值 | 
|---|---|---|
| 
 | 字符串 | 
         设备内核名称(例如  | 
| 
 | 字符串 | 磁盘型号 | 
| 
 | 字符串 | 序列号 | 
| 
 | 整数 | 磁盘大小(磁盘扇区数) | 
| 
 | 字符串数组 | 磁盘 udev 名称列表。您可以使用其中的任何名称来表示设备。 | 
| 
 | 字符串 | 磁盘供应商名称 | 
    以下示例中的配置文件会在最大的磁盘上安装系统。它会按大小对现有磁盘列表排序,然后使用最后一个磁盘。之后,它会使用 :device 键作为 device 元素的值。
   
<partitioning t="list">
  <drive>
    <% disk = disks.sort_by { |d| d[:size] }.last %> <!-- find the largest disk -->
    <device><%= disk[:device] %></device> <!-- print the disk device name -->
    <initialize t="boolean">true</initialize>
    <use>all</use>
  </drive>
</partitioning>7.2.3 network_cards #
network_cards 帮助程序可返回网卡列表,包括网卡名称,状态信息(例如,它们是否已连接)。
   
| 键 | 类型 | 值 | 
|---|---|---|
| 
 | 字符串 | 
         设备名称(例如  | 
| 
 | 字符串 | MAC 地址 | 
| 
 | 布尔 | 设备是否处于活动状态 | 
| 
 | 布尔 | 设备是否已连接 | 
| 
 | 字符串 | 磁盘供应商名称 | 
下面的示例会找到最先连接网络的网卡,并将其配置为使用 DHCP。
<interfaces t="list">
  <% with_link = network_cards.sort_by { |n| n[:name] }.find { |n| n[:link] } %>
  <% if with_link %>
    <interface>
      <device><%= with_link[:device] %></device>
      <startmode>auto</startmode>
      <bootproto>dhcp</bootproto>
      </interface>
  <% end %>
</interfaces>7.2.4 os_release #
os_release 帮助程序返回操作系统信息,这些信息包含在 /etc/os-release 文件中。
   
| 键 | 类型 | 值 | 
|---|---|---|
| 
 | 字符串 | 
         发行套件 ID(例如  | 
| 
 | 字符串 | 
         发行套件名称(例如  | 
| 
 | 字符串 | 
         发行套件版本(例如  | 
您可以使用这些信息决定要安装的产品,对所有发行套件(SLE 或 openSUSE 发行套件)使用几乎相同的配置文件。
<products t="list"> <% if os_release[:id] == 'sle' %> <product>SLES</product> <% else %> <product>openSUSE</product> <% end %> </products>
7.2.5 hardware #
hardware 帮助程序提供其他硬件信息。它会返回 hwinfo 命令返回的所有信息。当通过所述帮助程序获取的信息不足时,您可以使用此帮助程序作为后备手段。下一个示例中使用 hardware 帮助程序来过滤 USB 设备。请查看 第 7.3 节 “运行 ERB 帮助程序” 了解如何检查 hardware 帮助程序提供的所有信息。
   
<% usb_disks = hardware["disk"].select { |d| d["driver"] != "usb-storage" } %>7.3 运行 ERB 帮助程序 #
   您可以使用 Ruby 控制台运行 AutoYaST ERB 帮助程序,并了解它们可提供哪些功能。可以通过 Y2Autoinstallation::Y2ERB::TemplateEnvironment 类的实例访问所有 ERB 帮助程序。以 root 身份运行 irb -ryast -rautoinstall/y2erb 启动 Ruby 交互式解释器。
  
irb > env = Y2Autoinstallation::Y2ERB::TemplateEnvironment.new  # the env variable gives access to the helpers
irb > env.disks
=>
[{:vendor=>"WDC", :device=>"sda", ...},
 {:vendor=>"TOSHIBA", :device=>"sdb", ...},
...]
irb > env.hardware.keys
=>
["architecture",
 "bios",
 "bios_video",
 ...]
irb > env.hardware["architecture"]
=>
"x86_64"7.4 呈现 ERB 配置文件 #
   AutoYaST 命令行提供了 check-profile 命令,可用于基于 ERB 文件生成配置文件。此命令会要求 AutoYaST 分析、运行 ERB 代码,并生成最终的配置文件。您可以检查呈现的配置文件,确定所有功能均按预期工作。请查看命令帮助了解该命令支持的所有选项:autoyast check-profile --help。在下面的示例中,check-profile 要求 AutoYaST 下载并分析配置文件,解释 ERB 并运行前脚本。结果将转储到 result.xml 文件中。
  
>sudoyast2 autoyast check-profile filename=http://192.168.1.100/autoinst.erb output=result.xml run-scripts=true run-erb=true
check-profile 权限
    大多数情况下,check-profile 都需要 root 权限,因此在以 root 身份运行安装前脚本和 ERB 配置文件时请务必保持谨慎。请仅使用您信任的配置文件。
   
7.5 调试 ERB 配置文件 #
   在有些情况下,您需要停止 ERB 评估并检查发生了什么情况,为此 YaST 提供了与 byebug 调试器的集成。安装 rubygem(byebug) 软件包并将 Y2DEBUGGER 环境变量设为 1。
  
>sudozypper --non-interactive in "rubygem(byebug)">sudoY2DEBUGGER=1 yast2 autoyast check-profile ...
   在想要停止的位置添加断点就像添加 <% byebug %> 一样容易。有关 byebug 的详细信息,请参见 https://github.com/deivid-rodriguez/byebug。
  
<% byebug %>
<% if system("dmidecode | grep some-model") %>
  <!-- do something -->
%<% end %>7.6 ERB 与规则和类的对比 #
   尽管 ERB 和规则/类都能实现动态生成配置文件的功能,但一般而言,ERB 配置文件更容易阅读和理解。一个重要的不同之处是规则和类可以合并配置文件,而 ERB 则不能。请参见第 6 章 “规则和类”了解有关合并配置文件的更多信息。另一方面,ERB 具有高级别语言 Ruby 的所有优势。我们来看一个使用了两种方式的示例。在下面的示例中,我们要将 /home 目录放在 /dev/sdb 中(如果该目录存在)。
  
<rule>
  <custom1>
    <script>
if blkid | grep /dev/sdb > /dev/null; then
echo -n "yes"
else
echo -n "no"
fi;
    </script>
    <match>yes</match>
    <match_type>exact</match_type>
  </custom1>
  <result>
    <profile>classes/sdb_home.xml</profile>
    <dont_merge config:type="list">
      <element>partition</element>
    </dont_merge>
  </result>
</rule><% home_in_sdb = disks.map { |d| d[:device] }.include?("sdb") %>
<partitioning config:type="list">
  <drive>
    ...
  </drive>
  <% if home_in_sdb %>
  <drive>
    <device>/dev/sdb</device>
    <disklabel>none</disklabel>
    <partitions t="list">
      <partition>
        <format t="boolean">true</format>
        <filesystem t="symbol">xfs</filesystem>
        <mount>/home</mount>
      </partition>
    </partitions>
  </drive>
  <% end %>
</partitioning>