Autoyast: Retaining/reusing existing partitions

If you plan to do automated installs of openSUSE or SUSE Linux Enterprise Server (SLES), you will sooner or later meet their installation automation solution, Autoyast. Since there is not much info on the Web on Autoyast control files and scripts apart from the official documentation, I thought I could contribute some of my own experiences in a small series of blog posts. To begin with let’s have a look at pre-install scripts.

Pre-install scripts allow you to do things after Yast startup and probing but ahead of the partitioning. One especially useful feature is that you can modify the Autoyast control file “in flight”: as officially documented here, the control file lives at /tmp/profile/autoinst.xml during execution of your pre-install script. If you create a file /tmp/profile/modified.xml, it will be picked up by Yast after pre-install script execution and used instead of the original control file. Thus if you start your pre-install script with a simple

cp /tmp/profile/autoinst.xml /tmp/profile/modified.xml

you can afterwards run commands such as sed and awk to dynamically modify /tmp/profile/modified.xml according to whatever inspections your script does.

When would you want to use this feature? One real world scenario is when you have filesystems that you want to be reused if they exist and created if they don’t. The underlying problem here is that Autoyast does not allow you to specify such a “create only if needed” behaviour directly: the <create> XML tag only knows true or false. In the former scenario the corresponding partition will always be created even if it already exists, causing, of course, data loss. In the latter scenario the partition will never be created even if it does not already exist, meaning that you can’t use the control file against a fresh new disk disk. Sure, you could use two Autoyast control files but who wants that? You could also use Autoyast’s rules and classes feature but it comes with a price of complexity which does not necessarily have to be paid if it is for this problem alone. Pre-install scripts to the rescue!

As described in this mailing list reply by Thomas Fehr, you can simply default the <create> tag to false and then change it from within the pre-install script if required. For an example let’s look at an excerpt from an Autoyast control file (ignore the boldface and italics styling for now):

<partitioning>
  <drive>
    <device>/dev/sda</device>
    <use>free</use>
    <partitions config:type="list">
      <!-- Partition 1 (EFI system partition) automatically created by Yast -->
      <partition>
        <partition_nr config:type="integer">2</partition_nr>
        <create config:type="boolean">false</create>
        <size>15GB</size>
        <format config:type="boolean">true</format>
        <filesystem config:type="symbol">ext4</filesystem>
        <mount>/</mount>
      </partition>
      <!-- Other partitions follow here... -->
    </partitions>
  </drive>
</partitioning>

Given this fragment, you could define a pre-install script such as this one:

<scripts>
  <pre-scripts config:type="list">
    <script>
      <filename>examine_hard_disks.sh</filename>
      <notification>Examining hard disks...</notification>
      <interpreter>shell</interpreter>
      <source>
<![CDATA[
cp /tmp/profile/autoinst.xml /tmp/profile/modified.xml

if parted --script /dev/sda print 2>&1 | grep "Partition Table: unknown" >/dev/null ; then
  sed -i "/<device>\/dev\/sda<\/device>/,/<\/drive>/{/<create.*>/{s,false,true,}}" /tmp/profile/modified.xml
fi
]]>
      </source>
    </script>
  </pre-scripts>
</scripts>

This uses parted to check if /dev/sda already has a partition table. If not, it will use sed to go into the block from <device>/dev/sda</device> to </drive> (shown in italics above) and if within that block it finds a line containing <create (shown in boldface above) replace the string false with true. Note that this will affect all partitions defined for that disk, which makes sense given that there is no partition table. The limitation to that particular drive’s block is to prevent it from touching other disks. Yet you may want to run your control file with true in the beginning just to be sure.

Of course it would be nicer if one could specify this behavior directly inside the Autoyast control file. I have opened Bug #1120982 for such a new feature, however I don’t expect such functionality to appear any time soon.