Skip to content

Instantly share code, notes, and snippets.

Why We No Longer Write Init Scripts

In early 2014, we started switching our in-house services from System V startup (the standard service startup mechanism on RHEL up to RHEL 6) to supervisord, and ceased writing new SysV init scripts. The technical rationale is a bit involved; the end result simplifies development and improves parity between production and development environments, while also being easier to manage and deploy. To explain how this works, let's back up a step and talk about classic Unix daemonization.

Unix Daemons the Old Way, and Why SysV Init Sucks

The classic Unix daemonization system has each daemon (service) started by a dedicated command, which sets up the daemon as a child of PID 1, and then exits. You can see this in practice: run nginx and note that NginX starts in the background, and then returns control of the terminal to your shell. To make this happen, the startup program has to do a very complicated series of system calls. From the systemd documentation:

  1. Close all o
. /usr/local/git/contrib/completion/git-completion.bash
. /usr/local/git/contrib/completion/git-prompt.sh
GIT_PS1_SHOWDIRTYSTATE=true
GIT_PS1_SHOWUNTRACKEDFILES=true
ps1_status() {
if [ $? -ne 0 ]; then
echo ":("
else
echo ":)"
commit f3d6bcc227f14770b3d72f094f5b00f3939a6d8f
Author: Owen Jacobson <owen.jacobson@grimoire.ca>
Date: Mon Apr 13 23:36:41 2015 -0400
Add a magic linebreak to build.gradle.
Removing this line break causes Gradle to believe that the `publications`
section is being applied _after_ the Bintray plugin accesses the publications.
As this is illegal, it fails the build:
/*
* Loads a class, convert the '.' to '/'.
*/
static jclass
LoadClass(JNIEnv *env, char *name)
{
char *buf = MemAlloc(strlen(name) + 1);
char *s = buf, *t = name, c;
jclass cls;
jlong start, end;
def all_subsets(*elements):
# ensure elements is indexable and contains only unique values
elements = list(set(elements))
# Each bit pattern in an n-bit bitfield corresponds to a unique subset
# of an n-element set. Iterate over all such bitfields where
# n = len(elements).
for permutation_bits in xrange(2**len(elements)):
indexes = [
i
class gitolite {
group { 'git':
ensure => present,
system => true,
}
user { 'git':
ensure => present,
system => true,
gid => git,
@ojacobson
ojacobson / gist:3767547
Created September 22, 2012 19:39
post-receive/post-update hook for Jenkins
#!/usr/bin/env python
import logging as l
import contextlib as c
import os
import sys
import subprocess as s
import urllib as u
import urllib2 as u2
@ojacobson
ojacobson / pom.xml
Created September 24, 2012 17:33
Bootstrap in Maven, draft 1
<plugin>
<groupId>org.lesscss</groupId>
<artifactId>lesscss-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
<!-- Asadmin setup targets -->
<target name="ant.asadmin" depends="ant.asadmin-port">
<!-- This relies on an obnoxious linked list of presetdef tasks to
conditionally pass the 'host' and 'port' options to asadmin if and
only if the associated properties are set in Ant. -->
<presetdef name="asadmin">
<asadmin.port />
</presetdef>
</target>
class gitolite {
group { 'git':
ensure => present,
system => true,
}
user { 'git':
ensure => present,
system => true,
gid => git,