✺ articles.inqk.net

Usually more extended thoughts by Michael Camilleri.

Read how to use this blog.

TLDR

An introduction to the Tenter gem.

Introducing Tenter

I pushed out a gem over the weekend called Tenter. You might be interested in it.

What is Tenter?

Tenter is a Sinatra-based web application that runs user-defined commands in response to HTTP requests. It provides a simple way of creating webhooks that can be called by GitHub in response to events in a repository.

A ‘webhook’ is a URL that you can configure GitHub to send a request to when certain events happen in your repository. Receiving a pushed commit is an example of an ‘event’.

Why Does Tenter Exist?

Tenter is meant as an alternative to deployment systems like Capistrano. Those have their place but are ridiculously heavy if all you want to do is have your server perform an action after you do something with a repository.

The source files for this blog are all in a GitHub repo, for example. With Tenter, I can cause the server that hosts my blog to update its copy of the repo and rebuild itself whenever I push a change to GitHub.

How Does Tenter Work?

Tenter expects to receive HTTP requests to URLs of the form /run/<cmd>/in/<dir>. When it receives such a request, it first authenticates it. Tenter does this by looking up the secret in /var/www/<dir>/hooks.yaml and checking whether the signature in the X-Hub-Signature header has been validly created using the secret (GitHub generates this header automatically).

If the signature is valid, Tenter spawns a separate process to execute the file <cmd> in the /var/www/<dir>/commands/ directory and responds that the command has been initiated.1

If the signature isn’t valid, or if <cmd> or <dir> don’t exist, Tenter returns an error.

Is Tenter Configurable?

Tenter takes a convention over configuration approach. Out of the box, it will assume the directories it is watching are in /var/www/, that each directory’s secret is in hooks.yaml, that commands are in commands/ and so on.

The defaults are meant to cover most use cases but if you want to tweak things the defaults are all configurable. More information on this is available in the README.

How Do I Get Tenter?

Tenter is available as a gem from RubyGems. I hope you find it useful! ✺

  1. Tenter detaches the process after spawning. In other words, Tenter does not wait for the result of the command and does not guarantee successful execution. By default, Tenter logs the output of commands to /var/www/<dir>/log/commands.log.