Skip to content

Configuring ob2

Roger Chen edited this page Jan 25, 2016 · 5 revisions

This article introduces ob2’s configuration system. If you just want to see an example, check out the example ob2 config, and start from there instead.

Octobear 2’s configuration system

There are 2 parts of ob2’s configuration:

  • config.yaml contains key-value pairs for configuring most of the important features in ob2. Values can be null, integers, strings, lists, or dictionaries (any type supported by YAML). The default values for these key-value pairs are shipped with ob2.
  • functions.py contains arbitrary Python code. This file is executed after ob2 has loaded. It allows you to add hooks to change the behavior of ob2.

A config directory contains these two files, config.yaml and functions.py, along with any other files you want to add. You can specify a list of config directories, in order to override defaults. For example, your list of config directories might contain:

  • The defaults shipped with ob2 (these are always enabled)
  • A config directory for your course, which defines your course's assignments and policies.
  • A config directory specifically for local development or specifically for production use, which defines web server settings and security keys.

Getting started

You should create a new Git repository to store your ob2 config, or just make a new directory in an existing repository. Create two new files in it:

config.yaml

---
# My first ob2 config

course_name: "CS162: Operating Systems"
course_number: "CS162"

functions.py

import logging

logging.info("My first ob2 config")

Running ob2 with config directories

Config directories will be loaded in the following order:

  1. The default config directory that ships with ob2 is loaded (unless you delete it).
  2. The environment variable OB2_CONFIG_PATHS is used to find more config directories. Multiple directories can be separated with a colon.
  3. Any config directories specified by the command line arguments are loaded. You can specify config directories by adding --config DIR or -C DIR to ob2.

For now, I suggest you use option 3 and run ob2 with a config directory specified on the command line:

python -m ob2 --config ~/your_config_dir/

If everything worked correctly, ob2 should tell you that it loaded your config directory:

I[2016-01-07 14:32:39,750][ob2.config] Loading configuration from '/home/vagrant/src/config'
I[2016-01-07 14:32:39,765][ob2.config]   -> config.yaml loaded
I[2016-01-07 14:32:39,766][ob2.config]   -> functions.py loaded
I[2016-01-07 14:32:39,767][ob2.config] Loading configuration from '/home/vagrant/your_config_dir'
I[2016-01-07 14:32:39,811][ob2.config]   -> config.yaml loaded
I[2016-01-07 14:32:39,812][ob2.config]   -> functions.py loaded
I[2016-01-07 14:32:40,218][root] Hello world!
I[2016-01-07 14:32:40,219][root] My first ob2 config

Next steps

You should look at all the key value pairs in the default config.yaml, and override the ones that you want to change. You should also:

Paths in config.yaml

If a key ends in _path, then ob2 assumes that it refers to a filesystem path. You can use relative paths and ob2 will resolve them relative to the config directory. For example, if your config directory looks like:

/my_config_dir/
/my_config_dir/config.yaml
/my_config_dir/functions.py
/my_config_dir/inst_account_forms/
/my_config_dir/inst_account_forms/aa.pdf
/my_config_dir/inst_account_forms/ab.pdf
/my_config_dir/inst_account_forms/ac.pdf

Then, you can specify the path of the instructional account forms like this:

inst_account_forms_path: "inst_account_forms/"

Advanced uses of config.yaml

Key-value pairs in config.yaml will override previous values. If you do not specify a value, then the default will be used. If you are configuring a key-value pair where the value is a list, then you can also tell ob2 to append to that list.

Appending to a list

# This overrides the previous value
github_ta_usernames:
- rogerhub

# This appends "rogerhub" to the previous value
github_ta_usernames_APPEND:
- rogerhub

In a similar fashion, you can also update a dictionary instead of overriding it.

Updating a dictionary

# This overrides the previous value
group_ta_assignments:
  group42: Roger

# This updates 1 key in the previous value
group_ta_assignments_UPDATE:
  group42: Roger

Hooks

The main purpose of the functions.py file is to allow you to register hooks with ob2, before it starts running. Hooks are callback functions that change the behavior of ob2. There are 4 types of hooks in ob2:

  • action - When a certain event occurs, your function is called (possibly with some arguments related to the event).
  • filter - Your function is used to change the value of a variable, in a way similar to value = f(value). Sometimes, extra arguments are passed to your function to give you more context. You can choose to return the original value, you can choose to call functions on the value before returning it, or you can choose to return an entirely different value.
  • partial - Allows you to insert arbitrary HTML into web templates. This lets you customize your web interface, so you can insert text relevant to your course.
  • job - (This is the most important type of hook.) Defines a function for grading assignments. A job function always receives two arguments (repository and commit hash) and always returns a 2-tuple (build log and score).

Clone this wiki locally