Project

General

Profile

TemplateWriting » History » Version 105

Marek Hulán, 07/17/2017 02:07 AM

1 25 Paul Kelly
{{toc}}
2 26 Paul Kelly
3 1 Justin Sherrill
h1. Templates
4
5
6
7 16 Justin Sherrill
The following functions and macros can be used within templates.  These are guaranteed to work via the safemode rendering, to ensure a template can do nothing harmful. With safemode disabled other macros may work, but are not supported at this time.
8 15 Justin Sherrill
9 30 Martin Hovmöller
To enable safemode, set "safemode_render" to "true" in Settings -> Foreman settings.  Safemode rendering prevents templates from reading and writing files on the file system or modifying application data within foreman.  
10 1 Justin Sherrill
11
12 8 Justin Sherrill
h2. Accessing Templates
13 1 Justin Sherrill
14 10 Justin Sherrill
There are two ways to render a template, based on a single host, or based on a Hostgroup.  The host or hostgroup provides all the details with which to render the template.  
15 1 Justin Sherrill
16 10 Justin Sherrill
17 8 Justin Sherrill
h3. Host-based Rendering
18
19 13 Justin Sherrill
Only a single template of each type may be rendered for a system.  Foreman determines which template to use following these rules:
20 1 Justin Sherrill
21 13 Justin Sherrill
1. Only the templates of the appropriate kind and associated with the hosts operating system are considered
22
2. If a template has a hostgroup/environment combination that matches that of the host, use this template else
23
3. If a template is associated with the environment of the host, use this template, else
24
4. Use the first template found associated with the operating system associated with the host.
25 1 Justin Sherrill
26 13 Justin Sherrill
So essentially, the hostgroup/environment combination is used first, then just the environment, and finally just the operating system of the host.
27
28
29 1 Justin Sherrill
To access a template of a certain type simply use this url:
30
31 13 Justin Sherrill
@/unattended/KIND_NAME@
32 1 Justin Sherrill
33 13 Justin Sherrill
For example:    @/unattended/provision@
34 12 Justin Sherrill
would render the provisioning template.  The host will be based on the IP Address it is accessed from.  To spoof a template simply access the url in this manner:
35
36 13 Justin Sherrill
@/unattended/provision?spoof=192.168.0.1@
37 12 Justin Sherrill
38 70 Dominic Cleal
where 192.168.0.1 is the ip address of the system you want to spoof. This allows you to view a template for a particular system from anywhere.
39 1 Justin Sherrill
40 17 Justin Sherrill
h3. Hostgroup-based rendering
41 9 Justin Sherrill
42 70 Dominic Cleal
Allows any template to be rendered for any host group.  When rendering using a hostgroup, @host is actually the hostgroup instead of a defined host. The default values for the hostgroup are used for templated values.  This means if a value is not set in the hostgroup, you may get an error when rendering the template.  To access a template using a Hostgroup to render, simply use this URL:
43 8 Justin Sherrill
44
/unattended/template/Template Name/Hostgroup Name
45 1 Justin Sherrill
46
For example, a hostgroup of name Finance, and a template named WebServerKickstart could be rendered using the url:
47 8 Justin Sherrill
48
/unattended/template/WebServerKickstart/Finance
49 70 Dominic Cleal
50
When building the default PXE template (from the Provisioning Templates page), any host group with the operating system, installation media and architecture set, plus provisioning templates with the host group set on the Associations tab will be listed at the bottom of the menu.
51 1 Justin Sherrill
52 33 Ohad Levy
h3.  PXE Menus
53 10 Justin Sherrill
54 84 Marek Hulán
PXE Menus can be deployed to smart proxies from the Provisioning Templates list page (/templates/provisioning_templates).  All provisioning templates will be added with each of their hostgroup combinations (see above).  For example if the template "WebServerKickstart" is associated to the Hostgroup1/Production, Hostgroup2/Production, and Hostgroup2/Testing combinations, the template would only be added twice.  Once for WebServerKickstart-Hostgroup1 and WebServerKickstart-Hostgroup2.
55 1 Justin Sherrill
56 84 Marek Hulán
Note that you can use only macros that are not host specific since this global PXE template is not specific to one host.
57
58 8 Justin Sherrill
h2. Writing templates
59 17 Justin Sherrill
60
Templates can be written using common ERB style templating.  Here's an example on using a variable/function:
61
62 81 Franklin Piat
<pre>
63 46 Tomas Edwardsson
@rootpw --iscrypted <%= root_pass %>@
64 81 Franklin Piat
</pre>
65 17 Justin Sherrill
66
Using a simple conditional:
67
68 81 Franklin Piat
<pre>
69 46 Tomas Edwardsson
@<%= "selinux --disabled\n" if @osver != 3 -%>@
70 81 Franklin Piat
</pre>
71
72 17 Justin Sherrill
This would include a line to disable selinux if the operating system version is not 3 (since Selinux isn't supported on RHEL 3)
73
74
Another way to do conditional (with if/elsif/else):
75
76 18 Justin Sherrill
<pre>
77 46 Tomas Edwardsson
<% if @osver == 5 -%>
78 17 Justin Sherrill
 echo "uses yum"
79 46 Tomas Edwardsson
<% elsif @osver == 4 -%>
80 17 Justin Sherrill
 echo "uses up2date
81 46 Tomas Edwardsson
<% else -%>
82 17 Justin Sherrill
 echo "I'm not sure"
83 46 Tomas Edwardsson
<% end -%>
84 18 Justin Sherrill
</pre>
85 8 Justin Sherrill
86 1 Justin Sherrill
h2. Functions and macros:
87
88 84 Marek Hulán
h3. Generic macros
89
90
You should be able to use these macros in any template (Partition tables and Provisioning templates of all kinds)
91
92 1 Justin Sherrill
|_.Name|_.Description|_.Example|
93 94 Dominic Cleal
|dns_lookup| Performs a forward or reverse DNS lookup on a supplied name or IP address, Foreman 1.13+ | echo <%= dns_lookup('example.com') %> example.com >> /etc/hosts |
94 1 Justin Sherrill
|foreman_server_fqdn| FQDN of Foreman server derived from _foreman_url_ Setting, Foreman 1.12+ | # Template generated at <%= foreman_server_fqdn %> |
95
|foreman_server_url| Full URL of Foreman server equal to value of _foreman_url_ Setting, Foreman 1.12+ | curl <%= foreman_server_url %>/my_plugin_api |
96
|foreman_url(kind)| Provides the full URL to a host-rendered template of the given kind, based on _unattended_url_ Setting with fallback to current request headers | foreman_url("provision") =>  http://HOST/unattended/provision |
97 94 Dominic Cleal
|indent(n)|Indents the block of code by n spaces, useful when using snippet which are not indented | <pre><code class="ruby"><%= indent 4 do
98
    snippet 'subscription_manager_registration'
99
end %></code></pre>|
100 84 Marek Hulán
|snippet(name)   | Renders the specified snippet | |
101
|snippets(file)   | Renders the specified snippet found in DB, tries to load it from unattended/snippets/$file directory from hard drive it it's not found in DB | |
102
|snippet_if_exists(name)   | Renders the specified snippet, skip it if it can't be found by name | |
103 97 Lukas Zapletal
|template_name | Returns @template_name (1.13+ | |
104 84 Marek Hulán
105
h3. Host specific macros
106
107
These macros can be used only when the template is rendered for specific host.
108
109
|_.Name|_.Description|_.Example|
110
|grub_pass  |The GRUB password wrapped in md5pass argument | grub_pass # => --md5pass=#{@host.grub_pass} |
111 101 Dominic Cleal
|host_enc |Returns the host's ENC hash of data, including lists of classes and parameters (Foreman 1.15+) | @<%= host_enc %>@ |
112
|host_param |Returns the value of a parameter on the host, or inherited from a host group etc. (Foreman 1.15+) | @<%= host_param('example') %>@ |
113
|host_param_true? |Returns true if the given host parameter is a true/yes/1 value (Foreman 1.15+) | @<% if host_param_true?('example') -%>@ |
114
|host_param_false? |Returns true if the given host parameter is a false/no/0 value (Foreman 1.15+) | @<% if host_param_false?('example') -%>@ |
115
|ks_console |A string assembled using the port and baud of the host which can be added to a kernel line | ks_console # => console=ttyS1,9600 |
116 84 Marek Hulán
|_media_path_ | not used anywhere in built in templates, candidate for removing in Foreman 1.13 | media_path # => /media |
117 1 Justin Sherrill
|root_pass  |The root password configured for the system| |
118 101 Dominic Cleal
119 84 Marek Hulán
120 96 Sean O'Keeffe
h3. Remote Execution specific macros
121
122
|_.Name|_.Description|_.Example|
123
|errata(<ID>) |A hash of errata data containing errata_type, title, reboot_suggested & loads of others (Only applicable with Katello) | errata(2) OR errata('RHBA-2016:1992') |
124
125 84 Marek Hulán
h3. Variables and snippets
126
127
|_.Name|_.Description|_.Example|
128 87 a d^2
|@host.model | The name of the value assigned in Hardware Models. | <notextile><% if @host.model.to_s == 'vmware' %> .. <% end -%></notextile>,  <notextile><% if @host.model.to_s == 'xen' %> .. <% end -%></notextile>|
129 46 Tomas Edwardsson
|@host.name                |The (full) name of the host| |
130 39 Ben Hagen
|@host.shortname           |The (short) name of the host| |
131 71 Lukas Zapletal
|@host.certname            |The SSL certificate name of the host| |
132 1 Justin Sherrill
|@host.domain           |The domain of the host| |
133 95 Gerwin Krist
|@host.ip                |The IPv4 address of the host| |
134
|@host.ip6               |The IPv6 address of the host| |
135 1 Justin Sherrill
|@host.hostgroup       |The hostgroup of the host| <notextile><% if @host.hostgroup.to_s == "Base/Application Servers" -%>...<% end -%></notextile>|
136
|@host.mac                |The HW address of the host| |
137 81 Franklin Piat
|@host.diskLayout     |The disklayout of the host (could come from the operating system)| |
138 59 Arnold Bechtoldt
|@host.ptable        |The disklayout name | <notextile><% if @host.ptable.name == 'Kickstart RHEL default' %> .. <% end %></notextile> |
139 1 Justin Sherrill
|@host.puppetmaster   |The puppetmaster the host should use | |
140
|@host.environment  |The environment the host should use | |
141 34 Frank Sweetser
|@host.location    |The location of the host | |
142 82 Dominic Cleal
|@host.architecture   |The arch of the host (i.e. x86_64)| |
143 79 Franklin Piat
|@host.medium |The assigned OS installation medium (1.10.2+)|
144 81 Franklin Piat
|@host.operatingsystem.name|The operating system name| |
145 1 Justin Sherrill
|@host.operatingsystem.major |The major version of the OS| <notextile><% if @host.operatingsystem.major.to_i < 7 %> .. <% end %></notextile> |
146
|@host.operatingsystem.minor |The minor version of the OS| <notextile><% if @host.operatingsystem.minor.to_i > 2 %> .. <% end %></notextile> |
147 81 Franklin Piat
|@host.operatingsystem.family |The OS Family (I.e. Redhat, Debian, etc.)||
148 77 Maurice Mouw
|@host.os.medium_uri(@host) |The url for provisioning (path configured in installation media)|<%= @host.os.medium_uri(@host) %> => http://mirror.os.org/os/|
149 84 Marek Hulán
|@host.param_false?(name) | returns false if host parameter of a given name evaluates to false (e.g. 0, 'no', false, 'false', 'f', off, nil) |<%= @host.param_true?('enable-puppetlabs-repo') %> => true|
150 1 Justin Sherrill
|@host.param_true?(name) | returns true if host parameter of a given name evaluates to true (e.g. 1, 'yes', true, 'true', 't', on) |<%= @host.param_true?('enable-puppetlabs-repo') %> => true|
151
|@host.subnet.mask |The subnet mask of the host||
152 95 Gerwin Krist
|@host.subnet.gateway |The IPv4 gateway of the host||
153
|@host.subnet6.gateway | The IPv6 gateway of the host ||
154 42 Trey Dockendorf
|@host.subnet.dns_primary |The primary DNS of the host||
155 1 Justin Sherrill
|@host.subnet.dns_secondary |The secondary DNS of the host||
156 82 Dominic Cleal
|@host.subnet.dhcp|Boolean that render true if a dhcp proxy is configured for this host|<notextile><% if @host.subnet.dhcp %> .. <% else %> .. <% end %></notextile>|
157
|@host.url_for_boot(:kernel) |Full url to the kernel associated with this host.|Not recommended, as it doesn't interpolate variables, prefer boot_files_uri|
158
|@host.url_for_boot(:initrd) |Full url to the initrd image associated with this host|Not recommended, as it doesn't interpolate variables|
159 44 Siert Z.
|@host.operatingsystem.boot_files_uri(@host.medium,@host.architecture) | Full URL to the kernel and initrd, returns an array (1.10.2+) |
160
|@host.sp_name|The name of the BMC interface ||
161
|@host.sp_ip|The IP address of the BMC interface ||
162
|@host.sp_mac|The HW address of the BMC interface ||
163 73 Marek Hulán
|@host.sp_subnet|Subnet of the BMC network ||
164 74 Marek Hulán
|@host.interfaces| Contains an array of all available host interfaces including primary (see networking notes below for changes between Foreman versions) ||
165
|@host.primary_interface| Returns host's primary interface (1.8+) |it existed in 1.7, returning primary_interface identifier based on imported facts, 1.8+ it returns interface object |
166 73 Marek Hulán
|@host.provision_interface| Returns host's provision interface (1.8+) | returns interface object, see notes below for more details |
167
|@host.bond_interfaces| Contains an array of all bonds (1.7+) ||
168 1 Justin Sherrill
|@host.managed_interfaces| Limit the array to managed (non-BMC nor Bond) interfaces only which are set to be managed (1.7+) ||
169
|@host.interfaces_with_identifier(['eth0', 'eth1']) | Returns array of interfaces with given identifier (1.7+)||
170
|@host.interfaces.managed| Limit the array to managed (non-BMC nor Bond) interfaces only (only works if safemode_render=false) ||
171
|@host.interfaces.bmc| Limit the array to BMC (non-managed) interfaces only (only works if safemode_render=false) ||
172 73 Marek Hulán
|@host.interfaces.size| Number of additional interfaces (either type interface or bmc) (only works if safemode_render=false) |size=1 means a host has two interfaces on 1.7, one interface on 1.8+|
173 72 Dominic Cleal
|@host.interfaces.empty|If true host does not have ant interface (only works if safemode_render=false) ||
174
|@host.facts| Contains a hash of facts from Facter/Ohai etc. (1.7.2+) ||
175 88 Dominic Cleal
|@host.facts['ipaddress']| Accessing the 'ipaddress' fact for the host, use @::@ as a separator to access structured facts (1.7.2+) ||
176 66 Dominic Cleal
|@host.facts_hash| Contains a hash of facts from Facter/Ohai etc. (only works if safemode_render=false) ||
177 81 Franklin Piat
|@host.facts_hash['ipaddress']| Accessing the 'ipaddress' fact for the host (only works if safemode_render=false) ||
178
|@host.image_build?| Returns true if the host is provisioned using an image (1.5+)| <notextile><% if @host.image_build? %></notextile> |
179 1 Justin Sherrill
|@host.pxe_build?| Returns true if the host is provisioned using the network/PXE (1.5+)| <notextile><% if @host.pxe_build? %></notextile> |
180 102 Sean O'Keeffe
|@host.token| Return the hosts provisioning token | |
181 81 Franklin Piat
|@provisioning_type|Equal to 'host' or 'hostgroup' depending on type of provisioning (1.6+)| <notextile><% if @provisioning_type == 'hostgroup' %></notextile> |
182 1 Justin Sherrill
|@static|Boolean value to determine if the network configuration is static or dynamic|Use <notextile><%= @static ? "static" : "dynamic" %></notextile> in templates|
183
|@template_name|Name of the template being rendered (1.7+)| <%= @template_name %> |
184
185 55 Stefan Lasiewski
*NOTE*: For *PXELinux* templates in 0.4 or older _only_ leave off the '@host.' from the above as it is currently generated slightly different from everything else. 
186 53 Dominic Cleal
187 1 Justin Sherrill
*NOTE*: The interface array can be parsed this way: <pre><% @host.interfaces.each do |i| %> key is <%= i.ip %> <% end %></pre>. To print information for the first interface in the array, try something like: <pre><% myinterface = @host.interfaces.first %> IP: <%= myinterface.ip %> Netmask: <%= myinterface.subnet.mask %> Gateway: <%= myinterface.subnet.gateway %></pre>
188
189
*NOTE*: Some variables can't be accessed while safemode is enabled.  Disable via safemode_render in _More > Settings_, though be aware this enables arbitrary code to be added to templates.  Some are being whitelisted via #2948.
190 57 Benjamin Papillon
191 1 Justin Sherrill
*NOTE*: You may need to add "&static=yes" to the foreman_url to use the @static parameter in templates (see [[KickstartStatic]]).
192
193 74 Marek Hulán
*NOTE*: A lot of networking functions changed their meaning between 1.7 and 1.8 releases. In 1.7, primary interface used to be part of host object so it was not part of '@host.interfaces'. Also it could be detected by '@host.has_primary_interface?' which was removed in 1.8. For more advanced example of using networking functions, see kickstart_networking_setup.erb provisioning template snippet.
194 1 Justin Sherrill
195 104 Jo Vandeginste
*NOTE*: If you get interface object as a returning value of some function (e.g. primary_interface or interfaces.first) it is evaluated to its DNS name by default. You can easily get to other attributes of such interface, e.g. @host.primary_interface.identifier or @host.primary_interface.mac. Valid attributes include: "managed?", "subnet" (returns subnet object), "virtual?", "physical?", "mac", "ip", "identifier", "attached_to", "link", "tag", "domain" (returns domain object), "fqdn", "shortname", "vlanid", "bond_options", "attached_devices", "mode", "attached_devices_identifiers", "primary", "provision", "alias?", "inheriting_mac" (if it's virtual it inherits the mac from attached_to device)
196 21 Justin Sherrill
197 85 Sean O'Keeffe
h3. Katello only Variables and snippets
198
199
|_.Name|_.Description|_.Example|
200
|@host.info['parameters']['lifecycle_environment'] |The lifecycle environment of the host| |
201 93 Sean O'Keeffe
|Katello::ActivationKey.find_by_name(@host.info['parameters']['kt_activation_keys']).host_collections<notextile>[1]</notextile>['name'] | The first host collection in the activation key the host is using. (only works if safemode_render=false) |<% if Katello::ActivationKey.find_by_name(@host.info['parameters']['kt_activation_keys').host_collections.select { <notextile>|</notextile>host_collection<notextile>|</notextile> host_collection['name'] == 'MY_HOST_COLLECTION_NAME' } -%>|
202 1 Justin Sherrill
203
h3. Kickstart only variables (Only available for provision templates and "RedHat" Family operating systems):
204 21 Justin Sherrill
205
|_.Name|_.Description|_.Example|
206
|@osver |The OS Major Version (Same as @host.operatingsystem.major)||
207 46 Tomas Edwardsson
|@arch | The architecture (same as @host.architecture.name)  ||
208
|@mediapath | The full kickstart line to provide the url command.|@mediapath => http://file.example.com/RHEL-5-Server/U5/x86_64/os/|
209 1 Justin Sherrill
|@epel |A command which will automatically install the correct version of the epel-release rpm.  Use full in a %post script.|@epel => "su -c 'rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm'"|
210 21 Justin Sherrill
|@dynamic |true if the parition table being used is a %pre script (has #Dynamic as the first line of the table)|<% if @dynamic -%>|
211 6 Justin Sherrill
212 1 Justin Sherrill
h3. Preseed attributes (Only available for provision templates and "Debian" Family operating systems)::
213
214
|_.Name|_.Description|_.Example|
215 27 Alexander Rusa
|@preseed_path |||
216
|@preseed_server |||
217
218 98 Patrick Schönfeld
The values of those attributes are auto-computed based on the url attribute configured in the installation medium.
219 99 Patrick Schönfeld
220 100 Dominic Cleal
h3. Host or host group parameters
221 35 David M.
222 100 Dominic Cleal
In Foreman 1.15 or higher, retrieve the value of a parameter on a host (or inherited from the OS, domain etc) by using:
223 1 Justin Sherrill
224 100 Dominic Cleal
    host_param('param_name')
225
226
In 1.14 or earlier:
227
228
    @host.params['parameter_name']
229
230 1 Justin Sherrill
If you need to test if a parameter contains a boolean true/false value, there are two helpers that will help:
231
232 100 Dominic Cleal
    host_param_true?('parameter_name')
233
host_param_false?('parameter_name')
234
235
Or on 1.14 or higher:
236
237 75 Dominic Cleal
    @host.param_true?('parameter_name')
238
@host.param_false?('parameter_name')
239 36 Adrian Bridgett
240 41 Ohad Levy
These check the parameter is a true/false/on/off/1/0 string.
241
242
h3. Compute Resource Specific functions
243
244 36 Adrian Bridgett
see [[Compute Resources#Templates]]
245
246
h3. Settings
247
248
Setting.setting_name
249 1 Justin Sherrill
250 78 Stephen Benjamin
You will need to disable Safemode-Rendering in More->Settings.
251
252
h2. Ruby methods
253
254
The most common methods on Ruby's core classes should be allowed (split, gsub, to_i, blank?, etc).  A full list is in the Safemode Gem: https://github.com/svenfuchs/safemode/blob/master/lib/safemode/core_jails.rb#L33
255
256
To avoid turning off safemode, consider alternative ways of writing your ruby code. For example this would not work in the default Jail:
257
258
<pre>
259
@host.ip.rpartition('.')[-1]
260
</pre>
261
262
263
But this does:
264
265
<pre>
266
@host.ip.split('.').last
267 83 Paul Armstrong
</pre>
268
269 105 Marek Hulán
Since Foreman 1.15.3, it's not allowed to use to_proc syntax for iterators, e.g. 
270
<pre>
271
@host.interfaces.map(&:id)
272
</pre>, please use 
273
<pre>
274
@host.interfaces.map { |i| i.id }
275
</pre>
276
instead. This applies to all iterating method such as each, map, inject
277
278 83 Paul Armstrong
h2. Troubleshooting
279
280
Kickstart/preseed files are all generated dynamically based on the setting of each host in Foreman, things like partition tables and root password can be unique per server.
281
282
If you are having issues with a system building from a template or a system is unable to retrieve a template you can see the kickstart/preseed template result using your browser. If your system failed to retrieve the kickstart file it may be due to the fact that the template build failed. 
283
284
Use the spoof parameter by pointing your browser to a url similar to:
285
286
<pre>
287
http://foreman/unattended/provision?spoof=123.321.123.321
288
</pre>
289
290
* 123.321.123.321 is the hosts IP Address (the one you want to build).
291
* usually you want to see the page source, the browser might display the file in html which will result in hard to read output.
292 1 Justin Sherrill
* the completed template will be displayed or any errors that were encountered while the template was being built.