1Rex::Commands::File(3)User Contributed Perl DocumentationRex::Commands::File(3)
2
3
4
6 Rex::Commands::File - Transparent File Manipulation
7
9 With this module you can manipulate files.
10
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
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)