A primary reason for the success of Webmin in so many environments is its reliance on modules to perform configuration specific to the various services and servers it supports. Though this was touched on briefly in the earlier parts of the book, this chapter is entirely about Webmin modules: What they are, how they work, and most importantly how to create your own. This chapter will detail the creation of a module along with a reference to the most common functions of the Webmin module API.
Because Webmin is under constant development, and new features are being added with every version, the module API is a moving target. Effort does go into making all API additions backward compatible, but it is best to refer to the official Webmin module programmers reference for specific information on the API.
Webmin has a number of components operating together to present the fancy GUI that you have so far associated with Webmin. This GUI is the facade to the real work behind the scenes, and naturally, many users won't care to go beyond that facade. Those who are content to be a Webmin user, and have no interest in becoming a Webmin enhancer, may wish to skip this chapter and go onto enjoying the light reading that follows (i.e. the index).
Webmin may be broken into a few parts for discussion. The first part is the miniserv.pl micro-webserver, which runs all the time and is the engine that pushes around the rest of the parts of the Webmin system. The configuration of miniserv.pl has already been discussed in the beginning of the book, but it is worth discussing some of the things that separate the Webmin web server from a traditional webserver like Apache. First, and foremost perhaps, the Webmin server is simpler than a full-blown webserver. It has very few features, except those required for its sole purpose in life. It offers access control features, support for encrypted communication, CGI support (so it can run all the rest of the Webmin parts), support for certificates, and logging.
Next comes the Webmin web-lib.pl library (hereafter, simply referred to as the web-lib) of Perl functions that are used by most of the rest of the Webmin system. This library contains all of the functions that are usually included in all Webmin modules, and can be used by all Webmin modules to simplify the generic tasks that all Webmin modules must be able to perform. The web-lib will almost always be read in for all of the modules you write. Though it is possible to write a module that does not rely on the web-lib it probably isn't advisable. This library contains functions to read and write files, process input strings and file lines, handle CGI form processing, lock and unlock files, present pages of icons, and manage access control. In recent versions, the web-lib has acquired an array of foreign call functions, allowing function calls into other modules, and remote foreign calls providing an advanced system for making remote procedure calls. This may seem like overkill to experienced Perl programmers (who might be thinking, "but there are CPAN modules for all of these things!"), the reason for this reproduction of many already existing and well-implemented functions is that one of Webmins requirements is to be as self-contained as possible. The practical and philosophical reasons for this are many: A self-contained system is easier for new users to install, a self-contained system can be made smaller than a group of tens or hundreds of Perl modules, and a self-contained system can be coherent because it is all written for a specific purpose. So, while it would have been possible to implement much of the web-lib by including many already implemented CPAN modules, it would have broken the promise of self-containment.
While I refer above to Webmin as being self-contained, this isn't strictly the case. There are at least a couple of cases where Jamie has opted to use existing modules. In all cases it is because the complexity of reimplementing the functionality for Webmin would be more work than maintaining self-containment is worth. Specifically, the Net::SSLeay module is used to provide SSL capability to the Webmin webserver, and the Authen::PAM module is used to support PAM passwords on systems that support PAM for authentication. These are the exceptions rather than the rule, but there is also no rule stating that your modules have to be self-contained. I regularly use CPAN for my modules, and I don't feel a trace of guilt.
Finally, the part that does the hard work and handles all of the complexity that is within a Unix system, is the modules. Each icon on the index pages of Webmin are windows into a different program or set of programs that will help you administer one part of the system. Because Webmin has the lofty goal of working directly with the text configuration files on the system, and the even more lofty goal of not interfering with other forms of administration, the modules themselves have to be quite smart about how they work with the configuration. The configuration file grammar varies wildly from one server or service to the next, making it impossible to share very much of the configuration file parsing and processing code between different modules. Thus, the modules are the key to Webmins real functionality. Without modules, Webmin is useless.