1Rex::Commands::File(3)User Contributed Perl DocumentationRex::Commands::File(3)
2
3
4

NAME

6       Rex::Commands::File - Transparent File Manipulation
7

DESCRIPTION

9       With this module you can manipulate files.
10

SYNOPSIS

12        task "read_passwd", "server01", sub {
13          my $fh = file_read "/etc/passwd";
14          for my $line ($fh->read_all) {
15            print $line;
16          }
17          $fh->close;
18        };
19
20        task "read_passwd2", "server01", sub {
21          say cat "/etc/passwd";
22        };
23
24
25        task "write_passwd", "server01", sub {
26          my $fh = file_write "/etc/passwd";
27          $fh->write("root:*:0:0:root user:/root:/bin/sh\n");
28          $fh->close;
29        };
30
31        delete_lines_matching "/var/log/auth.log", matching => "root";
32        delete_lines_matching "/var/log/auth.log", matching => qr{Failed};
33        delete_lines_matching "/var/log/auth.log",
34                       matching => "root", qr{Failed}, "nobody";
35
36        file "/path/on/the/remote/machine",
37          source => "/path/on/local/machine";
38
39        file "/path/on/the/remote/machine",
40          content => "foo bar";
41
42        file "/path/on/the/remote/machine",
43          source => "/path/on/local/machine",
44          owner  => "root",
45          group  => "root",
46          mode  => 400,
47          on_change => sub { say "File was changed."; };
48

EXPORTED FUNCTIONS

50   template($file, @params)
51       Parse a template and return the content.
52
53       Embedded templates
54
55       Use "__DATA__" to embed templates at the end of the file. Prefix
56       embedded template names with "@". If embedding multiple templates, mark
57       their end with @end.
58
59       Single template
60
61        my $content = template( '@hello', name => 'world' ); # Hello, world!
62        __DATA__
63        @hello
64        Hello, <%= $name -%>!
65
66       Multiple templates
67
68       Use @end to separate multiple templates inside "__DATA__".
69
70        my $content     = template( '@hello', name => 'world' ); # Hello, world!
71        my $alternative = template( '@hi',    name => 'world' ); # Hi, world!
72
73        __DATA__
74        @hello
75        Hello, <%= $name -%>!
76        @end
77
78        @hi
79        Hi, <%= $name -%>!
80        @end
81
82       File templates
83
84        my $content = template("/files/templates/vhosts.tpl",
85                      name      => "test.lan",
86                      webmaster => 'webmaster@test.lan');
87
88       The file name specified is subject to "path_map" processing as
89       documented under the file() function to resolve to a physical file
90       name.
91
92       In addition to the "path_map" processing, if the -E command line switch
93       is used to specify an environment name, existence of a file ending with
94       '.<env>' is checked and has precedence over the file without one, if it
95       exists. E.g. if rex is started as:
96
97        $ rex -E prod task1
98
99       then in task1 defined as:
100
101        task "task1", sub {
102           say template("files/etc/ntpd.conf");
103        };
104
105       will print the content of 'files/etc/ntpd.conf.prod' if it exists.
106
107       Note: the appended environment mechanism is always applied, after the
108       'path_map' mechanism, if that is configured.
109
110   file($file_name, %options)
111       This function is the successor of install file. Please use this
112       function to upload files to your server.
113
114        task "prepare", "server1", "server2", sub {
115          file "/file/on/remote/machine",
116            source => "/file/on/local/machine";
117
118          file "/etc/hosts",
119            content => template("templates/etc/hosts.tpl"),
120            owner  => "user",
121            group  => "group",
122            mode   => 700,
123            on_change => sub { say "Something was changed." };
124
125          file "/etc/motd",
126            content => `fortune`;
127
128          file "/etc/named.conf",
129            content    => template("templates/etc/named.conf.tpl"),
130            no_overwrite => TRUE;  # this file will not be overwritten if already exists.
131
132          file "/etc/httpd/conf/httpd.conf",
133            source => "/files/etc/httpd/conf/httpd.conf",
134            on_change => sub { service httpd => "restart"; };
135
136          file "/etc/named.d",
137            ensure => "directory",  # this will create a directory
138            owner  => "root",
139            group  => "root";
140
141          file "/etc/motd",
142            ensure => "absent";   # this will remove the file or directory
143
144        };
145
146       The first parameter is either a string or an array reference. In the
147       latter case the function is called for all strings in the array.
148       Therefore, the following constructs are equivalent:
149
150         file '/tmp/test1', ensure => 'directory';
151         file '/tmp/test2', ensure => 'directory';
152
153         file [ qw( /tmp/test1 /tmp/test2 ) ], ensure => 'directory'; # use array ref
154
155         file [ glob('/tmp/test{1,2}') ], ensure => 'directory'; # explicit glob call for array contents
156
157       Use the glob carefully as it can leak local filesystem information
158       (e.g. when using wildcards).
159
160       The source is subject to a path resolution algorithm. This algorithm
161       can be configured using the set function to set the value of the
162       path_map variable to a hash containing path prefixes as its keys.  The
163       associated values are arrays listing the prefix replacements in order
164       of (decreasing) priority.
165
166         set "path_map", {
167           "files/" => [ "files/{environment}/{hostname}/_root_/",
168                         "files/{environment}/_root_/" ]
169         };
170
171       With this configuration, the file "files/etc/ntpd.conf" will be probed
172       for in the following locations:
173
174        - files/{environment}/{hostname}/_root_/etc/ntpd.conf
175        - files/{environment}/_root_/etc/ntpd.conf
176        - files/etc/ntpd.conf
177
178       Furthermore, if a path prefix matches multiple prefix entries in
179       'path_map', e.g. "files/etc/ntpd.conf" matching both "files/" and
180       "files/etc/", the longer matching prefix(es) have precedence over
181       shorter ones. Note that keys without a trailing slash (i.e.
182       "files/etc") will be treated as having a trailing slash when matching
183       the prefix ("files/etc/").
184
185       If no file is found using the above procedure and source is relative,
186       it will search from the location of your Rexfile or the .pm file if you
187       use Perl packages.
188
189       All the possible variables ('{environment}', '{hostname}', ...) are
190       documented in the CMDB YAML documentation.
191
192       This function supports the following hooks:
193
194       before  This gets executed before everything is done. The return value
195               of this hook overwrite the original parameters of the function-
196               call.
197
198       before_change
199               This gets executed right before the new file is written. Only
200               with content parameter. For the source parameter the hook of
201               the upload function is used.
202
203       after_change
204               This gets executed right after the file was written. Only with
205               content parameter. For the source parameter the hook of the
206               upload function is used.
207
208       after   This gets executed right before the file() function returns.
209
210   file_write($file_name)
211       This function opens a file for writing (it will truncate the file if it
212       already exists). It returns a Rex::FS::File object on success.
213
214       On failure it will die.
215
216        my $fh;
217        eval {
218          $fh = file_write("/etc/groups");
219        };
220
221        # catch an error
222        if($@) {
223          print "An error occured. $@.\n";
224        }
225
226        # work with the filehandle
227        $fh->write("...");
228        $fh->close;
229
230   file_append($file_name)
231   file_read($file_name)
232       This function opens a file for reading. It returns a Rex::FS::File
233       object on success.
234
235       On failure it will die.
236
237        my $fh;
238        eval {
239          $fh = read("/etc/groups");
240        };
241
242        # catch an error
243        if($@) {
244          print "An error occured. $@.\n";
245        }
246
247        # work with the filehandle
248        my $content = $fh->read_all;
249        $fh->close;
250
251   cat($file_name)
252       This function returns the complete content of $file_name as a string.
253
254        print cat "/etc/passwd";
255
256   delete_lines_matching($file, $regexp)
257       Delete lines that match $regexp in $file.
258
259        task "clean-logs", sub {
260           delete_lines_matching "/var/log/auth.log" => "root";
261        };
262
263   delete_lines_according_to($search, $file, @options)
264       This is the successor of the delete_lines_matching() function. This
265       function also allows the usage of an on_change hook.
266
267       It will search for $search in $file and remove the found lines. If
268       on_change hook is present it will execute this if the file was changed.
269
270        task "cleanup", "server1", sub {
271          delete_lines_according_to qr{^foo:}, "/etc/passwd",
272           on_change => sub {
273             say "removed user foo.";
274           };
275        };
276
277   append_if_no_such_line($file, $new_line, @regexp)
278       Append $new_line to $file if none in @regexp is found. If no regexp is
279       supplied, the line is appended unless there is already an identical
280       line in $file.
281
282        task "add-group", sub {
283          append_if_no_such_line "/etc/groups", "mygroup:*:100:myuser1,myuser2", on_change => sub { service sshd => "restart"; };
284        };
285
286       Since 0.42 you can use named parameters as well
287
288        task "add-group", sub {
289          append_if_no_such_line "/etc/groups",
290            line  => "mygroup:*:100:myuser1,myuser2",
291            regexp => qr{^mygroup},
292            on_change => sub {
293                       say "file was changed, do something.";
294                     };
295
296          append_if_no_such_line "/etc/groups",
297            line  => "mygroup:*:100:myuser1,myuser2",
298            regexp => [qr{^mygroup:}, qr{^ourgroup:}]; # this is an OR
299        };
300
301   append_or_amend_line($file, $line, @regexp)
302       Similar to append_if_no_such_line, but if the line in the regexp is
303       found, it will be updated. Otherwise, it will be appended.
304
305        task "update-group", sub {
306          append_or_amend_line "/etc/groups",
307            line  => "mygroup:*:100:myuser3,myuser4",
308            regexp => qr{^mygroup},
309            on_change => sub {
310                       say "file was changed, do something.";
311                     };
312        };
313
314   extract($file [, %options])
315       This function extracts a file. The target directory optionally
316       specified with the `to` option will be created automatically.
317
318       Supported formats are .box, .tar, .tar.gz, .tgz, .tar.Z, .tar.bz2,
319       .tbz2, .zip, .gz, .bz2, .war, .jar.
320
321        task prepare => sub {
322          extract "/tmp/myfile.tar.gz",
323           owner => "root",
324           group => "root",
325           to   => "/etc";
326
327          extract "/tmp/foo.tgz",
328           type => "tgz",
329           mode => "g+rwX";
330        };
331
332       Can use the type=> option if the file suffix has been changed. (types
333       are tar, tgz, tbz, zip, gz, bz2)
334
335   sed($search, $replace, $file)
336       Search some string in a file and replace it.
337
338        task sar => sub {
339          # this will work line by line
340          sed qr{search}, "replace", "/var/log/auth.log";
341
342          # to use it in a multiline way
343          sed qr{search}, "replace", "/var/log/auth.log",
344           multiline => TRUE;
345        };
346
347
348
349perl v5.30.2                      2020-04-06            Rex::Commands::File(3)
Impressum