I have a Python script that I'm executing using screen on an ubuntu host, and I want to turn that into a proper background service using a Chef recipe. The python script just starts up an SMTP server that discards all emails (a "black hole" server, useful for testing), and then calls python's asyncore.loop() to run forever.

How do I turn this into a chef recipe? I'm using the cookbook_file resource to upload my python script, and I know I need to use the service resource to start the service, but I'm not sure how to actually create the service to begin with. Do I need to write a file to /etc/init.d or /etc/systemd to create the service at the OS level, or is there some Chef recipe/resource I can call to create a background service for me, with a given command?

I'm using Chef 11.18.12 and can't upgrade, so that rules out some cookbooks (like runit) that require 12+. The host OS is Ubuntu 14.04.3.

Here's what I've got so far:

include_recipe 'apt'
include_recipe 'python'

# the python script to run as a background service    
cookbook_file '/usr/local/bin/smtp_server_blackhole.py' do
  source 'smtp_blackhole_server.py'
  owner 'root'
  group 'root'
  mode '0755'

# the init.d file which defines the service? Not sure about this part...
cookbook_file "init.d_smtp_server_blackhole" do
    path "/etc/init.d/smtp_server_blackhole.py"
    source "init.d_smtp_server_blackhole"
    owner "root"
    group "root"
    mode "0755"

service "smtp_blackhole_server.py" do
  # this doesn't work, because the command doesn't reference an existing service?
  start_command 'python /usr/local/bin/smtp_blackhole_server.py -c bounce'
  action [ :enable, :start ]

  # I think I need to do something like this, to wait for the init.d file to be written
  subscribes :restart, "cookbook_file[init.d_smtp_server_blackhole]", :immediately

Potential Solutions

  1. daemontools is a LWRP that allows you to create a service using a template file for the run command. However, it hasn't been updated in a couple of years, and it requires that you set up the svscan service for the "appropriate init system".
  2. This question has some good answers for how to write a Python daemon service using various code samples and Python libraries (e.g. python-daemon and daemonize), but it doesn't cover how to execute the OS commands in an idempotent way within a chef recipe.
  3. https://github.com/poise/poise-service looks like what I need, but it doesn't support Chef 11.18, since poise 2.0 requires chef 12+.

For Ubuntu 14.04 you would want to start with Upstart most likely since that's the system init framework. Check out the upstart Erb template in poise-service to see how to set things up or check out the Upstart Cookbook from Canonical. If you want to use something other than Upstary I would recommend Supervisord both for its simplicity and because it is popular in the Python community.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.