Novell Home

YaST2 on SUSE Linux Enterprise Server 9: Getting Started

Novell Cool Solutions: Feature
By Arun Singh, Stefan Hundhammer

Digg This - Slashdot This

Posted: 24 Sep 2004
 

Arun Singh
Senior Software Engineer
Novell Developer Services

Stefan Hundhammer
YaST2 Development
SUSE Linux AG

Introduction

This article will help you to understand the internal working of YaST, from user, administrator and developer viewpoints. It provides steps to install the YaST SDK.

YaST makes the difference

If you have installed SUSE Linux on Server or Desktop, you have seen YaST in action. Basically YaST provides Installation, Configuration and Administration. ?YaST? (which stands for Yet another Setup Tool) guides you through the installation procedure and later during the system configuration. Once the system is configured and running, YOU (YasT Online Update) offers a unique system maintenance service. YaST is a key difference between SUSE Linux and other Linux offerings. YaST manages all of the system configuration data behind the scenes and yet allows the user the freedom of manual configuration and editing of the system data if they so desire.


YaST Control Center

YaST2 Architecture

To achieve the modularity of YaST, it's split up into a number of components for each individual task. There is the core engine and scripts written in YCP, Perl or (in future releases) other scripting languages.


Click image for larger view.

Modules and YCP Language

YaST consist of many components and layers. YaST-modules are important components and are written in YaST Control Language (YCP). When YaST is running, the YCP-modules are interpreted by the low-level YaST-Components and YCP code makes use of the infrastructure. YaST provides the option to developers to write their own modules to manage their components. YaST modules are the layers of YaST the user comes in contact with.

WFM (Workflow Manager)

The Workflow Manager (WFM) is the central component that acts as a dispatcher and communications hub for all other components: When a (YCP, Perl, etc.) script calls a function, based on the respective namespace identifier the WFM determines what component handles that function call, makes that component perform that call, and returns the result to the caller.

For example, calls like UI::OpenDialog() go to the UI (the user interface), SCR::Read () to the SCR (the system configuration repository).

The WFM includes an YCP interpreter and bindings for other programming languages like (currently) Perl. All communication between the different languages is done via a predefined set of YCP data types - simple data types like string, integer, boolean, etc., but also compound data types like maps (key / value pairs, also known as "hashes" in other programming languages) or lists (like arrays or vectors in other programming languages). For complex data structures, maps, lists and simple data types can be nested to any degree.

It is not necessary for the caller to know the programming language in which a function was written in the WFM, to handle that kind of dispatching. The caller only needs to know the function name, its namespace and (of course) the required parameters.

For example, for a call User::Add () the WFM would search a module called "User" - User.ycp or User.pm (or in future versions maybe User.py or whatever) and call a function "Add ()" in that module with the parameters specified by the caller, doing necessary data conversions in the process.

The WFM also has a set of built-in functions to access data on the installation source - for example, configuration files for the installation process.

SCR (System Configuration Repository)

Even though in most scenarios there is only one single machine, it is important to distinguish between the installation source machine and the installation target machine:

  • The installation source machine is the machine that holds the installation media - usually CDs or DVDs - and a mini-Linux called "inst-sys" that is copied from one of those installation media to that machine's RAM disk to have a basic operating system to work with on a "bare metal" machine (a machine that doesn't have an operating system installed yet). Most of that inst-sys is read-only; there is only limited disk space for temporary files, and since everything runs from a RAM disk, the writable part of it is very volatile.


  • The installation target, on the other hand, is the machine that is to be installed or administered. That may be the same machine as the installation source machine (in fact, this is very common for PC installation or administration tasks), but it might as well be two distinct machines - a virtual machine on a mainframe computer or a remote rack-mounted machine without any display adapter or CD/DVD drives.

All communication with the installation target is handled via the System Configuration Repository (SCR) to guarantee the network abstraction design goal. This is much easier said than done, however. YaST2 module developers always have to keep in mind that it is strictly forbidden to access system files (or any other system resources, for that matter) directly, even if there may be very convenient CPAN Perl modules to do that. Rather, SCR is to be used instead - always. Otherwise, everything might run fine if installation source and target are the same machine, but break horribly if they are not.

SCR in itself is also modularized. All calls are handled by "agents," each of which knows how to handle a particular configuration "path" like "/etc/fstab" or "/etc/passwd". That may be a simple file, but it may also be a directory hierarchy like "probe," an agent which handles all kinds of hardware probing, from mouse and display adapters to storage device controllers (like SCSI or IDE controllers), disks attached to each individual controller or partitions on those disks. Paths are denoted like ".etc.fstab" for SCR. YCP even has a special data type "path" for just this case (a special kind of string with some special operations).

SCR agents handle no more than three calls:
      SCR::Read()
      SCR::Write()
      SCR::Execute()

The first argument is always the path to handle, but there may be any number of additional parameters, depending on the agent.

While Read() and Write() are obvious, Execute() may not be. This is intended for some kinds of agents that actually run a program on the installation target. In particular, the ".target.bash" agent does that - it runs a "bash" shell on the target machine and accepts a shell command as an argument. This is the tool of choice for tasks such as starting or stopping system services on the target machine - and again, the distinction between installation source and installation target machine becomes very important. You want to start or stop the service on the (possibly remote) target machine, not on the machine that happens to hold the installation media.

SCR agents can easily added when needed. There are frameworks available to write SCR agents in C++, in Perl, or as Bash shell scripts as well as several ready-made parsers for different file formats like the ".ini" file parser that can handle files with "key = value" pairs or the "anyagent" that generalizes that concept even more using regular expressions. Those parsers return YCP lists and maps ready for further processing.

Typically, a YaST2 module for a specific installation or administration task includes a set of YCP or Perl scripts as well as some SCR agents to handle its particular configuration files.

UI (User Interface)

Given the wide variety of machines that can possibly be handled with YaST2, it is important to keep the user interface (UI) abstraction in mind - very much like the SCR, the UI does not necessarily run on the installation target machine. It doesn't even need to run on the same machine as the WFM.

The UI provides dialogs with "widgets" - user interface elements such as input fields, selection lists or buttons. It is transparent to the calling application if those widgets are part of a graphical toolkit such as Qt, or text based (using the NCurses library), or something else entirely. An input field, for example, only guarantees that the user can enter and edit some value with it. A button only provides a means to notify the application when the user activated it - by mouse click (if the UI supports using pointing devices such as a mouse), by key press, or however else.

The UI has a small number of built-in functions - for example:

  • UI::OpenDialog() accepts a widget hierarchy as an argument and opens a dialog with those widgets.


  • UI::CloseDialog() closes a dialog.


  • UI::QueryWidget() returns a widget's property such as the current value of an input field or selection box.


  • UI::ChangeWidget() changes a widget's property.


  • UI::UserInput() waits until the user has taken some action such as activate a button - after which the application can call UI::QueryWidget() for each widget in the dialog to get the current values the user entered. The application does not have to handle every key press in each input field directly - the widgets are self-sufficient to a large degree.

There is virtually no low-level control for the widgets - nor is it necessary or even desired to have that. You don't specify a button's width or height - you specify its label to be, for example, "Continue," and it will adapt its dimensions accordingly. If desired, more specific layout constraints can be specified. For example, buttons can be arranged in a row with equal width each. The UI will resize them as needed, giving them additional margins if necessary.

The existing UIs provide another layer of network abstraction: The graphical UI uses the Qt toolkit which is based on the X Window System's Xlib which in turn uses the X protocol running on top of TCP/IP. X Terminals can be used as well as a Linux console (that may be the installation source machine or the installation target machine or another machine connected via the network) running the X Window System or even X servers running on top of other operating systems.

The NCurses (text based) UI requires no more than a shell session - on a text terminal (serial console or other), on a Linux console, in an XTerm session, via ssh or whatever.

Setting the YaST Development Environment

YaST, by design, is modular and you can create YaST modules for your application using YaST API's. YaST modules are written in the YaST Control Language (YCP). To create a YaST module you need the yast2-devel package. Other helpful packages are yast2-core-devel and yast2-devtools. All of these packages are available in the SUSE Linux SDK 9 (http://developer.novell.com/ndk/susesdk.htm).

Install YaST SDK components from SUSE Linux SDK CD using YaST Control Center (/sbin/yast2). This is two-step process:

  1. Add Source Media using ?Change Source of Installation? option in YaST Control Center, if it is not added previously. Verify ?SLES SDK Version 9? is in the list.
    i.e. /sbin/yast2 ->Change Source of Installation ->Add (Software Source Media)


  2. Select ?Install and Remove Software? option in YaST Control Center (/sbin/yst2). i.e. /sbin/yast2 -> Install and Remove Software -> Filter (Selections)

    You should be able to select ?SDK YaST? option to install YaST development packages. Here is a brief description of some packages:
yast2-core-devel:     Include Files and Documentation for Core Libraries
yast2-devel: Development Scripts and Documentation
yast2-devtools: Scripts and Templates for developing YaST2 modules and components.


Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com

© 2014 Novell