Skip to content
This repository has been archived by the owner on Jun 4, 2021. It is now read-only.

Writing Tasks

smcclellan edited this page May 18, 2015 · 7 revisions

Tasks are structurally very simple: they consist of a (YAML) metadata file, and any number of templates. Once you have automated the install for your operating system, for example, via kickstart or preseed, turning that into a task is a simple exercise in writing a bit of metadata and templating some of the things that your task does. Have a look at the stock tasks that ship with Razor to see some examples.

Tasks can either be stored in the file system or in the database. To get started, and especially while you are developing a task, you should only use tasks stored in the file system. The configuration setting task_path determines where in the file system Razor looks for tasks and can be a colon-separated list of paths. Relative paths in that list are taken to be relative to the toplevel Razor directory. For example, setting task_path to /usr/local/razor/tasks:/home/me/task:tasks will make Razor search these three directories in that order for tasks.

Task folder

Each task is encapsulated inside a folder called NAME.task where NAME is the task name. Inside this folder exist the metadata file and the templates.

Task metadata

The following metadata entries can be in a task's YAML file, which must be called metadata.yaml and reside in folder NAME.task.

---
description: HUMAN READABLE DESCRIPTION
os: OS NAME
os_version: OS_VERSION_NUMBER
base: TASK_NAME
boot_sequence:
  1: boot_templ1
  2: boot_templ2
  default: boot_local

Only os_version and boot_sequence must be provided. base allows deriving one task from another, by reusing some of its metadata and templates. Entries in the derived task's metadata override those in the base task's.

The boot_sequence hash indicates which templates to use when a node using this task boots: in the example, a node will first boot using boot_templ1, then using boot_templ2, and on every boot afterwards using boot_local.

Writing templates

Templates are ERB templates and are searched in all the directories given in the task_path configuration setting, in the directories name.task and common (in this order). If the task has a base task, the base task's template directory is searched just before the common directory.

Templates can use the following helpers to generate URL's that point back to the server. All of them respond to a GET request, even the ones that make changes on the server:

  • task: This includes attributes such as name, os, os_version, boot_seq, label, description, base, and architecture.
  • node: This includes attributes such as name, metadata, hostname, facts, and root_password.
    • policy: The node's policy, containing attributes such as name and broker.
  • repo: This includes attributes such as name, iso_url, url.
  • file_url(TEMPLATE): the URL that will retrieve TEMPLATE.erb (after evaluation) from the current node's task
  • repo_url(PATH): the URL to the file at PATH in the current repo
  • log_url(MESSAGE, SEVERITY): the URL that will log MESSAGE in the current node's log
  • node_url: the URL for the current node
  • store_url(VARS): the URL that will store the values in the hash VARS in the node. Currently only changing the node's IP address is supported. Use store_url("ip" => "192.168.0.1") for that.
  • stage_done_url: tell the server that we are done with this stage of the boot sequence, and that we should boot into the next one upon reboot.
  • broker_install_url: a URL from which the install script for the node's broker can be retrieved. The os_complete.erb script, which is used by most tasks, contains an example.

Each boot (except for the default boot) must culminate in something akin to curl <%= stage_done_url %> before the node reboots. Omitting this will cause the node to reboot into the same boot template over and over again.

The task must indicate to the Razor server that it has successfully finished its task by doing a GET request against stage_done_url("finished"), for example using curl or wget. This will mark the node as installed in the Razor database.

The way you use all these helpers is to cause your script to perform an HTTP GET against the generated URL; this might mean that you pass an argument like ks=<%= file_url("kickstart")%> when booting a kernel, or that you put curl <%= log_url("Things work great") %> in a shell script.

Migration to 0.15.0

In order to improve the layout of tasks in Razor, version 0.15.0+ will follow a new standard for task and template layout. Stock tasks included with Razor have already been migrated. If you wrote a custom task prior to this release, the steps below will help you migrate that task to the new version.

  • Templates folder is no longer following naming convention of "{name}/{os_version}"
  • YAML metadata file has changed its naming convention

Steps to migrate:

  1. Rename template folder "tasks/{name}" to "tasks/{name}.task". If the task did not require a template folder, then folder "tasks/{name}.task" needs to be created.
  2. Move any existing templates from "tasks/{name}.task/{os_version}" to parent folder "tasks/{name}.task"
  3. Remove "tasks/{name}.task/{os_version}" -- which should be empty now -- if it exists.
  4. Move/rename "tasks/{name}.YAML" to "tasks/{name}.task/metadata.YAML" If you have any trouble migrating an existing task, please feel free to get in touch on the mailing list or IRC.

Why was this change made?

This change was made for three reasons: To improve the intuitiveness of the search path (described below); to encapsulate tasks as one folder that follows a standard naming convention; and to standardize the metadata file's name.

Previously, tasks were spread over a top level file and a matching directory hierarchy. Individual versions inside that lead to a deeply nested tree of templates. Creating a modified copy of a task could be very challenging. Now, tasks live entirely inside a single "%{name}.task" directory, and without deep nesting. This makes them easier to copy, rename, and move.

Prior to the change, searching for templates used implicit search paths. It would use this search order:

  1. "tasks/{name}/{os_version}"
  2. "tasks/{name}"
  3. "tasks/{base_task}/{os_version}" (if inheritance was used)
  4. "tasks/{base_task}" (if inheritance was used)
  • [Any other base tasks are searched here recursively]
  1. "tasks/common"

This was cumbersome and led to some counterintuitive results. For example, let's say you have a task "windows-2008" with os_version "2008-R2". This task might derive from base task "windows" which has os_version "2012-R2-SP1". If you were to search for templates for "windows-2008", the path would include "tasks/windows/2012-R2-SP1" (base's name and base's os_version) and not "tasks/windows/2008-R2" (base's name and derived task's os_version).

The new search path uses this simplified search order:

  1. "tasks/{name}.task"
  2. "tasks/{base_task}.task"
  • [Any other base tasks are searched here recursively]
  1. "tasks/common"

The example above would not have the confusion over the os_version directory using this new search path.

Clone this wiki locally