5.20. Templating

5.20.1. Template Providers

Cobbler is not using a single templating engine but has a small abstraction layer that allows for multiple template engines. The default template engine is set via the setting default_template_type and currently has the value cheetah for backwards compatibility.

Note

While the default is Cheetah, new features will prefer Jinja 2 since the community and available resources are bigger than Cheetah.

5.20.1.1. Cheetah

The Cheetah template engine allows you to embed Python-like expressions and logic directly in your templates. It is traditionally used in Cobbler for generating configuration files and scripts. Cheetah templates use the $variable syntax and support control structures such as #if, #for, and #end if.

Example (Cobbler Kickstart snippet):

#if $system.gateway
GATEWAY=$system.gateway
#end if

#for $iface in $system.interfaces
DEVICE=$iface.name
IPADDR=$iface.ip_address
#end for

Explanation:

This example shows how to conditionally set the gateway if it is defined, and how to iterate over all network interfaces of a Cobbler system object to render device and IP address information. The $system variable is provided by Cobbler and exposes system attributes to the template.

More information:

5.20.1.2. Jinja

Jinja is a modern templating engine with a clean syntax, supporting advanced features like filters and template inheritance. Cobbler recommends Jinja for new templates due to its flexibility and strong community support. Jinja templates use the {{ variable }} syntax for expressions and {% ... %} for control structures.

Note

Cobbler does not utilize the block feature from Jinja. Please stick to the include syntax.

Example (Cobbler Kickstart snippet):

{% if system.gateway %}
GATEWAY={{ system.gateway }}
{% endif %}

{% for iface in system.interfaces %}
DEVICE={{ iface.name }}
IPADDR={{ iface.ip_address }}
{% endfor %}

Explanation:

This example demonstrates how to use Jinja’s conditional and loop syntax to render Cobbler system attributes. The gateway is set only if present, and all network interfaces are listed with their device name and IP address. Jinja’s syntax is concise and supports powerful features for template logic and formatting.

More information:

5.20.2. Available Variables inside the templates

Cobbler uses the method cobbler.utils.blender() to generate the information that can be used inside a template. The method internally combines the information from the settings and the to be rendered object and tweaks a few variables so they can be used more easily. All variables from autoinstall_meta are being promoted to the top-level of the generated information.

5.20.3. The Tag System

The Template class contains the property tags(). This property is a Set of Python Strings which steers the selection for which a template is being used. A list of well-known strings can be found in cobbler.enums.TemplateTag.

5.20.4. Relevant XML-RPC API Calls

For detailed information, please check the docstrings of the linked XML-RPC API methods.

5.20.5. Changes for version 4.0.0

Cobbler 4.0.0 introduced the following changes that need to be accounted for inside the templates:

  • Templates are now a dedicated item object.

  • Templates are now internally selected via tags instead of filenames.

  • Templates can now additionally be loaded from environment variables.

  • Templates are now cached in-memory and have to be explicitly refreshed with an API call after being edited.

  • Built-in templates are not stored in /var/lib/cobbler/templates anymore but are moved into the Python Package.

  • Built-in templates can be references via built-in-<name>.

5.20.6. Intended Workflow

  1. Write a template to disk underneath autoinstall_templates_dir or inside an environment variable which is accessible to the Cobbler Daemon.

  2. Use cobbler.remote.CobblerXMLRPCInterface.new_template() to create a new template object.

  3. Use cobbler.remote.CobblerXMLRPCInterface.modify_template() to modify the name, template_type, uri and tags of the object

  4. Use cobbler.remote.CobblerXMLRPCInterface.save_template() to persist the changes and make it available for use.

  5. Optional: Set the UID/Name of the template as a value to autoinstall inside a Profile or System.

  6. Optional: Execute a sync to update the affected configuration.

5.20.7. Usage Examples

In the following, the built-in DHCP template is retrieved via the XML-RPC API, modified using Python Code and written to disk. The result of the script is that the built-in template is not used anymore.

import xmlrpc.client

# Connect to Cobbler XML-RPC API
server = xmlrpc.client.ServerProxy("http://localhost/cobbler_api")

# Authenticate and get a token
token = server.login("username", "password")

# 1. Retrieve the built-in DHCP template content
built_in_template_uid = server.get_template_handle("built-in-dhcp")
dhcp_content = server.get_template_content(built_in_template_uid, token)

# 2. Modify the template (example: add a comment at the top)
modified_content = "# Custom DHCP template\n" + dhcp_content

# 3. Save the modified template to disk
with open("/var/lib/cobbler/templates/dhcp.template", "w") as f:
    f.write(modified_content)

# 4. Create a new Template object in Cobbler
template_obj = server.new_template(token)

# 5. Modify the Template object properties
server.modify_template(
    template_obj,
    {
        "name": "custom-dhcp",
        "template_type": "cheetah",  # or "jinja" if using Jinja syntax
        "uri": "/var/lib/cobbler/templates/dhcp.template",
        "tags": ["dhcp", "active"],
    },
    token,
)

# 6. Save the Template object to make it available
server.save_template(template_obj, True, True, "bypass", token)

# 7. Refresh templates cache
server.background_templates_refresh_content({}, token)

5.20.8. Limitations and Suprises

Before templates are passed to Jinja or Cheetah, there is a pre-processing of templates happening. During pre-processing Cobbler replaces variables like @@my_key@@ in the template. Those keys are currently limited by the regex of \S, which translates to [^ \t\n\r\f\v].