Chapter 4. Interacting with other components

Table of Contents

4.1. Introduction
4.1.1. Observers
4.2. Objects module
4.3. Network module
4.4. Firewall module
4.5. Defining new observers

4.1. Introduction

There are three different reasons why your module may need to interact with other modules:

  • The simplest case is just the need to change some configuration setting in another module using its API. An example of this are all modules that offer services over the network, they need to tell the firewall on what port they are going to listen so that it can show all services in its configuration interface, letting the user choose who gets to use each service. This case is trivial, you just create an instance of the module you want to call and use its API to change whatever you need to change.

  • The second case are dependencies. A dependency happens when a module keeps reference to configuration items handled by other modules and needs to be restarted whenever the other module gets its configuration change. An example of this is the firewall, it lets you define rules for every network object defined in the objects module. However if you create rules for an object and then use the objects user interface to add new members to that object the firewall will need to be restarted too, so that the rules you created can be applied to the new members. This situation is very easy to manage, the firewall declares a dependency on the network module in its GConf schema, and then the framework automatically restarts the firewall module whenever the objects module is restarted. Declaring dependencies is explained in Section 3.6

  • Finally, the most complex situation is when some configuration information handled by your module depends on how other modules are configured. In the firewall example, what would happen if you go and delete that object for which you had just defined some rules? This kind of situation requires cooperation between both modules so that they can offer a consistent behavior to the user. This is what this chapter is all about, the following sections will describe how the objects, firewall and network modules solve this problem (these modules are the most likely to be needed by others) and it will show you how to solve this problem in your own modules.

4.1.1. Observers

Suppose you are writing a DHCP module, you want to let the user set up the dhcp service on a per network interface basis. However not all interfaces should be allowed to have a dhcp daemon running on them, if the user configured interface eth1 as a dhcp client, then it makes no sense to let him put a dhcp server on that interface. So, you decide that the dhcp configuration pages will only show network interfaces that have a static IP address. That's fine, but what happens if the user sets up the dhcp service on an static interface and later goes on to change the interface to dhcp or trunk mode?

Those modules that might have to inform other modules about certain events define abstract observer classes the other modules can extend from if they want to be notified when those events happen. The network module provides the EBox::NetworkObserver class for this purpose. This class has several abstract methods, your module may implement any of these methods and it will be notified when a relevant event takes place.