Skip to content
Dave edited this page May 21, 2022 · 21 revisions

You can copy the contents of a Gitea repository to a directory on a host by setting up a Gitea webhook like this: http://destination.host:1706/rsync?dest=%2Fsrv%2Fwww

Here's what happens on the host where Tea Runner is running:

  1. The Gitea repository is cloned into a temporary directory.
  2. The contents of the temporary directory (minus the .git subdirectory) are copied to the path given in the dest parameter (/srv/www in the example.)

Here are a few things to keep in mind:

  • The directory for the dest parameter must exist. Taking the example above, /srv/www must exist.
  • You must have the destination directory (or parent directory) bind mounted to the Tea Runner container. See the sample compose.yml for hints.
  • Omitting the dest parameter is the same as specifying dest=repo-name where repo-name is the Gitea repository that triggere the action. This is most useful in combination with RSYNC_ROOT specified in config.ini (see below.)

Security Considerations

If you're looking at the dest parameter and screaming, "but that's unsanitized user input!" congratulations, you passed web security 101. So how do you deal with this risk?

  1. Use the containerized version of Tea Runner and only bind mount the paths you need. For example, if you're planning to rsync web content, only bind mount /srv/www.
  2. Use the RSYNC_ROOT option in Tea Runner's config.ini.
  3. Do both.

Consider the config.ini example below. This will prepend /srv to any path specified with the dest parameter.

[rsync]
RSYNC_ROOT=/srv

Neat, right? "RSYNC_ROOT for all!" you're shouting.

Well, there are some things to be aware of if you use RSYNC_ROOT to restrict directories where content can go.

  1. The value of RSYNC_ROOT is prepended to any path specified with the dest parameter (or the implied dest of the repo-name.)
  2. The dest parameter is restricted to a single subdirectory level.
  3. The dest parameter will be mangled if it contains unsafe characters. (See werkzeug.utils.secure_filename for more.)

Using RSYNC_ROOT

Here's an example with the /srv/www destination used previously.

First, you add an entry in Tea Runner's config.ini to specify RSYNC_ROOT. The section you need to add looks like this:

[rsync]
RSYNC_ROOT=/srv

Now that this is in place, you need to adjust any Gitea webhooks that used dest=/srv/www and remove the parent directory of /srv. In other words...

This:

http://destination.host:1706/rsync?dest=%2Fsrv%2Fwww

Becomes this:

http://destination.host:1706/rsync?dest=www

Or even this (if the repo is named www):

http://destination.host:1706/rsync

Serendipity! Not only does using RSYNC_ROOT help mitigate the problem of unsanitized input, it also makes the webhook URL a whole lot prettier.

One Caveat

So what happens if you want to use RSYNC_ROOT with dest= and a multi-level subdirectory? For example, dest=%2Fwww%2Ftest You might be hoping to see your repository files in /srv/www/test, but that's not what you'll get. Instead you'll see a new directory of /srv/www_test with very restricted permissions.

This www_test name is because of how werkzeug.utils.secure_filename() creates a filename to thwart malicious intent. To prevent a crafty person from doing something like dest=../etc/passwd or similar, any forward slashes get converted to underscores. So while it helps keep you safe, it also limits you to a single subdirectory destination.

The restrictive permissions are the result of rsync creating the subdirectory that does not already exist.

Example webhooks

Clone this wiki locally