You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
7.7 KiB
210 lines
7.7 KiB
#!/usr/bin/perl |
|
# |
|
# This handles moving around and managing files on Anvil! nodes, DR hosts and Striker dashboards. |
|
# |
|
# When this is called (periodically by the daemon of after an upload / ISO generation); |
|
# - 1. Check 'incoming/' for files. For any found, generate an md5sum and see if the file name and sum match |
|
# anything in the database from any host; |
|
# - If so, update/add an entry in 'file_locations' |
|
# - If not, create a new entry in 'files' and then add the first entry in 'file_locations' |
|
# - 2. Check 'file_locations' for any files on this system, and verify they exist still. |
|
# - If not, check the other files for one with a matching md5sum. If found, handle as a rename. |
|
# - If not found at all, search for the file according to the search rules and copy to here if found. |
|
# - If not found anywhere, remove it from 'file_locations' and send an alert. |
|
# - If found, check the size. If it differs, recalculate the md5sum. |
|
# - 3. If called with '--rename --file <filename> --to <newname>', rename the file and update 'files'. |
|
# - 4. If called with '--delete', remove from 'file_locations' and then remove from the local storage. If |
|
# also used with '--everywhere', then all copies on all systems we know about will be deleted. This is |
|
# done by registering a job against all known hosts. As such, if this is called and the target file |
|
# doesn't exist, it just clears the job and then exits. |
|
# - 5. If called with '--is-script=[0|1]', mark as 'script' in the 'files' table and set/remove the executable bit. |
|
# |
|
# Exit codes; |
|
# 0 = Normal exit or md5sum of this program changed and it exited to reload. |
|
# 1 = No databases available. |
|
# 2 = Another process that is still running has picked up this job. |
|
# 3 = No filename specified when needed by another switch. |
|
# 4 = Request to change the file name but the new name wasn't given. |
|
# 5 = The file specified was not found. |
|
# 6 = The file to delete is not under '/mnt/shared/'. |
|
# |
|
# TODO: |
|
# - |
|
# |
|
# NOTE: |
|
# - |
|
# |
|
|
|
use strict; |
|
use warnings; |
|
use Anvil::Tools; |
|
use Data::Dumper; |
|
|
|
|
|
# Disable buffering |
|
$| = 1; |
|
|
|
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; |
|
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; |
|
if (($running_directory =~ /^\./) && ($ENV{PWD})) |
|
{ |
|
$running_directory =~ s/^\./$ENV{PWD}/; |
|
} |
|
|
|
my $anvil = Anvil::Tools->new(); |
|
|
|
$anvil->data->{switches}{'job-uuid'} = ""; |
|
$anvil->data->{switches}{'rename'} = ""; |
|
$anvil->data->{switches}{'is-script'} = ""; |
|
$anvil->data->{switches}{file} = ""; |
|
$anvil->data->{switches}{to} = ""; |
|
$anvil->data->{switches}{'delete'} = ""; |
|
$anvil->data->{switches}{everywhere} = ""; |
|
$anvil->Get->switches; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"switches::job-uuid" => $anvil->data->{switches}{'job-uuid'}, |
|
"switches::rename" => $anvil->data->{switches}{'rename'}, |
|
"switches::is-script" => $anvil->data->{switches}{'is-script'}, |
|
"switches::file" => $anvil->data->{switches}{file}, |
|
"switches::to" => $anvil->data->{switches}{to}, |
|
"switches::delete" => $anvil->data->{switches}{'delete'}, |
|
"switches::everywhere" => $anvil->data->{switches}{everywhere}, |
|
}}); |
|
|
|
# Connect or die |
|
$anvil->Database->connect; |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"}); |
|
if (not $anvil->data->{sys}{database}{connections}) |
|
{ |
|
# No databases, exit. |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0003"}); |
|
$anvil->nice_exit({exit_code => 1}); |
|
} |
|
|
|
# If we have a job_uuid, pick it up. |
|
if ($anvil->data->{switches}{'job-uuid'}) |
|
{ |
|
my $return = $anvil->Job->get_job_details({check => 1, job_uuid => $anvil->data->{switches}{'job-uuid'}}); |
|
if ($return == 1) |
|
{ |
|
# It's not a UUID. |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { 'return' => $return }}); |
|
$anvil->nice_exit({code => 2}); |
|
} |
|
if ($return == 2) |
|
{ |
|
# This job is being handled by another process that is still alive. |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { 'return' => $return }}); |
|
$anvil->nice_exit({code => 3}); |
|
} |
|
|
|
# If there's a progress, clear it. |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { 'job::job_progress' => $anvil->data->{job}{job_progress} }}); |
|
if ($anvil->data->{job}{job_progress}) |
|
{ |
|
$anvil->Job->update_progress({ |
|
progress => 1, |
|
message => "clear", |
|
job_uuid => $anvil->data->{jobs}{'job-uuid'}, |
|
}); |
|
} |
|
} |
|
|
|
# What are we doing? |
|
if ($anvil->data->{switches}{'rename'}) |
|
{ |
|
handle_rename($anvil); |
|
} |
|
elsif ($anvil->data->{switches}{'delete'})) |
|
{ |
|
handle_delete($anvil); |
|
} |
|
|
|
# We're done |
|
$anvil->nice_exit({exit_code => 0}); |
|
|
|
|
|
############################################################################################################# |
|
# Private functions. # |
|
############################################################################################################# |
|
|
|
# This handles deleting a file. If the requested deletion target doesn't exist, we'll just clear the |
|
# database. If that doesn't exist either, we still don't error. This is to handle broad requests to delete a |
|
# file everywhere. If we're asked to delete it everywhere, then we'll register a job against all hosts. |
|
sub handle_delete |
|
{ |
|
my ($anvil) = @_; |
|
|
|
if (not $anvil->data->{switches}{file}) |
|
{ |
|
# Um... |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0052"}); |
|
$anvil->nice_exit({exit_code => 3}); |
|
} |
|
elsif ($anvil->data->{switches}{file} !~ /^\/mnt\/shared\//) |
|
{ |
|
# We don't do that here... |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0053", variables => { file => $anvil->data->{switches}{file} }}); |
|
$anvil->nice_exit({exit_code => 6}); |
|
} |
|
|
|
# Does the file exist? |
|
if (-e $anvil->data->{switches}{file}) |
|
{ |
|
# Delete it. |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0263", variables => { file => $anvil->data->{switches}{file} }}); |
|
|
|
unlink $anvil->data->{switches}{file}; |
|
|
|
# Sleep and verify |
|
sleep 1; |
|
if (-e $anvil->data->{switches}{file}) |
|
{ |
|
# Failed to delete... |
|
# TODO: |
|
} |
|
else |
|
{ |
|
# Deleted successfully. Remove from 'file_locations' |
|
### TODO: Find the file_uuid, then if found, see if we have and entry in file_location and then delete it. |
|
} |
|
} |
|
|
|
return(0); |
|
} |
|
|
|
# This handles renaming files. |
|
sub handle_rename |
|
{ |
|
my ($anvil) = @_; |
|
|
|
# Do we have the current file name and the new one? |
|
if (not $anvil->data->{switches}{file}) |
|
{ |
|
# Um... |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0049"}); |
|
$anvil->nice_exit({exit_code => 3}); |
|
} |
|
elsif (not $anvil->data->{switches}{to}) |
|
{ |
|
# We need a target |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0050", variables => { file => $anvil->data->{switches}{file} }}); |
|
$anvil->nice_exit({exit_code => 4}); |
|
} |
|
elsif (not -f $anvil->data->{switches}{file}) |
|
{ |
|
# The file to rename doesn't exist. |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0051", variables => { file => $anvil->data->{switches}{file} }}); |
|
$anvil->nice_exit({exit_code => 5}); |
|
} |
|
elsif (-e $anvil->data->{switches}{to}) |
|
{ |
|
# There's already a file (or directory or something) with that name. |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0052", variables => { file => $anvil->data->{switches}{file}, to => $anvil->data->{switches}{to} }}); |
|
$anvil->nice_exit({exit_code => 6}); |
|
} |
|
|
|
### TODO: Left off here |
|
|
|
return(0); |
|
}
|
|
|