![]() | ![]() |
|
Designing Integrated High Quality Linux ApplicationsCopyright © 2002 by Avi Alkalay v2.1, 2002-08-24
1. IntroductionLinux is becoming more and more popular, and many Software vendors are porting their products from other platformas. This document (article) tries to clarify some issues and give tips on how to create Linux applications highly integrated to the Operating System, security and easy of use. The examples run on Red Hat Linux, and should be compatible with other distributions based on Red Hat (Conectiva, Turbolinux, Caldera, PLD, Mandrake, etc). 2. User Friendly: Guaranteed SuccessThe user-friendly concept is missassociated with a good GUI (graphical user interface). In fact, it is much more than that. In systems like Linux (with more server-like characteristics), the user measures how easy a Software is, mainly in the installation and initial configuration. He can even forget how easy were to install and use a certain product, but it will never forget that a Software package has a complex configuration and installation process. A migration or new installation allways will be a nightmare, making the user avoid it. 2.1. Embrace the Install-and-Use ParadigmImagine you'll install that expansive product your company bought from ACME, and realized you'll have to do the following:
Sounds familiar? Who never faced this sad situation, that inducts the user to make mistakes? If your products' installation process sound like Uncompress-Copy-Configure-ConfigureMore-Use, like this one, you have a problem, and the user won't like it. Users like to feel that your Product integrates well with the OS. You should not demand that the OS adapt himself to your Product (changing environment variables, etc). It must let the user Install-and-Use. The Install-And-Use glory is easily achieved using a 3 ingredients receipt:
We'll discuss here what are these ingredients and how to implement them. 3. The Four Universal Parts of Any SoftwareThe file set of any Application Software, graphical, server-side, commercial, open/free, monolithic etc, has allways four universal parts: 1st :: The Software on its own: the bodyThe executables, libraries, static-data files, examples, manuals and documentation, etc. Regular users must have read-only access to these files. They are changed only when the system administrator makes an upgrade in this Software. 2nd :: Configuration Files: the soulThese are files that define how the Software will run, how to use the Content, security, performance etc. Without them, the Software on its own is usually useless. Depending on your Software, specific privileged users may change these files, to make the Software behave as they want. It is important to provide documentation about the configuration files. 3rd :: ContentIs what receives all the user attention. Is what the user delegated to be managed by your Product. Is what makes a user throw away your product and use the competitors', if it gets damaged. Are the tables of a database system, the documents for a text editor, the images and HTML pages of a web-server, the servlets and EJBs of an Application Server, etc. 4th :: Logs, Dumps etcServer Software use to generate access logs, trace files problem determination, temporary files etc. Other types of softwares also use this files, but it is less common. It is the last class of file, but many times they are the most problem generator for a system administrator, because their volume can surpass even the content size. Due this fact, it is important for you to think in some methodology or facility for this issue, while you are in design time. 3.1. Practical ExamplesLet's see how universal is this concept analyzing some types of softwares: Table 1. Universality of 4 Parts
Pay attention that the Software on its Own contains all your product business logic, which could be useless if you hadn't a Configuration to define how to work with a data bundle, provided by the user. So, Configurations are what connects your product to the user. We can use a metaphor about a Sculptor (business logic), that needs Bronze (content) and a Theme or Inspiration (configuration) from a Mecenas (user), to produce a beautiful work (content). He make annotations in his Journal (logs) about his day-by-day activities, to report to his Mecenas (user). 3.2. The Importance of Clear Separation Between Four PartsOK, so let's be more practical. The fact is, if we correctly use the universal parts concept, we greatly improve the quality of our Product. We'll do that simply separating, encapsulating, each one of these parts in different system directories (having only different files for each part is not sufficient). There is a standard called FHS that defines the Linux directories for each part, and we'll discuss it later in Section 4. By now let's see the value of this separation to the user:
Let's make some exercise with separation using as example a system called MySoftware, in which the business logic is in Example 1 and the configuration is in Example 2. Example 1. A Shell program referring an external configuration file Example 2. File containing only the configurations for MySoftware 3.3. One Body, Many SoulsWhen I was a system administrator for IBM e-business Hosting Services, I was fascinated by Apache's flexibility letting us do things like this:
If we don't pass any parameter (like the first example), Apache loads its default, hardcoded configuration file from /etc/httpd/conf/httpd.conf. We built other configs, one for each customer, with a completely different structure, IP address, loaded modules, content directory, passwords, domains, log strategy etc. This same concept is used by a text editor of a multiuser desktop (like Linux). When the code is loaded, it looks for a configuration file on the user's $HOME, and depending who invoked him (user A or B), it will appear differently because each user has its own personal configuration. The obvious conclusion is that the Software's body (business logic) is pure e completely oriented by his manipulator's spirit (configuration). But the competitive advantage lays on how easy we switch from one spirit to another, like in Apache's example. It is very healthy to promote it to your user. You'll be letting him create intimacy, reliability, confort with your Product. We used this approach with many different Softwares in that e-business Hosting time, and it was extremely usefull for maintenance etc. In a version migration we had total control over where were each of its parts, and upgraded and downgraded Software with no waste of time, with obvious success. But there were some Products that refused to work this way. They had so many hardcoded parameters, that we couldn't see what divided the body from their spirit (or other parts). These Softwares were marked as bad guys and discarded/replaced as soon as possible. We concluded that the good guys Softwares were intuitively blessed by their developer's four parts vision. And they made our life easyer. In fact, in that time we formulated this theory, that continues to prove itself. Do you want to deploy bad guy or good guy Software? 4. Linux Directory Hierarchy: Oriented to the Software PartsBy now, all discussion are OS independent. On Linux, the Four Software Parts theory is expressed in his directory structure, which is classified and documented in the Filesystem Hierarchy Standard. The FHS is part of the LSB (Linux Standard Base), which makes him a good thing because all the industry is moving thowards it, and is a constant preoccupation to all distributions. FHS defines in which directories each peace of Apache, Samba, Mozilla, KDE and your Software must go, and you don't have any other reason to not use it while thinking in developing your Software, but I'll give you some more:
This last reason already justifies FHS adoption, so allways use the FHS !!! More about FHS importance and sharing the same directory structure can be found in Red Hat website. 4.1. FHS SummarySo let's summarize what the FHS has to say about Linux directories: Linux system directories
You may think is a bad idea to break your Software (as a whole) in many pieces, instead of keeping it all under a self-contained directory. But a package system (RPM) has a database that manages it all for you in a very professional way, taking care of configuration files, directories etc. And if you spread your Software using the FHS, beyond the user friendliness, you'll bring an intuitive way to the sysadmin configure it, and work better with performance and security. 4.2. Examples Using the FHSNow that we know where each part of our software must be installed, lets review the Universal Parts Table applied to the FHS. Table 2. Same Software, applying FHS
4.3. Developer, Do Not Install in /opt or /usr/local !If you are a systems administrator, this section is not for you. This is a subject for developers and packagers, to make sysadmin's life easyer. The /opt and /usr/local directories are used by sysadmins to manualy non-packaged files (without RPM) of a software, precisely to not loose control over those files. Notice how separated this folder are from the rest of the system. A manual installation process (without RPM, or based on simple file copy) is documented in forgoten document inside a drawer (if it was documented), and inside the head of who made installation. If he moves to another job, that installations becomes obscure to the rest of the team, and is a time bomb. With RPM is different. RPM (or any other package system) is an installation "process" by itself. It is self-documented in his database and pre and post-install actions, which permits total control. Turns installations independent from who did it, turning installtions in a business process. Installations based on coping files into /opt or /usr/local are far from providing the organization, system visibility and control that RPM provides. I can say /opt and /usr/local would be obsoleted when all softwares become RPMized. It is very important to Linux evolution and popularization (especially in the desktop battlefield), that developers stop using this hell directories, and start using the FHS. After reading this section, if you still think this folders are good business, please drop me an e-mail. Products that are entirely installed under one directory, use the self-contained approach, that has several problems:
Many developers believe that the "self-contained" approach let them work with several versions of the same product, for testing purposes, or whatever. Yes, agree, with this or any good reason in the planet. But remember that a High Quality Software (or Commercial Grade Software) objective is to be practical for the final user, and not to be easy to their developers and testers. Invite yourself to visit an unexperienced user (but potential customer) and watch him installing your product. Developer, don't be afraid of spreading your files according to FHS because RPM will keep an eye on them. If you have a business reason to let the user work with several versions of your Product simultaneously (or any other reason), make a relocatable package, which is described in the Maximum RPM book. Be also aware about the implications of using this feature, described in the same book. Red Hat and derivated distributions allways use the directory standard, instead of /opt or /usr/local. Read what Red Hat says about this subject, and think about it.
5. Provide Architecture for Extensions and PluginsYou'll probably let other Software vendors plug extensions to your product. Since you are the author of the initial Software, is your responsability to organize it in such a way that the user can simply install the extension RPM and use it, without forcing him modify any configuration file. It is again the famous Install-and-Use that guarantees ease-of-use. Well, and extension is nothing more that some files in a right format (DLLs that implements the API your Software defined), put in the right folders (directories your Software looks for extensions). We can see many applications requesting the user to change configuration files to "declare" the presence of a new plugin. This is a bad approach that must be avoided because makes user's or plugin provider's life harder. The most important thing to consider in your plugin architecture is to not share files between plugins and your Software. You should provide an architecture where plugins will be able to fully install and uninstall themselves by simply putting and removing files in specific directories, documented in you Software. Good candidates are /usr/lib/myproduct/plugins as the plugins directory, and /etc/myproduct/plugins as the plugins configuration files directory. Your Software and plugins must be sufficient intelligent to know how to find files, specially configurations, in these directories. Using this approach, no post-install procedures is required from the user, and from the plugin provider. 5.1. Abstracting About PluginsI would like to close this subject inviting the reader a se abstratir and think about any Software can be treated as an extension to the lower level Software. In the same way a third party plugin is an extension to your Software, your Software is also an extension to the OS (lower level). This is where all the Integration (from the title of this document) magic lives. So we can apply all the ease-of-use concepts we discussed before to the plugin architecture design of your Software. 6. Allways Provide RPM Packages of Your SoftwaresThis is extremely important for many reasons:
But a good package is not only put together your files in a RPM. FHS must be followed, configuration and documentation files must be marked as is, and pre- and post-install scripts must be robust, to not let them damage the system (remember that installation processes is done by root). Know well RPM because it can bring much power and facilities to you and your user. There are a lot of documentation available about RPM on the Internet:
6.1. Software Package ModularizationYou should give user the option to install only the part of your Software he wants. Imagine your Software has a client part and a server part, and both use files and libraries in common. You should break them in 3 RPMs. For instance, lets say the name of your product is MyDB, so you'll provide the packages:
and last 2 packages depends on the first. If the user is installing a client profile, he will use:
If he is installing a server profile:
This approach will help the user save disk space, and be aware of how your Software is organized. 7. Security: The Omnipresent ConceptFrom a very general perspective, security is synonym of order, conscience. And insecure is everything that makes a system stop without the user wish. So besides open network ports, or weak cryptography (that are beyond the scope of this document), applications that inducts the user to use it only as root, or make him change files in inappropriate places, is considered insecure. We can say the same for the apps that fills a filesystem that is vital to the OS. Many standards appeared from good practices discussed and developed in conjunction for a long time. So you should know and use them when you'll package your software, because they are key for you to achieve a good organization (security) level. 8. Graphical User InterfaceEverybody loves graphical interfaces. Many times they make our life easyer, and this way helps to popularize a Software, because the learning curve get smaller. But for the everyday use, a command with many options and a good manual becomes much more practical, making scripts easy, remote access, etc. So the suggestion is, whenever is possible, to provide both interfaces: graphical for the beginners, and the powerfull command line for the expert. 8.1. KDE, GNOME, Java or Motif?Better then a simple graphical interface is a consistent integrated desktop. So developer, please do not reinvent the wheel using proprietary libraries. Today's Linux desktop is full-featured, complete APIs that makes your life easier. The desktops today in Linuxland are KDE and GNOME. Try to allways use one of them, or both. KDE is the most outstanding, offering a true consistent desktop, flexible, with an extremely elegant architecture, using components (like Microsoft's COM and COM+), intercommunication, performance etc. It is constantly evolving, and is developed in C++. Its applications have an familiar integrated look-and-feel, is light and mature. People say that KDE 3 is shiny diamond, ready to be used, and is my first suggestion to you. GNOME also brings the integrated desktop proposal, but it is far from the maturity and ease-of-use of KDE. From the other side, is very well supported by the comunity, and good improvements are appearing. Motif isn't an integrated desktop. It is a widgets library (button, scrollbar etc), plus a window-manager. It was born commercial, is mature and popular in commercial applications. But is considered obsolete in front of KDE and GNOME, that integrates the desktop. Motif source code was opened by the OpenGroup and because that was renamed to OpenMotif. Java is being used more and more for graphical interfaces, specially in server Software, where the graphics are only helpers to configuration and administration. 8.2. Web Interface: Access from AnywhereNowadays every desktop has a browser, and if your Product is a server application, the Web Interface is the right choice, because it lets a user administer it from anywhere. But keep in mind the security and organization of your CGIs, because they use to be front doors for crackers. Web interface (CGI) is completely different programming paradigm. Try to understand it conceptually first, starting from "how a web-server works", "what is a URL", etc, to get on this without compromising your Product's security. 8.3. Wizards and Graphical InstallersSpecially for a commercial Product, your Software must provide a graphical installer. Believe me, they are impressive in a demonstration, and CIOs love them. More then just installation, a wizard helps in the initial configuration of your Product, collects info like activation key etc, and shows the developer license. A wizard should not do more than this:
So the wizard hides the RPM installation and writes initial personalization. RPM is still responsable for putting all your software files in the correct places. This role should never be of your installer. Think that an experienced user (there are a lot of them in the Linux world) should be able to reproduce your Product installation without the graphical help, using only RPM commands. In fact, in big data centers, where people make mass installations, a graphical installer only disturbs. RPM provides tools that help your graphical installer interact with them, like installation percentage viewer. Documentation for use are allways in the RPM manual (man rpm) and in the Maximum RPM book. 9. Starting Your Software Automatically on BootThe way Linux starts (and stops) all its subsystems is very simple and modular. Lets you define initialization order, runlevels etc 9.1. From BIOS to SubsystemsLets review what happens when we boot Linux:
9.2. RunlevelsThe runlevels mechanism lets Linux initialize itself in different ways. And also lets us change from one profile (runlevel) to another without rebooting. The default runlevel is defined in /etc/inittab with a line like this: Example 3. Default runlevel (3, in this case) line in /etc/inittab
Runlevels are numbers from 0 to 6 and each one of them is used following this standard:
You can switch from one runlevel to another using the telinit command. And you can see the current runlevel and the last one with the runlevel command. See bellow how we switched from runlevel 3 to 5.
9.3. The SubsystemsSubsystems examples are a web-server, data base server, OS network layer etc. We'll not consider a user oriented application (like a text editor) as a subsystem. Linux provides an elegant and modular way to organize the subsystems initialization. An important fact to think is about subsystems interdependencies. For instance, it makes no sense to start a web-server before basic networking subsystem is active. Subsystems are organized under the /etc/init.d and /etc/rc.d/rcN.d directories:
So to make your Software start automatically in the boot process, it must be a subsystem, and we'll see how to do it in the following section. 9.4. Turning Your Software Into a SubsystemYour Software's files will spread across the filesystems, but you'll want to provide a simple and consistent interface to let the user at least start and stop it. Subsystems architecture promotes this ease-of-use, also providing a way (non obrigatoria) to be automatically started on system initialization. You just have to create your /etc/init.d script following a standard to make it functional. Example 6. Skeleton of a Subsystem control program in /etc/init.d
The mysystem subsystem methods you implemented will be called by users with the service command like this example: Example 7. service command usage
You don't have to worry about managing the symbolic links in /etc/rc.d/rcN.d. The chkconfig command makes it for you, based on the control comments defined in the beginning of your script. Example 8. Using the chkconfig command
Read the chkconfig manual page to see what more it can do for you. 9.5. Packaging Your Boot ScriptWhen you'll create the RPM, put your Subsystem script in /etc/init.d and do not include any /etc/rc.d/rcN.d link, because it is a user decision to make your subsystem automatic or not. If you include them and the user makes any change, the RPM file inventory will become inconsistent. The symbolic links must be created and removed dynamically by the post-installation and pre-uninstallation process of your package, using the chkconfig command. This approach guarantees 100% package and filesystem consistency. A. Red Hat, About the Filesystem StructureThis text was taken from The Official Red Hat Linux Reference Guide Why Share a Common Structure?An operating system's filesystem structure is its most basic level of organization. Almost all of the ways an operating system interacts with its users, applications, and security model are dependent upon the way it stores its files on a primary storage device (normally a hard disk drive). It is crucial for a variety of reasons that users, as well as programs at the time of installation and beyond, be able to refer to a common guideline to know where to read and write their binary, configuration, log, and other necessary files. A filesystem can be seen in terms of two different logical categories of files:
Shareable files are those that can be accessed by various hosts; unsharable files are not available to any other hosts. Variable files can change at any time without system administrator intervention (whether active or passive); static files, such as documentation and binaries, do not change without an action from the system administrator or an agent that the system administrator has placed in motion to accomplish that task. The reason for looking at files in this way has to do with the type of permissions given to the directory that holds them. The way in which the operating system and its users need to utilize the files determines the directory where those files should be placed, whether the directory is mounted read-only or read-write, and the level of access allowed on each file. The top level of this organization (/ directory)is crucial, as the access to the underlying directories can be restricted or security problems may manifest themselves if the top level is left disorganized (security=organization) or without a widely-utilized structure. However, simply having a structure does not mean very much unless it is a standard. Competing structures can actually cause more problems than they fix. Because of this, Red Hat has chosen the most widely-used filesystem structure and extended it only slightly to accommodate special files used within Red Hat Linux. B. About this DocumentThis document must be distributed under the terms of GNU Free Documentation License, which makes him sufficiently free. Everybody in invited to contribute to his content and ideas. Copyright 2002, Avi Alkalay. This document is published in the following locations:
It was written originally in brazilian portuguese, and then translated to english. SGML and the more-then-incredible DocBook was used, that made possible this document being distributed in other formats, found in website. It got ready (potuguese+english) in mid march 2002. Everything changed after this epoch is cosmetics. I wrote it to help commercial companies and OpenSource developers make plug-and-play, easy-to-use software for Linux, and this way improve Linux usability and popularity. All concepts (from a high level perspective) described here, can be used in any UNIX flavor, or even other OS, like Windows. Maybe some day I'll write one of these for Windows....or Mac.... |