Exercise 3: Using events and actions

In the SME Server, events are like callbacks in a programming language. The system signals an event whenever something interesting happens (e.g. a user is added, the IP address changes, etc.), which automatically executes all programs in the event directory. Therefore, any applications which need to know when a certain event is happening simply create a symbolic link from the event directory to a handler program, which will get executed whenever the event occurs.

In the previous exercise, we relied on the predefined events and actions in the SME Server to keep the /etc/crontab file up to date. In this example, we will create a new action script that will track the user accounts in the system. This script can be used as a template for any type of application that has its own notion of user accounts and needs to be driven by the existing user interface for adding, deleting, or modifying users.

Start by creating a new file called /etc/e-smith/events/actions/demo-user-tracking with the following contents:

#!/usr/bin/perl -w

# Set up Perl environment and libraries

package esmith;
use strict;
use warnings;
use esmith::ConfigDB;
use esmith::AccountsDB;

# Prepare to access configuration databases
my $db = esmith::ConfigDB->open_ro
    or die "Couldn't open ConfigDB\n";

my $accounts = esmith::AccountsDB->open_ro
    or die "Couldn't open AccountsDB\n";

# Read domain name from configuration database
my $domain = $db->get_value('DomainName');

# Read command line arguments
my $event = $ARGV [0];
my $id    = $ARGV [1];

# If no command line arguments, assume this is the initial setup
 # of all users. Process all accounts of type "user" (ignore groups,
# information bays, printers, etc.)

unless ($event and $id)
{
    for my $user ($accounts->users)
    {
        my $key     = $user->key;
        my $first   = $user->prop('FirstName');
        my $last    = $user->prop('LastName');

        system ("/usr/bin/logger", "-t", "Demo3",
                "Initializing user $key ($first $last) in domain $domain");
    }

    exit 0;
}

# If command line arguments are present, then this is a create, modify,
# or delete event, signalled by the SME Server event/action system.

my $user  = $accounts->get($id)
    or die "User $id does not exist\n";

my $first = $user->prop('FirstName');
my $last  = $user->prop('LastName');

if ($event eq 'user-create')
{
    system ("/usr/bin/logger", "-t", "Demo3",
            "Creating user $id ($first $last) in domain $domain");
}
elsif ($event eq 'user-modify')
{
    system ("/usr/bin/logger", "-t", "Demo3",
            "Changing user $id to ($first $last) in domain $domain");
}
elsif ($event eq 'user-delete')
{
    system ("/usr/bin/logger", "-t", "Demo3",
            "Deleting user $id in domain $domain");
}
else
{
    system ("/usr/bin/logger", "-t", "Demo3", "Ignoring $event event");
}

exit 0;

Make sure the permissions are correct:

chmod +x /etc/e-smith/events/actions/demo-user-tracking

Now create symbolic links so that this program is executed whenever a user is created, modified, or deleted. Make three symbolic links; one for each event directory:

cd /etc/e-smith/events
ln -s ../actions/demo-user-tracking user-create/S90demo-user-tracking
ln -s ../actions/demo-user-tracking user-modify/S90demo-user-tracking
ln -s ../actions/demo-user-tracking user-delete/S90demo-user-tracking

The S90 prefix ensures that the program will be executed after the standard actions (which typically have prefixes ranging from S15 to S80).

Study this program carefully. It uses many different SME Server capabilities. If invoked from the command line with no arguments, it will read all user accounts from the user database, fetch all the data fields associated with each user, and print this information to the log file. If invoked as an event, the SME Server will automatically pass it the event name and user id as command line arguments; in this case the program will print messages to the log file explaining that it is adding, modifying, or dropping the user.

Trying watching the log file by running the command:

tail -F /var/log/messages

or with the "View log files" panel in the server-manager. Use the standard SME Server user interface to add, modify, or remove users. You should see a stream of comments in the log file.

If you were creating an application that had its own database of user information, you would replace the logfile-writing code with your own code that initialized new users, modified them, etc. Then you would arrange for the RPM post-install script to execute:

/etc/e-smith/events/actions/demo-user-tracking

with no command line arguments. When the application is initially installed, it will immediately read all users from the database and set them up in your application. Then, as users are added, modified, or dropped over time - your code will be invoked each time, to update the application's private user database.

Tip: It is almost always better to extend the existing accounts database with additional properties for your application than to maintain another database.