Running Taskotron Tasks

This document will describe how to run Taskotron tasks locally using runtask (the Taskotron runner), or even directly using ansible-playbook.

Installing Taskotron runner

Refer to the quick start guide for the basics.

libtaskotron modules

As functionality has been added to libtaskotron, we’ve started breaking up that functionality into modules to increase flexibility and shrink the minimal install profile. Each module is packaged separately for easy installation.

libtaskotron is composed of 3 modules - libtaskotron-core, libtaskotron-fedora and libtaskotron-disposable.

The minimum needed to run tasks with libtaskotron. It consists of the most basic bits that most tasks will use, and the runner.
The fedora-specific functionality which is in libtaskotron - things like bodhi, koji and rpm-based directives.
The bits needed to enable execution with Disposable VMs. Local-only execution is still possible without this module. Note that libtaskotron-disposable depends on testcloud which will pull in several other non-trivial dependencies.

Running tasks

Local execution

Refer to the quick start guide for the basics.

Using remote machines

While the default execution path will run tasks on a local machine, it is also possible to delegate task execution to a remote machine or spawn a disposable virtual machine for task execution. This is useful when you want to execute runtask on your production machine, but of course don’t want to execute the tasks running as root on the same machine.


The remote connection will be done through ansible, which means the target machine has to have sufficient environment for ansible scripts to run (typically a Python2 interpreter).

Pre-existing remote machines

To use an already-existing remote machine, use the --ssh <user>@<ip address>[:port] argument to runtask. This will signal the runner to connect to the indicated machine and execute tasks there instead of locally.


Since the tasks require root privileges, you either need to connect as root or have a password-less sudo configured for your account on that machine.

This connection method is mostly meant for task development so that there isn’t a constant overhead of starting and configuring disposable VMs.

Remote Execution Diagram

Disposable VMs

Libtaskotron can spawn a one-shot virtual machine for you, run the task on it, and tear the VM down. To do this, use --libvirt command line option. Note that the image available by default is very generic and this can add significantly to execution time.

The specific process is:

  1. Start execution
  2. Spawn VM using testcloud
  3. Execute the ansible playbook remotely on the spawned VM
  4. Copy over artifacts from VM to the local machine
  5. Destroy spawned VM

This connection method is useful when you want to run your task in an absolutely clean environment, very closely resembling the production environment. To use this method, you’ll need to configure testcloud first.

Disposable Execution Diagram

By default, a base image defined by the imageurl option in taskotron.yaml config file is used. You can provide your own base image by changing the imageurl value (use file:// URL to point to a local file).

If you store these images in /var/lib/taskotron/images, adhere to their naming conventions and set force_imageurl=False in taskotron.yaml, we will find the latest one available automatically for you and you don’t need to update the imageurl option regularly.

Setting up testcloud

Configure ssh key for testcloud to use (the private key must be passwordless). Edit ~/.config/testcloud/ or /etc/testcloud/ and insert the respective public key in the place of the $SSH PUBKEY HERE$ string:

USER_DATA = """#cloud-config
  - default
  - name: root
    password: %s
    chpasswd: { expire: False }

Direct execution using ansible-playbook

Since runtask is just a wrapper around slightly-extended tasks written according to the Standard Test Interface, it is possible to execute the task without utilizing the Taskotron runner. All you need is to supply sufficient variables to ansible-playbook when running the task.

The basic command to execute the task playbook looks like this:

ansible-playbook tests.yml

That itself doesn’t make much sense, because you haven’t told the task what to test. However, it might still work for some tasks, if they have hardcoded a default value to use as an example. That is e.g. the case of task-rpmlint, which will test an example NVR.

For a more reasonable execution, you’ll need to override at least taskotron_item variable, like this:

ansible-playbook tests.yml -e taskotron_item=<ITEM>

where <ITEM> is the subject of the test, e.g. Koji NVR, etc, depending on the task.

It is likely that some tasks will crash with undefined variables until you define all variables that they need (i.e. they don’t use some sane defaults for an easy local execution). As a rule of thumb, look into the task README whether there are instructions for an easy local execution (e.g. for development purposes). If there aren’t any, you’ll either need to study the playbook to see what is needed, or you’ll need to define all variables that Taskotron defines - see Variables provided by Taskotron.