SUSE Conversations


How to integrate custom scripts into the YaST installation workflow and dialogs

ataschner

By: ataschner

September 9, 2009 3:15 pm

Reads:500

Comments:0

Rating:0

AutoYaST is an automated process to install SUSE operating systems onto diverse hardware. It enables unattended installations on diverse hardware defined in an XML-based control file that contains all settings and data required by the installer. Although AutoYaST is very flexible and allows for custom scripts to be executed during the installation, it is a challenge to monitor the progress of these scripts, or to at all see that they are being executed until after the installation has finished.

This article outlines the steps required to have custom scripts snap nicely into the installation framework including progress bar, messages about the individual steps being performed, logging and help text – just like many of the other installation dialogs. It applies to SUSE Linux Enterprise Server/Desktop 10 SP2.

Disclaimer: The technical level of this document is advanced and intermediate experience with AutoYaST and scripting is a prerequisite to get maximum benefit of it.

Details on how modify an installation DVD image to perform AutoYaST installation is beyond the scope of this article, but is described in TID 7001823 – Creating an auto-installing SLE 10 DVD

The things to do are as follows:

  1. Adapt the YaST module
  2. Include the module in the installation flow
  3. Choose and implement a delivery method
    • Pack the YaST module into a DUD file
    • Download
  4. Create a chroot script that imports the module

There are of course other approaches, but this one does the trick and is relatively simple.

At the end of the document you will also find a script to temporarily output to another terminal if that should be desirable.

1) Adapt the YaST module

General YaST module programming will not be discussed. Please refer to the documentation resources listed at OpenSUSE YaST (other suggestions are welcome).

The module (or YaST client to be correct) is written in the YaST Programming Language, called YCP and is attached (inst_mymodule.ycp).

It allows you to run each of your scripts or commands in either “normal” mode (without showing all the details on the screen) and verbose mode.

Each script or command to execute is a step and a description of the steps should be provided along with the command, since this is what will be displayed on the screen to the user.

A step is defined like this:

logStep( “<Description to appear in user dialog>” );
runStep( “<Command to execute>” );

An example of a step, that is using verbose output:

logStep( “Unpacking archive…” );
runStepVerbose( “tar -C / -zxvf /tmp/custom-files.tgz” );

These screenshots illustrate the difference between with using runStep and runStepVerbose for the same steps/commands:

Screenshot runStep
Fig. 1 – Using runStep

Screenshot runStep
Fig. 2 – Same commands, but using runStepVerbose

Once all the steps have been defined, it is essential to set the number_of_steps variable in order for the progress bar to function correctly.

The module is attached at the end of the article – remove the .txt extension before using it.

The author apologizes for the non-sequential organization of the things to be modified in the file, but hopes that the explanation in this document can make up for that.

There are also other variables, that might be desirable to modify, such as

  • helptext – Text to appear in left pane in ncurses (blue) interface. In the GUI version it only shows when clicking the Help button.
  • logfilename – Name of the log file in /var/log/YaST2/
  • sleep_after_completion – Time to sleep after all steps are done

Once the module has been adapted to fit your needs, it must be saved with a named inst_<something>.ycp in order to enable it to be included in the installation workflow.

In the scenario examples I have used the name inst_mymodule.ycp.

2) Include the module in the installation flow

The installation workflow is defined in the file control.xml, which resides in the root of the installation source.

In order to execute the module in the beginning of the Configuration tasks at the last stage of the installation, it should be defined just before the autoconfigure module (about 10 lines from the bottom of the file) like this:

<module>
<label>MyCompany specific customization</label>
<name>mymodule</name>
</module>

Label will be displayed as a step in the global installation workflow throughout the installation.

Name is the middle part of its filename without the prepending inst_ and the trailing .ycp.

Defining your module as the last module in the list will not work. YaST does not allow “running hooks at the end of the installation”. Been there, got the T-shirt.

3) Choose and implement a delivery method

Depending on the installation environment, it is possible to import the YaST module into the system being installed in different ways.

  • If it is possible to publish the module e.g. on an internal web server, this is preferrable
  • For stand-alone installations with no central repository for files, it needs to be packed into a driver update diskimage (DUD), which introduces additional, error-prone work

3a) Publish the module on a server

Whenever this is an option, go for it ! It is much simpler than creating a driver update disk, which needs to be recreated and updated in the installation source every time it changes.

If case the module gets published on a web server it can be retrieved using wget in a chroot script during stage 1 of the installation.

Simply publish the file somewhere and continue with step 4.

3b) Create a driver update disk

If publishing on a server is not possible, or standalone installation is preferred, choose this option. The steps are only described briefly here. For more information about DUD – see Autoyast: How and why you may need to update your SLE installation environment and source >

The files from a (DUD) are only available in stage 1 of the installation (before the boot). Since the YaST module should run during stage 2, it needs to be copied from the DUD to /usr/share/YaST2/clients/.

A small chroot script in the AutoYaST profile can accomplish that task.

  • Create a directory structure like this

    dud/linux/suse/x86_64-sles10/inst-sys/

    and copy the module to

    dud/linux/suse/x86_64-sles10/inst-sys/inst_mymodule.ycp
  • Create the driver update disk configuration file (dud.config):

    It is a short text file to describe the contents of the driverupdate file.

    An example:

      $ cat dud/linux/suse/x86_64-sles10/dud.config
      UpdateName: YaST module for private customization of the system
      UpdateID: inst_mymodule.ycp

    The UpdateName in the dud.config file will be displayed after the

    “Loading Driver Update – 0% ” (0% is normal)

    right after loading the installation system when kicking off the installation.

    UpdateID should be a unique string identifying the update.

    Your own scripts/files could also be added to this disk, as long as the total size does not exceed 16 MB.

  • Create a disk image of the file with mkfs.cramfs like this:
    # mkfs.cramfs dud/ driverupdate
  • Copy this driverupdate file to the root of the installation source

4) Create a chroot script that imports the module

The YaST module needs to be imported to the installed system by your AutoYaST profile. It is executed after the package installation and before the first boot.

If the module e.g. is published on an internal web server, the command should be something like:

wget -O /mnt/usr/share/YaST2/clients/inst_mymodule.ycp http://myserver/insttools/inst_mymodule.ycp

However if using a DUD, which gets mounted as /update/000/, the command would be:

cp -v /update/000/inst-sys/inst_mymodule.ycp /mnt/usr/share/YaST2/clients/

Simply adapt the example below and insert it after the <runlevel> section of the AutoYaST profile. Of course the <scripts> </scripts> tags should be removed if there is already such a section in the profile.

  <scripts>
    <chroot-scripts config:type="list">
      <script>
        <filename>copy-yastmodule.sh</filename>
        <interpreter>shell</interpreter>
        <chrooted config:type="boolean">false</chrooted>
        <source><![CDATA[
            #!/bin/sh
            # Get YaST module inst_mymodule.ycp
            # Uncomment and adapt the applicable command below
            # From an http source:
            # wget -O /mnt/usr/share/YaST2/clients/inst_mymodule.ycp http://<myserver/insttools>/inst_mymodule.ycp
            # from inst-sys
            # cp -v /update/000/inst-sys/inst_mymodule.ycp /mnt/usr/share/YaST2/clients/
            ]]>
        </source>
      </script>
    </chroot-scripts>
  </scripts>

AutoYaST stores the script in /var/adm/autoinstall/scripts/<filename> and the execution output of it will be logged to /var/adm/autoinstall/logs/<filename>.log.

That should be it. This is just a skeleton and some inspiration. The rest is up to your imagination.

Script to temporarily output to another terminal

This script enables you to switch away from the installation dialog screen/tty and display output there if it is more feasible (perhaps for debugging). At the end it will return to the YaST dialog tty.
It could be used as any other script in the YaST module.

# This script is useful if customization commands during
# system installation generate extended output that is
# unfeasible for the YaST log widget.
# It switches to a new tty, performs the commands and
# switches back to the tty it was invoked from.

CURVT=`/bin/fgconsole`
[ -z "$CURVT" ] && CURVT=1
NEWVT=16
DEVVT=/dev/tty$NEWVT
# Switch to the new terminal
/bin/chvt $NEWVT
# If this is a serial console, we should write there instead 
cons=`sed 's/.*console=\([^ ,]*\).*/\1/' /proc/cmdline` 
case "$cons" in
       ttyS*)  DEVVT=/dev/$cons ;;
       *)      DEVVT=/dev/tty$NEWVT ;;
esac
echo "Starting script (`date`):" > $DEVVT
########################################
#     Commands to execute go here      #
#  Append "> $DEVVT" to the commands   #
########################################

# Example : 
echo "Listing installation log files" > $DEVVT
ls -l /var/log/YaST2/ > $DEVVT

########################################
#     End of commands to execute       #
########################################

# Commands end

echo "Sleeping a little to allow time to read the output ..." > $DEVVT
sleep 10
# Switch back to the installation dialog
/bin/chvt $CURVT
exit

Comments and suggestions are welcome.

Known issues:
If a command to be executed contains an asterisk (*) and is is being executed with runStepVerbose, it will be written incorrectly in the log file (screen output is still OK).

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Tags: , , ,
Categories: SUSE Linux Enterprise Server, Technical Solutions

Disclaimer: As with everything else at SUSE Conversations, this content is definitely not supported by SUSE (so don't even think of calling Support if you try something and it blows up).  It was contributed by a community member and is published "as is." It seems to have worked for at least one person, and might work for you. But please be sure to test, test, test before you do anything drastic with it.

Comment

RSS