Thursday, June 25, 2015

Ubuntu Upstart unkown job

First, let me express my affection for startup scripts.  The ability to run a shell script directly, modify its contents freely, use familiar tools and tactics for debugging -- it's the epitome of beauty in simplicity.  SysV Init is elegant, effective, and easy to use.

Obviously, Ubuntu just couldn't live with that, so they replaced it with the ever-complicated and uppity Upstart.  Yes, it can start my laptop up in 10 seconds instead of 15.  Yes, it's event-driven.  Yes, it uses fancy private sockets and DBUS infrastructure and uber secure architecture.  Yes, the syntax is mysterious and unfamiliar.  Yes, it's a royal pain in the butt.

An issue that has plagued me for many moons is this:

asmith@asmith-hp:~$ sudo restart ssh
restart: Unknown job: ssh
asmith@asmith-hp:~$ sudo restart vsftpd
restart: Unknown job: vsftpd
asmith@asmith-hp:~$ sudo restart tftpd-hpa
restart: Unknown job: tftpd-hpa

Why can't I, the lowly, unprivileged user, manage ANY of my services?  Rather than find the service you're trying to control, initctl simply tells you your job doesn't exist.  After a bit of searching, I was gifted this answer.

asmith@asmith-hp:~$ man initctl

              Communication  with the init(8) daemon is normally performed over a private socket connection.  This has the advantage of speed and robustness, when issuing commands to start or stop services or even reboot the system you do not want to be affected by changes to the D-Bus system bus daemon.

              The disadvantage to using the private socket however is security, init(8) only permits the root user to communicate over this socket which means that read-only  commands such as status and list cannot be made by other users.

              The --system option instructs initctl to communicate via the D-Bus system bus rather than over the private socket.

              This  is  only  possible  if  the  system  bus  daemon is running and if init(8) is connected to it.  The advantage is that the default security configuration allows non-root users to use read-only commands.


In short, Upstart also manages services for the user session, which is kept separate from system service management.  When you run upstart management commands as a non-root user, it manages your user session services rather than the system services.  To manage those important system services, you must add "--system" to the command like so:

asmith@asmith-hp:~$ sudo restart --system ssh
ssh start/running, process 19645
asmith@asmith-hp:~$ sudo restart --system vsftpd
vsftpd start/running, process 19651
asmith@asmith-hp:~$ sudo restart --system tftpd-hpa
tftpd-hpa start/running

A note to Upstart developers: I'm a software engineer, too.  I'm probably about as lazy as you, and at times as unconcerned about the user experience as you are.  It's very easy to make things very difficult for the user.  If you train the user to do something a certain way, then change the way it's done, you MUST BE LOUD about it!  Switching from simple SysV scripts to Upstart was mean, but then changing the way Upstart works without helpful hints to the user was simply sadistic.

Do you think you could have at least searched for the requested service name over DBUS?  Heck, maybe only do that when the user is running the command via sudo, or some other way with root permissions.  Then, maybe you could emit a helpful message like this:

"warning: future versions will require you to use the '--system' argument to manage system-level services.  For example: restart --system ssh"

Other programs, like SSH, work like this.  I love SSH.  Even when SSH changes (like how the known keys are stored and managed), they will always look out for the little guy by giving hints and example commands that can simply be copied and pasted at the command line.

Upstart, may you turn from your secretive, pedantic, obscure ways and become one with those you serve.