Rex
view release on metacpan or search on metacpan
lib/Rex/Commands/File.pm view on Meta::CPAN
elsif ( ( exists $option->{content} || exists $option->{source} )
&& !$is_directory )
{
# first upload file to tmp location, to get md5 sum.
# than we can decide if we need to replace the current (old) file.
my $tmp_file_name = get_tmp_file_name($file);
if ( exists $option->{content} ) {
my $fh = file_write($tmp_file_name);
my @lines = split( qr{$/}, $option->{"content"} );
for my $line (@lines) {
$fh->write( $line . $/ );
}
$fh->close;
}
elsif ( exists $option->{source} ) {
$option->{source} =
Rex::Helper::Path::get_file_path( $option->{source}, caller );
upload $option->{source}, $tmp_file_name;
}
# now get md5 sums
eval { $old_md5 = md5($file); };
$new_md5 = md5($tmp_file_name);
if ( $new_md5 && $old_md5 && $new_md5 eq $old_md5 ) {
Rex::Logger::debug(
"No need to overwrite existing file. Old and new files are the same. $old_md5 eq $new_md5."
);
# md5 sums are the same, delete tmp.
$fs->unlink($tmp_file_name);
$need_md5 = 0; # we don't need to execute on_change hook
Rex::get_current_connection()->{reporter}->report(
changed => 0,
message =>
"No need to overwrite existing file. Old and new files are the same. $old_md5 eq $new_md5."
);
}
else {
$old_md5 ||= "";
Rex::Logger::debug(
"Need to use the new file. md5 sums are different. <<$old_md5>> = <<$new_md5>>"
);
#### check and run before_change hook
Rex::Hook::run_hook( file => "before_change", $file, %{$option} );
##############################
if (Rex::is_sudo) {
my $current_options =
Rex::get_current_connection_object()->get_current_sudo_options;
Rex::get_current_connection_object()->push_sudo_options( {} );
if ( exists $current_options->{user} ) {
$fs->chown( "$current_options->{user}:", $tmp_file_name );
}
}
$fs->rename( $tmp_file_name, $file );
Rex::get_current_connection_object()->pop_sudo_options()
if (Rex::is_sudo);
$__ret = { changed => 1 };
Rex::get_current_connection()->{reporter}->report(
changed => 1,
message => "File updated. old md5: $old_md5, new md5: $new_md5"
);
#### check and run after_change hook
Rex::Hook::run_hook( file => "after_change", $file, %{$option}, $__ret );
##############################
}
}
if ( exists $option->{"ensure"} ) {
if ( $option->{ensure} eq "present" ) {
if ( !$fs->is_file($file) ) {
#### check and run before_change hook
Rex::Hook::run_hook( file => "before_change", $file, %{$option} );
##############################
my $fh = file_write($file);
$fh->write("");
$fh->close;
$__ret = { changed => 1 };
Rex::get_current_connection()->{reporter}->report(
changed => 1,
message => "file is now present, with no content",
);
#### check and run after_change hook
Rex::Hook::run_hook(
file => "after_change",
$file, %{$option}, $__ret
);
##############################
}
elsif ( !$__ret->{changed} ) {
$__ret = { changed => 0 };
Rex::get_current_connection()->{reporter}->report( changed => 0, );
}
}
elsif ( $option->{ensure} eq "absent" ) {
$need_md5 = 0;
#### check and run before_change hook
Rex::Hook::run_hook( file => "before_change", $file, %{$option} );
##############################
lib/Rex/Commands/File.pm view on Meta::CPAN
if ( exists $option->{group} ) {
$dir_option{group} = $option->{group};
}
if ( exists $option->{mode} ) {
$dir_option{mode} = $option->{mode};
}
Rex::Commands::Fs::mkdir( $file, %dir_option, on_change => $on_change );
}
}
if ( !exists $option->{content}
&& !exists $option->{source}
&& $option->{ensure} ne "absent" )
{
# no content and no source, so just verify that the file is present
if ( !$fs->is_file($file) && !$is_directory ) {
#### check and run before_change hook
Rex::Hook::run_hook( file => "before_change", $file, %{$option} );
##############################
my $fh = file_write($file);
$fh->write("");
$fh->close;
my $f_type = "file is now present, with no content";
if ( exists $option->{ensure} && $option->{ensure} eq "directory" ) {
$f_type = "directory is now present";
}
Rex::get_current_connection()->{reporter}->report(
changed => 1,
message => $f_type,
);
#### check and run after_change hook
Rex::Hook::run_hook( file => "after_change", $file, %{$option}, $__ret );
##############################
}
}
if ( $option->{ensure} ne "absent" ) {
if ($need_md5) {
eval { $new_md5 = md5($file); };
}
my %stat_old = $fs->stat($file);
if ( exists $option->{"mode"} ) {
$fs->chmod( $option->{"mode"}, $file );
}
if ( exists $option->{"group"} ) {
$fs->chgrp( $option->{"group"}, $file );
}
if ( exists $option->{"owner"} ) {
$fs->chown( $option->{"owner"}, $file );
}
my %stat_new = $fs->stat($file);
if ( %stat_old && %stat_new && $stat_old{mode} ne $stat_new{mode} ) {
Rex::get_current_connection()->{reporter}->report(
changed => 1,
message =>
"File-System permissions changed from $stat_old{mode} to $stat_new{mode}.",
);
}
if ( %stat_old && %stat_new && $stat_old{uid} ne $stat_new{uid} ) {
Rex::get_current_connection()->{reporter}->report(
changed => 1,
message => "Owner changed from $stat_old{uid} to $stat_new{uid}.",
);
}
if ( %stat_old && %stat_new && $stat_old{gid} ne $stat_new{gid} ) {
Rex::get_current_connection()->{reporter}->report(
changed => 1,
message => "Group changed from $stat_old{gid} to $stat_new{gid}.",
);
}
}
my $on_change_done = 0;
if ($need_md5) {
unless ( $old_md5 && $new_md5 && $old_md5 eq $new_md5 ) {
$old_md5 ||= "";
$new_md5 ||= "";
Rex::Logger::debug("File $file has been changed... Running on_change");
Rex::Logger::debug("old: $old_md5");
Rex::Logger::debug("new: $new_md5");
&$on_change($file);
$on_change_done = 1;
Rex::get_current_connection()->{reporter}->report(
changed => 1,
message => "Content changed.",
);
$__ret = { changed => 1 };
}
}
if ( $__ret->{changed} == 1 && $on_change_done == 0 ) {
&$on_change($file);
}
elsif ( $__ret->{changed} == 0 ) {
Rex::Logger::debug(
"File $file has not been changed... Running on_no_change");
&$on_no_change($file);
}
lib/Rex/Commands/File.pm view on Meta::CPAN
=cut
sub extract {
my ( $file, %option ) = @_;
$file = resolv_path($file);
my $pre_cmd = "";
my $to = ".";
my $type = "";
if ( $option{chdir} ) {
$to = $option{chdir};
}
if ( $option{to} ) {
$to = $option{to};
}
$to = resolv_path($to);
if ( $option{type} ) {
$type = $option{type};
}
Rex::Commands::Fs::mkdir($to);
$pre_cmd = "cd $to; ";
my $exec = Rex::Interface::Exec->create;
my $cmd = "";
if ( $type eq 'tgz'
|| $file =~ m/\.tar\.gz$/
|| $file =~ m/\.tgz$/
|| $file =~ m/\.tar\.Z$/ )
{
$cmd = "${pre_cmd}gunzip -c $file | tar -xf -";
}
elsif ( $type eq 'tbz' || $file =~ m/\.tar\.bz2/ || $file =~ m/\.tbz2/ ) {
$cmd = "${pre_cmd}bunzip2 -c $file | tar -xf -";
}
elsif ( $type eq 'tar' || $file =~ m/\.(tar|box)/ ) {
$cmd = "${pre_cmd}tar -xf $file";
}
elsif ( $type eq 'zip' || $file =~ m/\.(zip|war|jar)$/ ) {
$cmd = "${pre_cmd}unzip -o $file";
}
elsif ( $type eq 'gz' || $file =~ m/\.gz$/ ) {
$cmd = "${pre_cmd}gunzip -f $file";
}
elsif ( $type eq 'bz2' || $file =~ m/\.bz2$/ ) {
$cmd = "${pre_cmd}bunzip2 -f $file";
}
else {
Rex::Logger::info("File not supported.");
die("File ($file) not supported.");
}
$exec->exec($cmd);
my $fs = Rex::Interface::Fs->create;
if ( $option{owner} ) {
$fs->chown( $option{owner}, $to, recursive => 1 );
}
if ( $option{group} ) {
$fs->chgrp( $option{group}, $to, recursive => 1 );
}
if ( $option{mode} ) {
$fs->chmod( $option{mode}, $to, recursive => 1 );
}
}
=head2 sed($search, $replace, $file [, %options])
Search some string in a file and replace it.
task sar => sub {
# this will work line by line
sed qr{search}, "replace", "/var/log/auth.log";
# to use it in a multiline way
sed qr{search}, "replace", "/var/log/auth.log",
multiline => TRUE;
};
Like similar file management commands, it also supports C<on_change> and C<on_no_change> hooks.
=cut
sub sed {
my ( $search, $replace, $file, @option ) = @_;
$file = resolv_path($file);
my $options = {};
Rex::get_current_connection()->{reporter}
->report_resource_start( type => "sed", name => $file );
if ( ref( $option[0] ) ) {
$options = $option[0];
}
else {
$options = {@option};
}
my $on_change = $options->{"on_change"} || undef;
my $on_no_change = $options->{"on_no_change"} || undef;
my @content;
if ( exists $options->{multiline} ) {
$content[0] = cat($file);
$content[0] =~ s/$search/$replace/gms;
}
else {
@content = split( /\n/, cat($file) );
for (@content) {
s/$search/$replace/;
}
}
( run in 0.914 second using v1.01-cache-2.11-cpan-5511b514fd6 )