Category Archives: python

Configuration Management Software Sucks

Yes.  Configuration Management Software Sucks.  Horribly.

The main problem is that n-th order tweakability is preferred over convention.  It’s just stupid.  There are a core set of things that just about everybody needs to do.  Those should be dead simple.  Ready to uncomment and run.  The set operating systems used in the enterprise is fairly small:  RHEL5, RHEL6, Debian 6, Ubuntu LTS.  A configuration system should be opinionated and have complete out of the box support for these platforms.  Simple rulesets for the basics that nearly everyone uses should be ready to go..  package management, process initialization, file management, ssh, sudo, DNS, Apache, PAM, PostgreSQL, MySQL, OpenLDAP, etc.  Keep it simple.  Keep it simple.  Keep it simple.  Resist all urges to add complexity.

That’s not the case.

You’d think after 30 years of Unix, BSD and Linux network deployments this would be pretty well trodden ground.  Wrong.  It’s a complete crapshoot and everybody does things differently.  Pick your poisons and reinvent the stack ad infinitum.

This is one of the few areas I’m green with envy of the Microsoft side of the fence.  Between Active Directory, Group Policy,  and maybe a third party tool or two for cloning and installs and such, Microsoft environments can easily be set up and managed well by complete morons (and often are).

Puppet

Puppet seems to have potential.  Of course, out of the box you’re pissing in the wind with a blank slate and most books and sites will have you following tutorials to rewrite rulesets that thousands of other people before you have similarly cobbled poorly together.  As a Ruby project, it unsurprisingly has vocal hipster fanboys.  Unfortunately, they forgot to parrot their DRY principle to each other.

It centers around a domain specific convention which isn’t so bad..  but in no time flat you’ll start seeing full blown Ruby programs intermingled.  Ugh.  But it’s not so bad if you stick to the basics.

If you look around you can find reasonably complete module sets, i.e. http://www.example42.com/.  It’s not all gravy as these are heavily interdependent and kludgy.  If you want a clean, simple solution you’re back to rolling your own with some healthy copy and paste.

Since it’s a Ruby project, aside from the annoying fanboys, you’re also going to run into scalability problems past a few hundred nodes.  There are mitigation strategies, but it’s a joke compared to something like Cfengine.

Due to hype, you’ll find decent versions in the Debian and Ubuntu backports repos.  RHEL 5 and 6 are covered by a Puppet Labs repo.  2.6 and 2.7 are therefore readily available and as long as your master is running the later version you shouldn’t have interop problems.

All things considered, Puppet is probably the best choice at the moment.  It sucks, but it’s got a lot of momentum behind it.  There are mountains of docs, books, and tutorials to get you going and nothing is too foreign or hard to grasp.

Cfengine 3

I really want to like Cfengine.  It’s incredibly light weight and hardcore ROFLscale.  It’s got serious theory behind it and older versions have been used in massive deployments.  But it’s not just a blank slate.  It’s even lower level and incomplete compared to the others.

You really need to add a promise library to get features that should be included by default.  These are all stagnate though, and still leave much to be desired.

There’s a company behind it doing something or another, but the open source version is raw.  If you have more than one Linux distribution, I’ll pretty much guarantee the packages are incompatible.

The repo choices aren’t great either.  Uncle Bob’s PPA on Ubuntu, out of luck on Debian.  RPMs in the EL repos look out of date.  You can of course get source and binaries from the Cfengine company, but it’s not my preferred way to install things and makes bootstrapping harder than it needs to be.

I haven’t tried the latest release, but quickly gave this one up when I found severe incompatibilities between point releases.  Madness.  You’d think people inventing something like promise theory could handle something as simple as version stability.

Ping me when a corporation backs Cfengine with a good promise library, some standard tasks, and repos for the common operating systems.

Bcfg2

Bcfg2 made the most sense to me out of the box.  XML is yucky and out of fashion these days, but Bcfg2 manages to use it acceptably.  Consequently, most things are declarative, easily read, and overall easy to mimic.  Beyond that, you can tap into some Python template and generator stuff.  But yes, these guys finally didn’t put n-th order above the common cases!  Installing packages and ensuring services are on is a snap.

They’ve got their own repos for many distros so installation isn’t bad.

The client and server are Python so you’ll have similar scaling problems to Puppet in large environments.

My biggest grievance with Bcfg2 is that the server needs intimate knowledge of each operating system version’s package repos.  You’ll fumble around writing a good bit of XML definitions for this in a heterogeneous environment.

The main thing Bcfg2 is lacking right now is community momentum.  Including repo definitions by default and some  more doc work.. I think this would be a great system for small to medium deployments.

Conclusions

The lot of this stuff is really terrible.  End to end system management under *nix is a major pain point.  On top of this, you’ll need a fairly free form monitoring framework (these also all suck) and directory service.  Mix and match an impossible array of projects and eventually you’ll find your own recipe that sort of works.  Except everyone does it differently so you’ll constantly be learning and redoing the same things over and over anyway.

It’s not fun.  What we need is end to end integrated thinking.  This area is still ripe for picking.  Oh RedHat, where art thou?

Something good about every language I used in 2010

Inspired by Samuel Tardieu’s post, I want to do a year in review of all the languages I have used this year.  A lot of times we prima donna programmers complain about anything and everything. I really enjoyed the positive outlook of Samuel’s post and want to take note of my experiences with similar attitude.

Bread & Butter

  • Python – My language of choice for the year.  Whether prototyping, experimenting, developing a Facebook application, maintaining a test framework I wrote for my workplace, or implementing cryptographic algorithms for a security course, Python continued to serve me well.  Between a copy of “Python Essential Reference” and PyPI, I feel there are very few problems beyond my means thanks to the power of this beautiful language and its surrounding community.
  • Java – As a student, I pounded out many a line of Java throughout the wee hours of the morning in my capstone classes.  Java seems to be the New Age language of academia and I can speak it universally to my classmates and professors as a lingua franca.  I’ve noticed that my Java programs tend to structure themselves well without much effort thanks to the strong object influence forced by Java and expansive standard library and Collections classes.  Also used at two collegiate programming competitions which is an entirely different experience than normal software development where the large standard library again came in handy.

Good Progress

  • C – I launched a good sized networking project in C as my first big project in the language and contributed a number of portability fixes to the libevent project.  Fast to compile, fast at runtime, and full low level control, C is a great language for Unix Systems Programming.  I greatly expanded my knowledge of the POSIX interfaces this year and really enjoy programming at this level.  I’ve noticed that some principles from other higher order languages have rubbed off on my C style; namely, data hiding and well formed/adaptable interfaces (see the post right before this one).
  • C++ – Been putting this one off because of all the FUD and intimidation at the sheer size of it.  C++ is pretty much the Latin of our field and is used in everything from safety-critical Jet aircraft systems, to GUIs, to games, to JITs, to cutting edge research.  As some of the pundits say, C++ is the language for “Demanding Applications”.  If you consider Java as the Flight Engineer of a large aircraft, C++ is definitely in the Pilot seat.  You have full control and high visibility of what is going on, but if you aren’t careful you can crash and burn.  I’ve probably progressed to the advanced beginner stage where I can use it as a better C but haven’t endured the trials and tribulations of an expert in the art of C++, nor read important references like Scott Meyers’ “Effective C++” series.  I really like the power and efficiency of the STL and plan on knowing enough C++ to use it when called upon.

Breaking New Ground

  • VHDL – After a required Electrical Engineering course, I was exposed to the entirely different paradigm of programmable hardware (FPGAs).  This was an eye opening experience.  Fundamentally, digital design is concurrent.  There may be valuable lessons here for both academic and professional Computer Science and I need to explore more here.  In 2011, I’d like to buy my own FPGA development board and work through the design of a simple CPU to gain further appreciation of hardware and VHDL or Verilog.

Back Burner

  • PHP – The first language I seriously learned and used some 12 years ago (I dabbled in Perl before that at the ripe age of 8, and probably Lego Logo a year before that :-P ).  I’ve been keeping an eye on it and it seems some of the Framework movement that stole a lot of developers away to other languages has sprouted mature analogues in PHP land.  No longer just C for the web, PHP 5.3 continues the lineage of the 5-series as a serious object-oriented language for web development that is basically universally available and dead simple to scale.  The extent of my PHP coding in 2010 was limited to maintaining some programs I’d written in years past (aside from merely installing/using PHP products like this blog).

On to 2011

  • D – D2 has me really excited.  For some intents and purposes, it seems like an evolution of C++ with a healthy removal of backward compatibility.  Embracing fast compile times, integrating concurrency and message passing, allowing easy interfacing to C libraries, and more mean this is a language capable of “Demanding Applications”.  Perhaps most intriguing is the use of the language proper for metaprogramming and compile-time programs.  I have Andrei Alexandrescu’s book on my shelf and have thumbed through it a few times.  The fact that he is involved speak volumes of D’s potential and his book looks superbly written. 2011 means working my way through the book and working on at least one sizable project in D.
  • Erlang – Erlang has been on my radar for a couple years now.  The fact that the OTP has roots in the demanding and critical realm of telecom means this is a serious language and seems to deliver interesting take on concurrency.  Erlang has already proven itself effective for XMPP servers and Message Queues.  This may yet be one of the best languages around for scalable networking applications and I’d like to get some hands on experience with it in 2011.
  • Haskell – I don’t know much about Haskell other than playing around with TryHaskell.  What I do know is that Haskell has a fairly mature Software Transactional Memory and that alone interests me.  I’ve also heard the optimizing compiler is pretty good.  Through investigation is due in the second half of the year.

But First, Write No Code

Something I see often in person and online are programmers constantly implementing common solutions, reinventing wheels, or embracing NIH.

Before you do this, please consider the Kev009’s Oath“But First, Write No Code”.  This is a solution to a variety of problems in software development, but today’s article is specifically on using external code.

I’ve found that programmers who follow a system similar to mine (detailed below) develop systems that are more stable, maintainable, and sane.  They likely write better code because it means they understand their tools and also read others’ code.  They examine the problem first rather than going in guns blazing.

Steps to decide whether to use an existing solution or write your own implementation:

  1. Scan the area. Google, Freshmeat, SourceForge, standard library, OS libraries, etc. are your friend.  See if the problem you are trying to solve has been solved.  I don’t care how long you’ve been programming or how much you think you know. The ecosystem of a language is constantly changing.Make a list of hits that look similar to the problem you are trying to solve.  Try and get a quick sense of the idiomatic methods of using your language, OS, etc.
  2. Do research. Are the solutions you found in step 1 suitable to the problem at hand?  Consider the pros and cons of each item.  Now, carefully evaluate how idiomatic the items are to your language and environment.If the item is open source, does the community seem active?  If it doesn’t fully map to your problem, does it look like you can modify it to do so?

    Even if you end up developing a solution from scratch, you should at least now have some good references.  Keep in mind, extending an existing project may be considerably less work.  You might even be able to offload maintenance of that component.

  3. Consider the license. This isn’t just for the legal department.  What kind of project you are working on will weigh in heavily.  Commercial or open source?  As a software professional, you need to be abreast with the various licenses in the wild.  As an open source developer, you need to consider how licenses will affect your work being packaged by distributions.An open source library licensed under the GPL is not acceptable for static linking to commercial software.  However, you can link to an operating system provided copy or bundle the dynamic library with your application.  LGPL does not have this restriction.  With both of these, you must supply your changes upon request from end users among other things.

    BSD, MIT, and Apache style licenses allow you to make changes and redistribute under completely different licenses.  Some just want credit in your documentation.  These are very compelling even in commercial development.

    Commercial components may have a per-copy fee associated which may dissuade their use by your organization.  If you don’t get the source, you won’t be able to effectively change or maintain it so you will also be at mercy of that developer.

  4. Make a decision. By now, your list should have been pared down based on licenses and research.  Perform extensive evaluations of the remainder and eventually hone in on the one you think fits best.  You’re going to have to rely on your experience and intuition while making the critical decision.  Perhaps the hardest part:  weighing it against a mythical home-grown solution in your mind.
  5. Implement the decision. Self explanatory.  This either means bootstrapping your own project or fully integrating the external one.  If you are extending an open source solution, consider submitting the patches back to the community for feedback and perhaps integration.  If you are bootstrapping your own solution, you’ve got your work cut out.  Is this only suitable for an internal project, or perhaps it would have its own merit as a new open source project?Be sure to reevaluate early and often.  That library you chose might turn out to be a can of worms, just as the “easy” new solution you had in your head might require years of development.
  6. Subscribe to the announce mailing list. Only if you used an external solution. Does the project have an RSS feed for releases or a low volume announcement list?  Don’t be like Adobe.  Avoid embarrassing security problems.  Also consider how enhancements and bug fixes to the external project might make your own project better, more stable, and more efficient.  This is where the real lasting dividends of using an external solution come from.

This list is widely applicable.  You’ve got a seriously high bar to reach if you are developing containers of <T>, sorting methods, GUI frameworks, parsers, text and binary file formats, and much more so try and follow it the next time you code.