(R)?ex the friendly automation framework

News

2023-08-05
Rex-1.14.3

Rex-1.14.3 is now available on CPAN. It contains bug fixes for local package installation, command existence checks, and Git tests.

2023-05-05
Rex-1.14.2

The Rex-1.14.2 release is now available on CPAN. It contains bug fixes for running local commands on Windows, cloning git repositories, and test suite fixes for the upcoming perl-5.38.0 release.

2023-03-17
Call for papers TPRC 2023

Dean Hamstead from the The Perl and Raku Foundation Marketing Committee has sent an invitation to present about Rex at TPRC 2023. I’m posting it here to increase visibility.

2023-03-05
Rex-1.14.1

The Rex-1.14.1 release is now available on CPAN. It contains bug fixes and documentation updates.

2023-02-05
Rex-1.14.0

The Rex-1.14.0 release is now available on CPAN. It contains improved Rexfile loading, documentation updates, and bumps the minimum required Perl version to 5.12.5.

Events

2021-03-08
Learning automation using Rex

Ferenc Erki (FErki) will be the guest of Gábor Szabó on the next Code Maven live stream to learn about automation using Rex. Register for the free event via Code Maven or Meetup, and join the discussion!

2020-03-05
Unexpected use cases with Rex

Unexpected use cases with Rex at the 22nd German Perl/Raku Workshop 2020 in Erlangen by Ferenc Erki (FErki).

2019-11-09
Rex & Friends

Rex & Friends talk at the Barcelona Perl & Friends 2019 by Ferenc Erki (FErki).

» 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 Perl and built with Statocles

GitHub repository and discussions / Chat on Matrix and IRC / Mailing list on Google Groups (retired: rex-users@freelists)

MetaCPAN / Twitter / StackShare / Server Fault   -.ô.-   Disclaimer