(R)?ex the friendly automation framework

News

2020-04-05
Rex-1.9.0

The Rex-1.9.0 release is now available on CPAN, and it adds a new feature flag to force writing UTF-8 encoded files, documents configuration options, and fixes bugs.

2020-03-05
Rex-1.8.2

The Rex-1.8.2 release is now available on CPAN, fixing a bug related to task hooks.

2020-02-05
Rex-1.8.1

The Rex-1.8.1 release is now available on CPAN, improving release automation, packaging, and documentation.

2020-01-05
Rex-1.8.0

The Rex-1.8.0 release is now available on CPAN, adding initial support to manage Void Linux systems.

2019-12-05
Rex-1.7.1

The Rex-1.7.1 release is now available on CPAN, fixing a Windows testing issue, and updating some docs.

Conferences

2016-06-21

Need Help?

Rex is a pure open source project, you can find community support in the following places:

Professional support is also available.

» Home » Docs » Rex book » The rex dsl » Using templates

Using templates

A template is a text file containing special variables or perl code inside it. So with this technique you can generate dynamic configuration files. For example if you want to configure apache only to listen on a special ethernet device (eth0 for example) templates are what you need.

The default template engine is a special Rex template engine. The syntax is a bit like php or erb. But you can use any template engine you want. Just browse cpan and find one you like.

For example:

Hello <%= $name %>!

If $name contains "World" this template would result in the string Hello World!. This is very useful if you have to maintain a large set of nearly identical configuration files.

Working with a template

First you have to create it

$ mkdir files
$ vim files/my.cnf.tpl

[mysqld]
datadir                 = /var/lib/mysql
socket                  = /var/run/mysqld/mysqld.sock
user                    = mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links          = 0
datadir                 = /var/lib/mysql
tmpdir                  = /tmp
skip-external-locking
max_allowed_packet      = 64M
thread_stack            = 192K
max_connections         = <%= exists $conf->{"max_connections"} ? $conf->{"max_connections"} : "1000" %>

max_connect_errors      = 1000
table_cache             = <%= exists $conf->{"table_cache"} ? $conf->{"table_cache"} : "5000" %>
table_open_cache        = <%= exists $conf->{"table_open_cache"} ? $conf->{"table_open_cache"} : "5000" %>
thread_concurrency      = 10

#
# ... and more ...
#

Than you can reference on it from within your Rexfile.

use Rex -feature => ['1.0'];
⁠
⁠user "root";
⁠key_auth;
⁠
⁠group databases => "mydb01", "mydb02";
⁠
⁠task "prepare_databases",
⁠  group => "databases",
⁠  sub {
⁠    file "/etc/my.cnf",
⁠      owner   => "root",
⁠      group   => "root",
⁠      mode    => "644",
⁠      content => template(
⁠        "files/my.cnf.tpl",
⁠        conf => {
⁠            max_connections => "500",
⁠            table_cache     => "2500",
⁠        }
⁠      );
⁠  };

Inline Templates

When you want to deliver a rexfile that includes the templates, you can use inline templates. To use this feature, you have to use the __DATA__ section of your rexfile. You can also define several templates in that section:

Using a single inline template

use Rex -feature => ['1.0'];
⁠
⁠task tempfiles => sub {
⁠    file '/tmp/test.txt' => content => template(
⁠        '@test',
⁠        test => {
⁠            author => 'reneeb',
⁠            target => 'rex',
⁠        },
⁠      ),
⁠      chmod => 644,
⁠      ;
⁠};
⁠
⁠__DATA__
⁠@test
⁠This is a test written by <%= $test->{author} %>
⁠for a project called <%= $test->{target} %>
⁠@end

The __DATA__ section is the last section of the Rexfile. The first parameter of the template method call gets the name of the inline template. Note that names of inline templates begin with @.

Rex knows that it has to look up the template in the __DATA__ section of the file where template was called. Within the section the template starts with its name (here: @test) and then follows the template text.

Using multiple inline templates

⁠use Rex -feature => ['1.0'];
⁠task tempfiles   => sub {
⁠    file '/tmp/test.txt' => content => template(
⁠        '@test',
⁠        test => {
⁠            author => 'reneeb',
⁠            target => 'rex',
⁠        },
⁠      ),
⁠      chmod => 644,
⁠      ;
⁠
⁠    file '/tmp/rex.txt' => content => template(
⁠        '@rex',
⁠        test => {
⁠            author => 'krimdomu',
⁠            target => 'rex',
⁠        },
⁠      ),
⁠      chmod => 644,
⁠      ;
⁠};
⁠
⁠__DATA__
⁠@test
⁠This is a test written by <%= $test->{author} %>
⁠for a project called <%= $test->{target} %>
⁠@end
⁠
⁠@rex
⁠Contribution by <%= $test->{author} %>
⁠for a project called <%= $test->{target} %>
⁠@end

Now we just look at the __DATA__ section: You notice the token @end. This is used to separate the templates. At the end of each template (except for the last one) this token is needed. Otherwise Rex will use everything up to the first @end as the template which is most likely too much.

Proudly powered by Statocles

Google Group / Twitter / GitHub / Mailinglist / irc.freenode.net #rex   -.ô.-   Disclaimer