Templates
A Template is a collection of tasks that are executed sequentially. Each Task is a collection of actions that are executed sequentially on a specific worker. Actions are the individual unit of work, such as streaming an image to a disk, writing a file, or partitioning a disk.
Templates are specified as a Kubernetes custom resource definition (CRD).
apiVersion: tinkerbell.org/v1alpha1
kind: Template
metadata:
name: ubuntu
namespace: tink-system
spec:
data: ""
While the spec.data
field in the Template CRD is of type string, it has an expected data structure. This structure is defined in the workflow spec under the status
field. It’s structure is as follows:
name: ""
version: "0.1"
global_timeout: 3600
tasks: []
- name
string
: A string that describes the template. It must be a string > 0 and < 200 characters. It should be unique among Tasks in the Template. Required. - version
string
: A string that describes the version of the template. It must be “0.1”. Note that it is deprecated and not used in the implementation. Required. - global_timeout
int
: An integer that describes the global timeout in seconds for the template. - tasks
[]task
: A list of task objects. Required.
The Go struct for Tasks is found here and the Kubernetes custom resource definition here. The spec can also be explored here.
A Task describes a list of actions. A Task can define volumes and environment variables that will be available to all action containers. Multiple Tasks can be defined. Each Task can define a worker to run on. The same worker can be used for multiple tasks. Task names must be unique within a template.
tasks:
- name: "installation"
environment:
GLOBAL_VALUE: "my global value"
volumes:
- /dev:/dev
- /lib/firmware:/lib/firmware:ro
worker: "{{.device_1}}"
actions: []
- name: "post installation"
environment:
GLOBAL_VALUE: "my global value"
volumes:
- /dev:/dev
- /lib/firmware:/lib/firmware:ro
worker: "{{.device_2}}"
actions: []
- name
string
: A string that describes the task. It should be unique among tasks in the template. Required. - worker
string
: A string that is a Go template value that is used to match a worker. Required. - volumes
[]string
: A list of strings that are used to mount volumes into all action containers. The format for each string should besource:destination
. - environment
map[string]string
: A map of strings that are used to set environment variables in all action containers. - actions
[]action
: A list of actions that are executed sequentially. Required.
Actions are the list of Action objects to be executed. Action objects will be executed sequentially at runtime and are all executed on the worker specified in the Task.
actions:
- environment:
COMPRESSED: "true"
DEST_DISK: /dev/vda
IMG_URL: http://192.168.2.112:8080/jammy-server-cloudimg-amd64.raw.gz
image: quay.io/tinkerbell/actions/image2disk:v1.0.0
name: stream ubuntu image
timeout: 9600
- environment:
CONTENTS: |
datasource:
Ec2:
metadata_urls: ["http://192.168.2.112:50061"]
strict_id: false
manage_etc_hosts: localhost
warnings:
dsid_missing_source: off
DEST_DISK: /dev/vda1
DEST_PATH: /etc/cloud/cloud.cfg.d/10_tinkerbell.cfg
DIRMODE: "0700"
FS_TYPE: ext4
GID: "0"
MODE: "0600"
UID: "0"
image: quay.io/tinkerbell/actions/writefile:v1.0.0
name: add-cloud-init-config
timeout: 90
- environment:
CONTENTS: |
datasource: Ec2
DEST_DISK: /dev/vda1
DEST_PATH: /etc/cloud/ds-identify.cfg
DIRMODE: "0700"
FS_TYPE: ext4
GID: "0"
MODE: "0600"
UID: "0"
image: quay.io/tinkerbell/actions/writefile:v1.0.0
name: add-tink-cloud-init-ds-config
timeout: 90
- image: quay.io/tinkerbell/actions/writefile:v1.0.0
name: write-netplan
timeout: 90
An Action is an individual units of work, such as streaming an image to a disk, writing a file, or partitioning a disk.
name: stream ubuntu image
image: quay.io/tinkerbell/actions/image2disk:v1.0.0
timeout: 9600
command: ["echo", "override", "entrypoint", "in", "container", "image", "here"]
on-timeout: ["echo", "timeout"]
on-failure: ["echo", "failure"]
volumes: ["/var/run/data":"/data"]
pid: "host"
environment:
COMPRESSED: "true"
DEST_DISK: /dev/vda
IMG_URL: http://192.168.2.112:8080/jammy-server-cloudimg-amd64.raw.gz
- name
string
: A string that describes the action. It should be unique among actions in the task. Required. - image
string
: A string that describes the fully qualified location to a container image to be used for the action. Required. - timeout
int
: An integer that describes the timeout in seconds for the action. - command
[]string
: A list of strings that are used to override the entrypoint in the container image. - on-timeout
[]string
: A list of strings that are used to override the entrypoint in the container image when the action times out. - on-failure
[]string
: A list of strings that are used to override the entrypoint in the container image when the action fails. - volumes
[]string
: A list of strings that are used to mount volumes into the action container. The format for each string should besource:destination
. - pid
string
: A string that describes the pid mode for the action. Generally it is either “host” or not defined. - environment
map[string]string
: A map of strings that are used to set environment variables in the action container.
Note: Actions are user-defined and can be any container image that is available to the worker. The Actions you see in this doc are examples and are not the only way to accomplish these tasks. See this Actions repo for the Tinkerbell maintained Actions.
This is a full example of a Template for installing Ubuntu and configuring it to use cloud-init.
apiVersion: tinkerbell.org/v1alpha1
kind: Template
metadata:
name: ubuntu
namespace: tink-system
spec:
data: |
name: ubuntu
version: "1.0"
global_timeout: 9800
tasks:
- name: "os installation"
worker: "{{.device_1}}"
volumes:
- /dev:/dev
- /dev/console:/dev/console
- /lib/firmware:/lib/firmware:ro
environment:
GLOBAL_VALUE: "my global value"
actions:
- name: "stream image"
image: quay.io/tinkerbell/actions/image2disk:v1.0.0
timeout: 9600
environment:
DEST_DISK: {{ index .Hardware.Disks 0 }}
IMG_URL: "http://{{ .artifact_server_ip_port }}/jammy-server-cloudimg-amd64.raw.gz"
COMPRESSED: true
- name: "add cloud init config"
image: quay.io/tinkerbell/actions/writefile:v1.0.0
timeout: 90
environment:
CONTENTS: |
datasource:
Ec2:
metadata_urls: ["http://{{ .hegel_ip_port }}"]
strict_id: false
manage_etc_hosts: localhost
warnings:
dsid_missing_source: off
DEST_DISK: {{ formatPartition ( index .Hardware.Disks 0 ) 1 }}
DEST_PATH: /etc/cloud/cloud.cfg.d/10_tinkerbell.cfg
DIRMODE: "0700"
FS_TYPE: ext4
GID: "0"
MODE: "0600"
UID: "0"
- name: "add cloud-init ds config"
image: quay.io/tinkerbell/actions/writefile:v1.0.0
timeout: 90
environment:
DEST_DISK: {{ formatPartition ( index .Hardware.Disks 0 ) 1 }}
FS_TYPE: ext4
DEST_PATH: /etc/cloud/ds-identify.cfg
UID: 0
GID: 0
MODE: 0600
DIRMODE: 0700
CONTENTS: |
datasource: Ec2
- name: "write netplan"
image: quay.io/tinkerbell/actions/writefile:v1.0.0
timeout: 90
environment:
DEST_DISK: {{ formatPartition ( index .Hardware.Disks 0 ) 1 }}
FS_TYPE: ext4
DEST_PATH: /etc/netplan/config.yaml
CONTENTS: |
network:
version: 2
renderer: networkd
ethernets:
id0:
match:
name: en*
dhcp4: true
UID: 0
GID: 0
MODE: 0644
DIRMODE: 0755
A Template spec can contain Go template values, for example {{ .device_1 }}
. The values come from a workflow spec that references the Template. For example, given the following template and workflow, the {{ .device_1 }}
in the Template will be evaluated to 02:00:00:00:00:01
as defined in the Workflow spec at spec.hardwareMap.device_1
. The spec.hardwareMap
in the Workflow takes arbitrary key/value pairs.
apiVersion: tinkerbell.org/v1alpha1
kind: Template
metadata:
name: ubuntu
namespace: tink-system
spec:
data: |
name: ubuntu
version: "1.0"
global_timeout: 9800
tasks:
- name: "os installation"
worker: "{{.device_1}}"
volumes:
- /dev:/dev
actions:
- name: "stream image"
image: quay.io/tinkerbell/actions/image2disk:v1.0.0
timeout: 9600
environment:
DEST_DISK: {{ index .Hardware.Disks 0 }}
IMG_URL: "http://{{ .artifact_server_ip_port }}/jammy-server-cloudimg-amd64.raw.gz"
COMPRESSED: true
apiVersion: tinkerbell.org/v1alpha1
kind: Workflow
metadata:
name: ubuntu-install
namespace: tink-system
spec:
templateRef: ubuntu
hardwareRef: hardware-1
hardwareMap:
device_1: 02:00:00:00:00:01
Key names that are defined by a User in the Workflow spec at spec.hardwareMap
:
source | output |
---|---|
{{ .device_1 }} |
02:00:00:00:00:01 |
{{ .key_name }} |
value |
Values from the Hardware spec (currently, only Disks are available):
source | output |
---|---|
{{ .Hardware.Disks }} |
[ /dev/nvme0n1, /dev/sda ] |
Standard Go template functions:
source | output |
---|---|
{{ .device_1 | printf "%s" }} |
02:00:00:00:00:01 |
{{ if eq .device_1 "02:00:00:00:00:01" }} |
true |
{{ index .Hardware.Disks 0 }} |
/dev/nvme0n1 |
source | output |
---|---|
{{ formatPartition ( index .Hardware.Disks 0 ) 1 }} |
/dev/nvme0n1p1 |
{{ contains .device_1 "02:00:00:00:00:01" }} |
true |
{{ hasPrefix .device_1 "02:00:00" }} |
true |
{{ hasSuffix .device_1 "00:01" }} |
true |