Build system images with Kiwi

Conjurer

Editing Examples

Examples of image descriptions (i.e., XML profiles with scripts and a root directory) are provided by the Kiwi maintainers in a repository on GitHub [2]. Local cloning of the repository, including the examples in this article, offers a quick-start option. The examples can then be tried out directly.

From the examples provided by the maintainers, you can quickly create your own image with individual customizations for a virtual machine. To do this, clone the repository with git, change to the appropriate directory, and view the content of the example directory (Listing 2).

Listing 2

Cloning a Repository

$ git clone https://github.com/OSInside/Kiwi-descriptions
$ cd Kiwi-descriptions/suse/x86_64/suse-leap-15.2
$ ls -1
config.sh
config.xml
root
root/etc
root/etc/udev
root/etc/udev/rules.d
root/etc/udev/rules.d/70-persistent-net.rules
root/etc/motd
root/etc/sysconfig
root/etc/sysconfig/network
root/etc/sysconfig/network/ifcfg-lan0

The config.xml file controls the build process by defining what should be installed and configured. After the build process, Kiwi copies the content of the root directory to the root filesystem. Finally, the config.sh script runs. In the example of Listing 3, the script enables the SSH daemon and chronyd and sets the systemd target to "graphical" (equivalent to the earlier runlevel 5).

Listing 3

config.sh

test -f /.kconfig && . /.kconfig
test -f /.profile && . /.profile
echo "Configure image: [$Kiwi_iname]..."
suseSetupProduct
suseInsertService sshd
suseInsertService chronyd
baseSetRunlevel 5

Often, time servers are useful (Figure 2) – either those belonging to the NTP pool project or your own. A few adjustments are all it takes. The chrony and chrony-pool-empty packages must be installed. Without specifying the latter, the system installs a package preconfigured for openSUSE time servers. The time servers to be used are listed in the root/etc/chrony.d/server.conf file:

Figure 2: Configuring the time zone to be used with YaST2 firstboot.
server 0.de.pool.ntp.org
server 1.de.pool.ntp.org
server 2.de.pool.ntp.org
server 3.de.pool.ntp.org

The entry suseInsertService chronyd in config.sh takes care of starting the chronyd service. Instead, the script can contain a systemctl call or any other commands. For some standard processes, Kiwi provides prepared functions for further simplification, as in the suseInsertService example. A list with explanations [3] of these functions can be found on the project's website.

An entry in the root/etc/motd file, such as:

Welcome to a modified openSUSE Leap 15.2 appliance.

gives you a "message of the day."

Final Configuration

If you want the user to set up the finished appliance on the first boot, openSUSE provides the yast2-firstboot package for this purpose [4]. If it is installed, the system asks the user for the individual configuration at the time of first boot, which includes the username and password, hostname, network configuration, time zone, and more.

The modules to be called are in the root/etc/YaST2/firstboot.xml file on the later filesystem. Listing 4 shows a sample configuration that starts the modules for the system language, keyboard layout, time zone, and a user to be created. The root password is also prompted for and set here, creating a customized image from a role model that can be installed and used immediately.

Listing 4

Querying System Configuration

<?xml version="1.0"?>
<productDefines  xmlns="http://www.suse.com/1.0/yast2ns"
  xmlns:config="http://www.suse.com/1.0/configns">
  <textdomain>firstboot</textdomain>
  <globals>
  <enable_autologin config:type="boolean">false</enable_autologin>
  </globals>
  <workflows  config:type="list">
    <workflow>
      <stage>firstboot</stage>
      <label>Configuration</label>
      <mode>installation</mode>
      <modules  config:type="list">
        <module>
          <label>Language and Keyboard</label>
          <enabled config:type="boolean">true</enabled>
          <name>firstboot_language_keyboard</name>
        </module>
        <module>
          <label>Time and Date</label>
          <enabled config:type="boolean">true</enabled>
          <name>firstboot_timezone</name>
        </module>
        <module>
          <label>Users</label>
          <enabled config:type="boolean">true</enabled>
          <name>firstboot_user</name>
        </module>
        <module>
          <label>Root Password</label>
          <enabled config:type="boolean">true</enabled>
          <name>firstboot_root</name>
        </module>
      </modules>
    </workflow>
  </workflows>
</productDefines>

The Author

Christian Schneemann works at B1 Systems GmbH (Germany) as a Linux consultant and developer with a focus on system management and deployment. He participates in the development of custom Linux appliances and manages them on behalf of customers. Sebastian Meyer has been working for B1 Systems GmbH as a Linux consultant and trainer since 2013. His focus is on system and software management with a wide variety of configuration management and deployment tools.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs



Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.

Learn More”>
	</a>

<hr>		    
			</div>
		    		</div>

		<div class=