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