Iniscripts

Been trying out upstart today. It's a nice piece of code, but unfortunately it's totally useless today.

Not because its concepts suck; rather, because Debian packages today ship with SysV-style initscripts, and those do not integrate well with upstart: most of the features that make upstart so interesting require you to create an event.d script, which has a totally different syntax. The Debian Developer inside me couldn't help but start to think about a way to fix this, but that seems harder than what it initially would sound like to the uninitiated.

My first idea was to add some /sbin executable to upstart or one of its supporting packages, so that a SysV-style initscript could exit if that binary told it that upstart was running, before doing anything. That way, a package could ship both upstart event.d files and SysV-style initscripts during a migration period, and we could get rid of the SysV-style initscripts when and if Debian eventually decides to migrate to upstar.

But when I sent that past #debian-devel, someone mentioned initng, which is yet a different init implementation. If this would work for upstart, it could also work for initng, and I don't think many packages would want to ship initscripts for three different init implementations. So scratch that.

My next idea was to generate initscripts, rather than have packages ship them. The amount of common code in our initscripts is huge, anyway, and it's not as if it's all that hard to write an initscript. The things an initscript needs to do are limited, anyway: start a daemon when requested, stop it, restart it, perhaps send it a SIGHUP if or when configuration updates have been performed, and provide some useful output on all that. In most cases, that's about it. So, I thought, why not create an RFC822-style file (analogously to other files in the debian/ directory of a debian source package) containing all the metadata on an initscript, and generate the correct style of initscript out of that? That should work, I thought. So I started writing a specification, and had a look at the initscript of one of my own packages, nbd-server. Which does this at some point (nonrelevant content cut out):

i=0
while [ ! -z ${NBD_FILE[$i]} ]
do
  start-stop-daemon --start --quiet --exec /bin/nbd-server (...)
  echo -n " ${NBD_FILE[$i]} ]
  i=$(( $i + 1 ))
done

There's no way you'll be able to express that type of flexibility with an RFC822-style file containing all the metadata. So, scratch that too.

I still do think generating initscripts is the right thing to do, however; the question that remains is "how". One idea I had was to use m4 in an autoconf kind of way, since autoconf allows one to mix autoconf macros with "regular" shell snippets, which would be exactly the kind of flexibility that one would need. However, that totally ignores the fact that autoconf is only able to pull this off because its output is shellscript in every case. An m4 macro that has to produce output which are not, in fact, shellscripts (such as would be the case for this project) could not do that.

I think I'm kinda stuck now...