samedi 27 août 2005

From Cfengine to Python

The following thoughts were written in response to various posts from people wandering if Python is a good language for administering systems.

Cfengine experience


I tried Cfengine very seriously and for a long while, and the idea of a configuration engine seduced me. In a word, Cfengine is a wonderful concept, detailed into a very good set of ideas, especially well documented and explained. There are many good things about Cfengine. I gave it a real honest deep try.

While doing so, I duly reported a lot of problems to the author, as any good citizen would do, including some comprehensive patches. While interested at first, I felt the author got irritated a bit about many details I reported, which were often cosmetic in nature, and unrelated to the entrails of the engine, dismissing them as not important enough. Maintaining all these patches myself, from one Cfengine release to the next, was not really productive, despite I deemed it necessary.

How can I say that in a few words. I'm a bit anal. (I could spend hours revising all comments of a project to make them more consistent, renaming variables so they get more legible, or just ensuring whitespace is uniformly used.) When one uses Cfengine to administrate the hearth of dozens of machines, it has to be perfect, in and out, everywhere. I need that feeling of confidence. I do not believe, deep in my hearth, that someone is able to be lousy on so many unimportant details, and be dependably perfect when the time comes to be. In a word, despite Cfengine is a wonderful concept, the implementation lacked bit on the quality of details.

Switching to Perl


To make the history short, I progressively came to regret having used this Cfengine package, for its lack of maintainability. But as I was so dependent on Cfengine for a lot of administrative tasks, it was just not possible for me to dismiss it. After having suffered enough, I bit the bullet, rewrote those parts I needed in Perl, and dropped out of Cfengine for good. It took me one heavy week of work for doing this first transition.

My configuration setup was not written with publication in head, and I did not retain from Cfengine the things I did not use nor need. Moreover, since I wrote it for me, I was not shy to push many of my own habits in the code. What required the most attention, if I remember well, was proper sorting and merging of all requested actions for efficiency, for example, a single pass through the file system did it all. Another point was proper logging of actions (for debugging or otherwise), with due references to the controlling files: and this proved very useful. Speed was also very acceptable: such beasts are typically IO-bound, Cfengine IO optimizations were not that difficult to transpose into a scripting language.

For a while, I still read the bug reports about Cfengine, just for the satisfaction of enjoying all those I never suffered ☺. Oh, my Perl rewrite surely had its own problems. But at least, I could fight them as needed, and things were not to be pushed aside anymore as not being important enough.

Python rewrite


When I adopted Python instead of Perl for my day-to-day works, I rewrote all the configuration scripts from Perl to Python, and was surprised to observe the sudden increase in legibility (and so in maintainability), while it required so little effort. My Python was pretty Perlish at the time. This is only later that I revised many scripts to take better advantage of the object-oriented features of Python.

It was also easy to design all controlling files so they use Python syntax, and use Python itself as a configuration description language; this gave me a tremendous power and flexibility for almost free. The result was not significantly slower than Cfengine or Perl in practice, teaching me that Python interpretation overhead merely disappears in I/O bound contexts.
Over years, I got my configuration engine to take care of many things that would likely escape Cfengine capabilities, like firewall build-up automatically derived from (Python) descriptions of the network topology and distribution of services, easy fetching and deployment for various external tools we depend upon, and other such things, so the overall collection does not much look like Cfengine anymore.

All in all, I found that Python is a marvellous framework for automatic system-administrative tasks, and shaping this framework is not that difficult, even if it requires some work. For me, it was quite worth it. In these years, I do not do much real system administration anymore. But in the team I work in, the main system administrator, who saw my framework, understood that it was not that difficult to do, and prefers making his own (in Python, of course), at least as a way to make sure he understands everything inside out. And that's very OK! ☺

The Conf pseudo-project


Because a few people asked me to see my scripts, I once published them as the Conf pseudo-project. It was a set of Python tools, a bit random, a bit organised, which I use for various system administration duties. It was never meant as a formal (self-contained and usable) distribution, but more as vehicle to exchange ideas with people having similar concerns. But since this publication brought very little feedback, I withdrawn it after a while, keeping it in-house instead. Even if once fairly elaborate, I slowly and progressively dismantled it while taking distance from system administration. Nothing much remains of it nowadays, besides a few disjoint, special-purpose utility scripts. But I vividly remember that, whatever the approach, Python is a wonderful language for such duties.