Omnibus-ctl: What is it and what can it do for you?

Are you building software with Chef Omnibus? Do your packages need to run multiple runit services? Then Omnibus-ctl may be for you!

Omnibus-ctl is a massively useful tool you can use to run common commands in Chef Omnibus packages.

What is Chef Omnibus?

Chef Omnibus is a way to easily create full-stack installers for projects across a variety of platforms. A full-stack installer includes everything your customers need to install and configure in order to run your application.

For more information, check out this talk by Seth Chisamore and Christopher Maier called Eat the Whole Bowl: Building a Full-Stack Installer with Omnibus. If you like, you can also view just the slides here.

What is Omnibus-ctl?

Omnibus-ctl is a wrapper for several service commands which can be run on a server that has been configured with an Omnibus package (i.e. omnibus-supermarket). These commands are largely used to either query common runit services or to run Chef commands.

Installing Omnibus-ctl

Omnibus-ctl is usually built through the omnibus-software repo. You can pull this into an omnibus project of your own by requiring the omnibus-software gem in your project’s Gemfile. Check out how the omnibus-supermarket project does this.

Here are the steps to including Omnibus-ctl in your Omnibus project:

1) Include omnibus-software in your omnibus-project’s Gemfile
2) In your omnibus project, create a file config/software/#{project_name}-ctl.rb
3) In this file you just created, list omnibus-ctl as a dependency (omnibus-ctl is brought in as part of omnibus-software, but you still need to add it as a dependency).

config/software/#{project_name}-ctl.rb
dependency "omnibus-ctl"

4) In your build block, configure a file called something similar to #{install_dir}/bin/#{project.name}. Here, you will define the SVWAIT (the amount of time to wait for a command to take effect, the default is 7 seconds), add some Ruby environment handling, and finally it calls the base omnibus-ctl command with a set of project specific arguments (the project name and the path to the extra commands) and then it passes on any arguments the user gave ($@).

Take a look at this example from omnibus-supermarket to see it in action.

Note that we call a template to define the file at the install_directory/bin/supermarket-ctl.

omnibus-supermarket/config/software/supermarket-ctl.rb

And here is the template, which defines ruby environment handling, SVWAIT, and more.

config/templates/supermarket-ctl/supermarket-ctl.erb

With these files in place, when the supermarket-omnibus package is installed we can run commands like “supermarket-ctl restart” to restart all services on the server.

Using Omnibus-ctl

Once Omnibus-ctl is included in the omnibus package and the package is installed, you now have a variety of commands at your disposal.

These commands include:

General Commands:
 cleanse
 Delete all supermarket data, and start from scratch.
 help
 Print this help message.
 reconfigure
 Reconfigure the application.
 show-config
 Show the configuration that would be generated by reconfigure.
 uninstall
 Kill all processes and uninstall the process supervisor (data will be preserved).
 Service Management Commands:
 graceful-kill
 Attempt a graceful stop, then SIGKILL the entire process group.
 hup
 Send the services a HUP.
 int
 Send the services an INT.
 kill
 Send the services a KILL.
 once
 Start the services if they are down. Do not restart them if they stop.
 restart
 Stop the services if they are running, then start them again.
 service-list
 List all the services (enabled services appear with a *.)
 start
 Start services if they are down, and restart them if they stop.
 status
 Show the status of all the services.
 stop
 Stop the services, and do not restart them.
 tail
 Watch the service logs of all enabled services.
 term
 Send the services a TERM.

You call one of these commands by prefixing it with #{project.name}-ctl. For example, to run the restart command from a server which has the omnibus-supermarket package installed, I would use:

$ supermarket-ctl restart

Extending Omnibus-ctl

Along with the included commands, you can also write and include your own ctl commands.

You create custom ctl subcommands using a lightweight DSL.

For examples, check out the install command from Chef Server or this test command from Omnibus Supermarket.

Generally, you include templates for your custom commands within a Chef recipe within your Omnibus package. The Chef recipe will take this template and make a file in the directory your specify. For example, take a look at this line from Omnibus Supermarket.

config/software/supermarket-ctl.rb

In Omnibus Supermarket, any custom commands are kept in omnibus-supermarket/cookbooks/omnibus-supermarket/files/default/ctl-commands. Our Chef recipes will take any template (such as the one at omnibus-supermarket/cookbooks/omnibus-supermarket/files/default/ctl-commands/test.rb) and use it to make a file and sync it in our install_directory/embedded/service/omnibus-ctl/ directory, which will make it available for use from the command line.

And that is an introduction to omnibus-ctl. Go forth and explore!

Avatar
Nell Shamrell-Harrington

Nell Shamrell-Harrington is a Principal Software Development Engineer and Community Engineering Lead at Chef. She is also a member of the Habitat core team. She specializes in Open Source, Chef, Ruby, Rails, Rust, Regular Expressions, and Test Driven Development and has traveled the world speaking on these topics. Prior to entering the world of software development, she studied and worked in the field of Theatre. The world of Theatre prepared her well for the dynamic world of creating software applications. In both, she strives to create a cohesive and extraordinary experience.