Frequently Asked Questions

1. General / Unsorted
1.1. How to comment functions and variables
1.2. How to read and write text files in YaST?
1.3. How to read and write sysconfig values?
1.4. How to run external programs?
1.5. Where are proposal screens handled during 2nd stage of installation?
1.6. Where the YaST2 logs can be found?
1.7. How is YaST2 logging done?
1.8. How to mark any text for the translation?
1.9. What kinds of VALIDATION code has been implemented in modules?
1.10. Are there some good examples of the use of Wizard? Any documentation?
1.11. What is the semantics of Wizard::SetDesktopIcon ("proxy") ?
1.12. What is the semantics of Wizard::CreateDialog() ?
1.13. What is the meaning of YCP files generated by y2tool?
1.14. Has anyone created a YaST mode for EMACS?
1.15. How to add a user using a script?
1.16. Could be any map seen as a tree?
1.17. How to create a new YaST module
2. Testing
2.1. How to test the YCP code?
2.2. How to test the SCR agent?
2.3. How to start and stop services?
2.4. How to test the first stage installation (before reboot)?
2.5. How to test the second stage installation (after reboot)?
2.6. How to test the installation proposals?
2.7. How to test YaPI and PerlAPI functions?
2.8. How to test the AutoYaST?
2.9. How to test the AutoInstallation?

1. General / Unsorted

1.1. How to comment functions and variables
1.2. How to read and write text files in YaST?
1.3. How to read and write sysconfig values?
1.4. How to run external programs?
1.5. Where are proposal screens handled during 2nd stage of installation?
1.6. Where the YaST2 logs can be found?
1.7. How is YaST2 logging done?
1.8. How to mark any text for the translation?
1.9. What kinds of VALIDATION code has been implemented in modules?
1.10. Are there some good examples of the use of Wizard? Any documentation?
1.11. What is the semantics of Wizard::SetDesktopIcon ("proxy") ?
1.12. What is the semantics of Wizard::CreateDialog() ?
1.13. What is the meaning of YCP files generated by y2tool?
1.14. Has anyone created a YaST mode for EMACS?
1.15. How to add a user using a script?
1.16. Could be any map seen as a tree?
1.17. How to create a new YaST module
1.1.

How to comment functions and variables

This section describes how to comment functions for other YaST tools to let them generate documentation automatically. Documentation is generated by script

/usr/lib/YaST2/bin/ycpdoc which can be found in the yast2-devtools package. See more detailed information by typing perldoc /usr/lib/YaST2/bin/ycpdoc. More examples can be found in the yast2-devtools package or in the /usr/share/doc/packages/yast2-devtools/ycpdoc/example/ directory.

This is the exemplary file header

/**
 * File:        modules/AnyFile.ycp
 * Package:     Fork and Knife Configuration
 * Summary:     Interface manipulation (/etc/sysconfig/fork and /etc/sysconfig/knife)
 * Authors:     John The Fish <johnthefish@yahoo.com>
 *
 * $Id: AnyFile.ycp 43423 2005-12-24 16:14:12Z fish $
 *
 * Imagine that this is a long description text.
 */

		    

ycpdoc recognizes comments when they are marked with special syntax

/**
 * some description
 * can be multiline
 */

Exemplary function comment

/**
 * @short       Returns names of network devices
 * @descr       This is a multi-line
 *              function description
 *
 * @param       boolean configured      whether function should return configured
 *                                      or unconfigured network devices
 * @param       string any_string_param just some second function parameter
 * @return      list <string> of network device names
 *
 * @see         GetAllNetworkInterfaceNames1
 * @see         GetAllNetworkInterfaceNames2
 * @example
 *              // Returns configured devices
 *              GetAllNetworkDeviceNames(true, "this is a string")
 *
 *              // Returns unconfigured devices
 *              GetAllNetworkDeviceNames(false, "this is another string")
 */
global list <string> GetAllNetworkDeviceNames (boolean configured, string any_string_param) {
    // ...
    return [ "Network Device Name 1", "Network Device Name 2" ];
}

		    

Exemplary variable descriptions

/**
 * This variable says whether the example is nice or not
 */
global boolean nice_example = true;

/**
 * Local variable for caching found keys/values
 */
map <string, string> closer_defined_map = $[ "key1" : "value", "key2" : "any string" ];
 
// This variable will not be documented
list <string> xyz = [ "string 1", "string 2", "string 3" ];

		    
1.2.

How to read and write text files in YaST?

Use .target.string path of 'system agent' to manipulate with the text files.

The Read function returns the whole contents as a one string, with the write variant you can rewrite the file.

/**
 * Example of using SCR/.target.string
 */
{
    import "SCR";

    string contents = (string) SCR::Read (.target.string, "/some/file");

    if (contents == nil)
	y2error("filename does not exist");

    boolean success = SCR::Write (.target.string,"/some/file", contents);
}

Documentation of system agent can be found at /usr/share/doc/packages/yast2-core/agent-system

Check for existing SCR agents for various configuration files.

If you want to read/edit/write known config file, it is very likely that SCR agent for this file already exists. The easy way to find this out is grep the files under /usr/share/YaST2/scrconf/ directory for the file name.

If you want to manipulate with a file contents (e.g. delete or rewrite some line) it is possible to use AsciiFile module, which describes the file by the map.

map file = $[];
AsciiFile::ReadFile (file, "/tmp/myfile");
// now you can check the 'file' map manually
// or using AsciiFile interface ...
AsciiFile::RewriteFile (new_map, "/tmp/myfile");
                            

For more, look directly into /usr/share/YaST2/modules/AsciiFile.ycp.

/**
 * Example for text file modification
 */
{
    import "AsciiFile";

    // let's have some file at the /tmp/simple-file location
    SCR::Write (.target.string, "/tmp/simple-file", "first line\nsecond line");

    // now read it into the map using AsciiFile
    map file	= $[];
    AsciiFile::ReadFile (file, "/tmp/simple-file");

    // modify line by line and save the modified file
    integer i	= 1;
    foreach (integer number, map linemap, file["l"]:$[], {
	y2internal ("line: %1", linemap);
	string line	= linemap["line"]:"";
	file["l",number,"line"]	= sformat ("%1.%2", i, line);
	i = i + 1;
    });
    AsciiFile::RewriteFile (file, "/tmp/simple-file");

    // ----------------------------------------
    // now, do the same thing using system agent...

    SCR::Write (.target.string, "/tmp/simple-file", "first line\nsecond line");
    i = 1;
    string contents = (string) SCR::Read (.target.string, "/tmp/simple-file");
    string new_contents = "";
    foreach (string line, splitstring (contents, "\n"), {
	y2internal ("line: %1", line);
	new_contents	= new_contents + sformat ("%1.%2\n", i, line);
	i = i + 1;
    });
    SCR::Write (.target.string, "/tmp/simple-file", new_contents);
}

                        
1.3.

How to read and write sysconfig values?

First, you need the scr file which actually calls an agent that handles this type of files. In this case it is done using the so called ini agent which can handle multiple types of config files, not only ini files.

The following listing is an example scr script which calls the ini agent special handling for sysconfig files:

/**
 * File:
 *   cfg_novell_apache.scr
 * Summary:
 *   SCR Agent for reading/writing /etc/sysconfig/novell-apache
 *   using the sysconfig-agent
 *
 *
 * Read/Sets the values defined in <tt>/etc/sysconfig/novell-apache</tt>
 * in an easy manner.
 */
.sysconfig.novell-apache

`ag_ini (
    `SysConfigFile("/etc/sysconfig/novell-apache")
)

                        

Now, this file has to be installed in /usr/share/YaST2/scrconf/ directory. In you ycp code, you can access the variable TESTING the following way:

                            
string test = (string) SCR::Read(.sysconfig.novell-apache.TESTING);
                        

and you can write it:

                            
SCR::Write(.sysconfig.novell-apache.TESTING, "a value");
                        

For most sysconfig files, there already exist the agents - you can grep in /usr/share/YaST2/scrconf/ directory for the file name you are looking for.

// read the BASE_CONFIG_DN variable from /etc/sysconfig/ldap
string base_config_dn = SCR::Read (.sysconfig.ldap.BASE_CONFIG_DN);

// ... and save the new value
SCR::Write (.sysconfig.ldap.BASE_CONFIG_DN, new_dn); 
                    

For documentation, see /usr/share/doc/packages/yast2-core/agent-ini/ini.html

/**
 * Example for sysconfig variables
 */
{
    // check for available sysconfig files from the base directory
    list sys_files	= SCR::Dir (.sysconfig);
    if (contains (sys_files, "ypbind"))
    {
	// read variable from /etc/sysconfig/ypbind
	string var = (string) SCR::Read(.sysconfig.ypbind.YPBIND_BROKEN_SERVER);
	y2milestone ("YPBIND_BROKEN_SERVER: %1", var);
    }

    // some files are in subdirectories, like /etc/sysconfig/network:
    y2milestone ("dir: %1", SCR::Dir (.sysconfig.network));

    // now modify the file /etc/sysconfig/network/dhcp
    if ((string) SCR::Read (.sysconfig.network.dhcp.DHCLIENT_SET_HOSTNAME)
	== "yes")
    {
	SCR::Write (.sysconfig.network.dhcp.DHCLIENT_SET_HOSTNAME, "no");
    }
}

                        
1.4.

How to run external programs?

Use 'system agent' documented in /usr/share/doc/packages/yast2-core/agent-system/.

/**
 * Example of using .target.bash
 */
{
    import "SCR";

    integer ret = (integer) SCR::Execute (.target.bash, "/bin/touch /tmp/file", $[]);

    // System environment variables which will be accessible in the
    // Execute() command
    map environment = $[
	"FILE":"/somedir/somefile"
    ];
    string command = "/bin/touch $FILE";
    map output = (map) SCR::Execute (.target.bash_output, command, environment);
}

Using .target.bash path you can run bash command, defined by the string parameter. The last parameter can be used to give initial environment definitions to the target. The keys have to be strings, the values can be of any type. The return value is an integer with the exitcode. If you use .target.bash_output path, the return value will be the map:

$[
    "exit" : <integer>,  //exitcode from shell script
    "stdout" : <string>, //stdout of the command
    "stderr" : <string>  //stderr of the command
]

/**
 * Example for running commands
 */
{
    // check if file exists
    if (SCR::Execute (.target.bash, "/usr/bin/test -e /tmp/myfile") == 0)
    {
	// check the file size
	integer filesize = (integer) SCR::Read (.target.size, "/tmp/myfile");

	// remove the 'big' file
	if (filesize > 10)
	{
	    boolean success = (boolean) SCR::Execute (.target.remove, "/tmp/myfile");
	    y2warning ("file removed: %1", success);
	}
	// enlarge the small one
	else
	{
	    SCR::Execute (.target.bash, "/bin/echo aaa >> /tmp/myfile");
	    map out = (map)
		SCR::Execute (.target.bash_output, "/bin/ls -l /tmp/myfile");
	    y2internal ("ls stdout: %1", out["stdout"]:"");
	}
    }
    // if not, create it
    else
    {
	SCR::Execute (.target.bash, "/bin/touch /tmp/myfile");
    }
}

                        
1.5.

Where are proposal screens handled during 2nd stage of installation?

For each proposal the control file /var/lib/YaST2/control.xml contains a list of clients to be called. The tag <proposal> describes the name of the client. Then, the name is suffixed by _proposal, for instance proxy_proposal.ycp, and such client is started via WFM::Call. The required action is done by a command line argument. Each proposal client has to implement the following arguments:

  • MakeProposal - prepare a proposal, return its summary

  • AskUser - start the GUI for user to manually modify the proposal

  • Description - return a map for title, entry in the menu button and your id

  • Write - user accepted the proposal, write it down

For more details see *_proposal.ycp clients in /usr/share/YaST2/clients/ directory and documentation in /usr/share/doc/packages/yast2-installation/.

1.6.

Where the YaST2 logs can be found?

Logs are situated in the /var/log/YaST2/ directory. They are named y2log and from y2log-1 to y2log-9, rotated in the size at about 1.1 MB.

1.7.

How is YaST2 logging done?

YaST2 loggings are done using y2* built-in functions. This is a simple program, which should help us with the logging.

/**
 * Example for logging
 * File: y2logs.ycp
 */
{
    y2debug	("debug");
    y2milestone	("milestone");
    y2warning	("warning");
    y2error	("error");
    y2security	("security");
    y2internal	("internal");
}
                        
  • y2debug is used only for the debugging information, only for testing because it is not logged during the normal run of the YaST2. It is usable only for the developer.

  • y2milestone is used for logging some important information. For instance Configuration has been changed, saving into the '/etc/any.conf'.

    y2milestone("Configuration has been changed, saving into the '%1'",
        "/etc/any.conf");
  • y2warning is used to announce that something would go wrong. For instance when any configured card has been lost after the reboot.

  • y2error is used for major problems. For instance if YaST2 didn't find what it expected and needed.

  • y2security is not used.

  • y2internal is not used.

And this is the part of the log found in the logfile /var/log/YaST2/y2log after we have runned Y2DEBUG=1 yast2 y2logs.ycp, we would not see any debug information if we would run yast2 y2logs.ycp only.

2004-09-21 10:04:13 <0> wizard(5964) [YCP] y2logs.ycp:2 debug
2004-09-21 10:04:13 <1> wizard(5964) [YCP] y2logs.ycp:3 milestone
2004-09-21 10:04:13 <2> wizard(5964) [YCP] y2logs.ycp:4 warning
2004-09-21 10:04:13 <3> wizard(5964) [YCP] y2logs.ycp:5 error
2004-09-21 10:04:13 <4> wizard(5964) [YCP] y2logs.ycp:6 security
2004-09-21 10:04:13 <5> wizard(5964) [YCP] y2logs.ycp:7 internal

Format of the log is [year]-[month]-[day] [time] [log-weight] [process-name](PID) [library] [filename]:[line-number] [message]. y2* built-in functions accepts maximally 9 parameters of variables:

y2milestone("This is the example for %3, %4, %1 and %2",
    "1st parameter", "2nd parameter", "3rd parameter", "4th parameter");

Each %[number] is replaced by the corresponding variable. Parameters can be all types (function, boolean, integer, map ...).

1.8.

How to mark any text for the translation?

There are two internal functions for marking the text for the translation. They are _(string text) (single underscore) in YCP and __(string text) (double underscore) in Perl. It is needed to place every single calling of the function on the separate line because of making .pot file. Every text marked for translation should be commented above for the translators.

/**
 * Example for marking texts for translations
 */
{
    import "Popup";

    textdomain "example";

    // TRANSLATORS: Checkbox
    term checkbox = `CheckBox(`id("use maximum"), _("Use &Maximum"));

    string filename = "/etc/this_file_doesn't_exist";
    // TRANSLATORS: An error popup message, %1 is the name of the file
    Popup::Error(sformat( _("Cannot open the file '%1'"),
	filename)
    );

    boolean expert_mode = true;
    string help =
	// TRANSLATORS: help text for simple and expert functonality (1/2)
	_("<p>This is the help text for the simple functionality</p>") +
	(expert_mode == true ?
	    // TRANSLATORS: help text for expert functionality only (2/2)
	    _("<p>And this is the help for the additional functionality</p>")
	    :
	    ""
	);
}
                        
1.9.

What kinds of VALIDATION code has been implemented in modules?

For simple syntax validation there is a lot of it, but only the basic ones are grouped together in the yast2.rpm. Those are:

  • IP::Check(), IP::Check4(), IP::Check6() for IP addresses checking

  • Hostname::Check(), Hostname::CheckDomain(), Hostname::CheckFQ() for Hostnames (DNS)

  • Address::Check(), Address::Check4(), Address::Check6() for addresses (IP or a hostname)

  • Netmask::Check(), Netmask::Check4(), Netmask::Check6() for netmasks

  • URL::Check() for URL syntax

For the rest you need to lookup in the corresponding YaST modules.

/**
 * Example for validation functions
 */
{
    import "Address";
    import "IP";
    import "Netmask";
    import "Popup";
    import "URL";

    term contents = `VBox (`HSpacing (50),
	`VSpacing (2),
	`TextEntry (`id (`ip), "Enter IP"),
	`PushButton (`id (`checkip), "Validate"),
	`VSpacing (2),

	`TextEntry (`id (`address), "Enter adress (IP or hostname)"),
	`PushButton (`id (`checkaddress), "Validate"),
	`VSpacing (2),

	`TextEntry (`id (`netmask), "Enter Netmask"),
	`PushButton (`id (`checknetmask), "Validate"),
	`VSpacing (2),

	`TextEntry (`id (`url), "Enter URL"),
	`HBox (
	    `PushButton (`id (`checkurl), "Validate"),
	    `PushButton (`id (`checkhttp), "HTTP only")
	),
	`VSpacing (2),

	`PushButton (`id (`exit), "Exit")
    );
    UI::OpenDialog (contents);

    any ret	= nil;
    repeat
    {
	ret		= UI::UserInput ();
	string ip	= (string) UI::QueryWidget (`id(`ip), `Value);
	string address	= (string) UI::QueryWidget (`id(`address), `Value);
	string netmask	= (string) UI::QueryWidget (`id(`netmask), `Value);
	string url	= (string) UI::QueryWidget (`id(`url), `Value);

	if (ret == `checkip)
	{
	    if (IP::Check4 (ip))
		Popup::Message ("OK");
	    else
		Popup::Error (IP::Valid4 ());
	}
	if (ret == `checkaddress)
	{
	    if (Address::Check4 (address))
		Popup::Message ("OK");
	    else
		Popup::Error (Address::Valid4 ());
	}
	if (ret == `checknetmask)
	{
	    if (Netmask::Check4 (netmask))
		Popup::Message ("OK");
	    else
		Popup::Error ("Not OK");
	}
	if (ret == `checkurl)
	{
	    if (URL::Check (url))
		Popup::Message ("OK");
	    else
		Popup::Error ("not ok");
	    y2internal ("parsed: %1", URL::Parse (url));
	}
	// do some own checking for url
	if (ret == `checkhttp)
	{
	    if (URL::Check (url))
	    {
		map parsed = URL::Parse (url);
		y2milestone ("parsed: %1", parsed);
		if (parsed["scheme"]:"" != "http")
		{
		    Popup::Error ("not http");
		}
		else
		{
		    Popup::Message ("OK");
		}
	    }
	    else
	    {
		Popup::Error ("not ok");
	    }
	}
    } until (ret == `exit || ret == `cancel);

    UI::CloseDialog ();

/* some examples of URL checks:
y2milestone("%1", URL::Check("http://a:b@www.suse.cz:33/ahoj/nekde?neco#blah"));
y2milestone("%1", URL::Check("ftp://www.suse.cz/ah"));
y2milestone("%1", URL::Check("ftp://www.suse.cz:22/ah"));
y2milestone("%1", URL::Check("www.suse.cz ah"));
*/

}

                        
1.10.

Are there some good examples of the use of Wizard? Any documentation?

See /usr/share/doc/packages/yast2/wizard/examples/ and /usr/share/doc/packages/yast2-core/libyui/examples/Wizard...

The wizard is controlled by the Wizard YCP module (import "Wizard"). It's documentation is in /usr/share/YaST2/modules/Wizard.ycp.

1.11.

What is the semantics of Wizard::SetDesktopIcon ("proxy") ?

This sets the icon at the left side of the dialog title label to the one used by the yast2-proxy desktop file. It is the same as appears in the yast2 control center.

1.12.

What is the semantics of Wizard::CreateDialog() ?

This creates a Wizard Dialog. This is the basic framework used in YaST screens with help on the left and the YaST graphics on top. At the bottom there are usually three buttons, Back, Abort and Next. This is how a workflow is implemented. However, in the last step of a workflow, naming the rightmost button "next" isn't appropriate.

Wizard::SetNextButton (`next, Label::FinishButton);

replaces the button caption with "Finish".

In some dialogs you need to hide some default buttons or to restorem them again.

Wizard::HideBackButton ();

hides the Back button.

Wizard::RestoreAbortButton ();

restores hidden Abort button.

1.13.

What is the meaning of YCP files generated by y2tool?

TODO ... more about templates, and devtools

1.14.

Has anyone created a YaST mode for EMACS?

TODO

Syntax file for VIM is part of SUSE's vim package.

1.15.

How to add a user using a script?

For documentation of whole Users module API, look at /usr/share/YaST2/modules/YaPI/USERS.pm

Example 1. YCP script

/**
 * Simple script for adding new user
 * call 'yast2 adduser.ycp <username> <password>
 */
{
    import "YaPI::USERS";

    // take user name and password from the command line
    list args		= WFM::Args ();
    string uid		= args[0]:"";
    string passwd	= args[1]:"";

    map<string,any> config	= $[];
    map<string,any> data	= $[
	"uid"		: uid,
	"userpassword"	: passwd
    ];

    string error	= YaPI::USERS::UserAdd (config, data);

    // the return value is empty string on success
    if (error != "")
    {
	y2error ("add user error: %1", error);
    }
}

                        

Example 2. Perl script

#!/usr/bin/perl -w

#
# Simple script for adding new user
# Requires 2 parameters: <username> <password>
#

BEGIN {
    push @INC, "/usr/share/YaST2/modules";
}

use YaPI::USERS;

# take user name and password from the command line
my $uid    = shift;
my $passwd = shift;

my $config	= {};
my $data	= {
    "uid"		=> $uid		|| "",
    "userpassword"	=> $passwd	|| ""
};
my $error     = YaPI::USERS->UserAdd ($config, $data);

# the return value is empty string on success
print "add user error: '$error'\n";

                        

Example 3. Perl script for LDAP user

#!/usr/bin/perl -w

#
# Simple script for adding LDAP user
# Requires 2 parameters: <username> <password>
#

BEGIN {
    push @INC, "/usr/share/YaST2/modules";
}

use YaPI::USERS;

# take user name and password from the command line
my $uid    = shift;
my $passwd = shift;

my $config	= {
    "type"		=> "ldap",
    "bind_pw"	      	=> "q"	# password for LDAP administrator
};

my $data	= {
    "sn"		=> $uid		|| "",
    "uid"		=> $uid		|| "",
    "userpassword"	=> $passwd	|| "",
    "description"       => [ "first", "second" ] # additional LDAP attribute
};

my $error     = YaPI::USERS->UserAdd ($config, $data);

# the return value is empty string on success
if ($error) {
    print "add user error: '$error'\n";
}

                        

1.16.

Could be any map seen as a tree?

Maps which you can find in y2log are not human-readable. You can use the tree view in UI which is the one you can find in yast2-testsuite package.

/**
 * Example for debugging (browsing) any map in TreeWidget
 */
{
    include "devel/debug.ycp"; // including part of yast2-testsuite
    
    map this_map = $[
	"list1" : [
	    $[ "string1" : 555 ], [ "a", "b", "c" ], 1, 2, 3, $[ "b" : 5 ],
	    $[ "string2" : [ $[ "a" : 1 ], $[ "a" : 22 ], $[ "a" : 333 ] ] ],
	],
	"list2" : [
	    $[ "key1" : "value1", "key2" : [ "1", "2", "3" ] ],
	    [ "string", 1 ], [ 5, "string" ], [ [ 1 ], [ 2 ], [ 3 ] ],
	],
    ];

    // Opens UI window with a browsable tree
    DEBUG(this_map);
}
                        

As you can see, this is very ugly map. Run yast2 debug_map.ycp to open the UI tree and browse the map.

1.17.

How to create a new YaST module

Use the /usr/bin/y2tool create-new-package. y2tool is included in the yast2-devtools package.

/usr/bin/y2tool create-new-package -s returns a list of available skeletons. They are:

  • agent - SCR agent skeleton

  • config - YaST configuration module skeleton

  • trans - YaST translation

To create a new YaST module run: /usr/bin/y2tool create-new-package -v config module-name "Maintainer Name" maintainer@email.com

2. Testing

2.1. How to test the YCP code?
2.2. How to test the SCR agent?
2.3. How to start and stop services?
2.4. How to test the first stage installation (before reboot)?
2.5. How to test the second stage installation (after reboot)?
2.6. How to test the installation proposals?
2.7. How to test YaPI and PerlAPI functions?
2.8. How to test the AutoYaST?
2.9. How to test the AutoInstallation?
2.1.

How to test the YCP code?

Use simple command ycpc -E source.ycp. It would report errors it it would find any.

Attention: files imported and included in the source are got from the default YaST2 directory /usr/share/YaST2/ first of all other locations.

2.2.

How to test the SCR agent?

Use the /usr/lib/YaST2/bin/y2base stdio scr command which allows you to send commands directly to the SCR. Commands are `Dir(path), `Read(path) and `Write(path).

`Dir(.sysconfig.network)
-> (["config", "dhcp", "providers"])

`Read(.sysconfig.network.dhcp.DHCLIENT_SET_HOSTNAME)
-> ("no")

`Write(.sysconfig.network.dhcp.DHCLIENT_SET_HOSTNAME, "yes")
-> (true)
2.3.

How to start and stop services?

  • Service Manipulation

    /**
     * Example for service manipulation
     */
    {
        import "Service";
        
        string service = "squid";
        
        boolean start   = Service::Start   (service);
        boolean stop    = Service::Stop    (service);
        boolean restart = Service::Restart (service);
        boolean reload  = Service::Reload  (service);
    }
  • Service Enabling

    /**
     * Example handling services in runlevels
     */
    {
        import "Service";
        
        string service = "cups";
        
        boolean enable   = Service::Enable  (service);
        boolean disable  = Service::Disable (service);
    
        // Adjust runleveles for service:
        boolean adjust   = Service::Adjust (service, "enable");
    
        // Set service to run in selected runlevels:
        boolean finetune = Service::Finetune (service, [ 3, 5 ]);
    }
  • Service Information

    /**
     * Example of getting information about services
     */
    {
        import "Service";
        
        string service = "sshd";
        
        // Get service info without peeking if service runs:
        map info = Service::Info (service);
        
        // Get service info and check if service is running:
        map full = Service::FullInfo (service);
        
        // Get service status
        integer status  = Service::Status (service);
        
        // Returns true if link in /etc/init.d/rc?.d/ exists for this service
        boolean enabled = Service::Enabled (service);
    }

Documentation can be found in /usr/share/doc/packages/yast2/runlevel/

/**
 * Example for handling services
 */
{
    import "Service";

    // if ypbind service is running (= '/etc/init.d/ypbind status')
    if (Service::Status ("ypbind") == 0)
    {
	// stop it (= '/etc/init.d/ypbind stop')
	Service::Stop ("ypbind");
    }
    else
    {
	// else start it (= '/etc/init.d/ypbind start')
	Service::Start ("ypbind");
    }

    // if ypbind service is enabled (
    if (Service::Enabled("ypbind"))
    {
	// disable it (= 'insserv -r ypbind')
	Service::Disable ("ypbind");
    }
    else
    {
	// else enable it (= 'insserv ypbind')
	Service::Enable("ypbind");
    }
}

                        
2.4.

How to test the first stage installation (before reboot)?

...

2.5.

How to test the second stage installation (after reboot)?

...

2.6.

How to test the installation proposals?

You can use this code to test the `network installation proposal:

/**
 * Example of testing network proposal
 */
{
    import "Wizard";
    import "Mode";

    Wizard::CreateDialog ();

    Mode::stage = "continue";
    WFM::CallFunction ("inst_proposal", [true, true, `network]);
}
                        

Run yast2 network_proposal.ycp to open the UI with the appropriate installation proposal.

There are more proposals with in more stages. You should find it in the control.xml file.

  • Proposal: `initial, Stage initial for the first stage installation

  • Proposal: `dirinstall, Stage normal for the installation into the directory

  • Proposal: `network, Stage continue for the second stage network configuration

  • Proposal: `hardware, Stage continue for the second stage hardware configuration

2.7.

How to test YaPI and PerlAPI functions?

There more methods of testing YaPI and PerlAPI functions. Let me show you one of them - simple YCP script.

/**
 * Example of calling YaIP/PerlAPI functions
 */
{
    import "SambaServer";

    y2milestone("Export_A: %1", SambaServer::Export());
    SambaServer::addShare("NEW1_SHARE", $[ "public" : "yes" ]);
    y2milestone("Export_B: %1", SambaServer::Export());
    SambaServer::addShare("NEW2_SHARE", $[ "public" : "no" ]);
    y2milestone("Export_C: %1", SambaServer::Export());
}
                        

Run this simple script using the yast2 samba.ycp command and see the log for the result. Here are the interesting parts of the log:

"shares":[
    $["options":[
	$["key":"public", "value":"yes"]],
	"share":"NEW1_SHARE"
    ]
]

at the "Export_B".

"shares":[
    $["options":[
	$["key":"public", "value":"yes"]],
	"share":"NEW1_SHARE"
    ],
    $["options":[
	$["key":"public", "value":"no"]],
	"share":"NEW2_SHARE"
    ]
]

at the "Export_C".

This is the PerlAPI implementation of the same functionality:

#! /usr/bin/perl -w

# Example of using YaPI/PerlAPI in Perl

use strict;
use Data::Dumper;

use ycp;
use YaST::YCP qw(sformat);
YaST::YCP::Import ("SambaServer");

y2milestone("Export_A: ".Dumper(SambaServer->Export()));
SambaServer->addShare("NEW1_SHARE", { "public" => "yes" });
y2milestone("Export_B: ".Dumper(SambaServer->Export()));
SambaServer->addShare("NEW2_SHARE", { "public" => "no" });
y2milestone("Export_C: ".Dumper(SambaServer->Export()));
                        

This is another example of the YaPI testing. It will open the popup window with an error message.

/**
 * Example of Popup
 */
{
    import "Popup";
    
    Popup::Error("Exemplary error message");
}
                        
2.8.

How to test the AutoYaST?

...

2.9.

How to test the AutoInstallation?

...


Copyright © 2005-2006 Novell, Inc., All rights reserved. Feedback
Validate XHTML