package RemoteFile 0.000001; use Carp; use Moose; use Modern::Perl; use File::Basename; use File::Slurper qw(read_text write_text); use Params::Validate; with 'MyOpenSSH', 'MyLogger2', 'DownloadDir'; use namespace::autoclean; has 'path' => (is => 'ro', isa => 'Str', required => 1, lazy => 0, writer => '_set_path', default => '' ); has 'gid' => (is => 'rw', isa => 'Int', required => 0, lazy => 1, default => '' ); has 'uid' => (is => 'rw', isa => 'Int', required => 0, lazy => 1, default => '' ); has 'perms' => (is => 'rw', isa => 'Value', required => 0, lazy => 1, default => '' ); has 'filename' => (is => 'rw', isa => 'Str', required => 0, lazy => 1, default => '' ); has 'localfile' => (is => 'rw', isa => 'Str', required => 0, lazy => 1, default => '' ); sub BUILD { my $self = shift; my $path = $self->path; $self->logt('building remotefile'); # make sure something exists at path given my $exists = $self->grab(_one_liner("-e('$path')")); $self->logf("$path does not exist at " . $self->get_host) if !$exists; # get absolute path of file if it is a symlink my $is_symlink = undef; while ($is_symlink = $self->grab(_one_liner("-l('$path')"))) { my $dir = dirname($path); my $cmd = _one_liner("Cwd::abs_path(readlink('$path'))", 'Cwd', $dir); my $abs_path = $self->grab($cmd); $self->_set_path($abs_path); $path = $abs_path; } # make sure we are dealing with a file my $is_file = $self->_file_exists($path); $self->logf("$path is not a file at " . $self->get_host) if !$is_file; # fetch data about the file my $uid = $self->grab(_one_liner("(stat '$path')[4]")); my $gid = $self->grab(_one_liner("(stat '$path')[5]")); my $mode = $self->grab(_one_liner("(stat '$path')[2]")); my $perms = sprintf ("%04o", $mode & 07777); my ($filename) = fileparse($path); # set some object attributes $self->gid($gid); $self->uid($uid); $self->perms($perms); $self->filename($filename); $self->localfile($self->dl_dir . $self->filename); # make sure we have a fresh copy of file and download to local machine unlink ($self->dl_dir . $self->filename); my %rsync_options = (rsync_path => 'sudo rsync', quiet => 1); $self->rsync_get(\%rsync_options, $self->path, $self->dl_dir); } sub append_file { my $self = shift; $self->logi('Appending local file'); validate_pos( @_, 1 ); my $text_to_append = shift; my $local_file = $self->localfile; open(my $fh, '>>', $local_file) or $self->logf("could not open $local_file to append"); print $fh $text_to_append; close $fh; } sub sandr { my $self = shift; my $search = shift; my $replace = shift; $self->logi('Search $'); my $text = read_text($self->localfile, 'UTF-8', 1); $text =~ s/$search/$replace/gim; write_text($self->localfile, $text, 'UTF-8', 1); } sub read_and_delete { my $self = shift; my $content = read_text($self->localfile, 'UTF-8', 1); unlink ($self->localfile); return $content; } sub upload_file { my $self = shift; $self->logi('Uploading file to server'); my $local_file = $self->localfile; my $path = shift || $self->path; my $staging_file = "/home/me/tmp/tmp_file"; my $is_file = $self->_file_exists($staging_file); $self->exec("sudo rm $staging_file") if $is_file; $self->scp_put($local_file, $staging_file) or $self->logf("Could not cp $local_file to server."); $self->exec('sudo chmod ' . oct($self->perms) . " $staging_file"); $self->exec("sudo chown root:root $staging_file"); $self->exec("sudo cp $staging_file $path"); $self->exec("sudo rm $staging_file"); unlink($self->localfile); $self->logi('File uploaded successfully.'); }