* Did some more work on anvil-manage-files.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 6 years ago
parent 0d62a28fda
commit e3d11fd938
  1. 2
      Anvil/Tools/Database.pm
  2. 5
      Anvil/Tools/Job.pm
  3. 4
      Anvil/Tools/Storage.pm
  4. 2
      share/anvil.sql
  5. 2
      share/words.xml
  6. 208
      tools/anvil-manage-files

@ -2401,7 +2401,7 @@ This is the sum as calculated when the file is first uploaded. Once recorded, it
=head3 file_type (required) =head3 file_type (required)
This is the file's type/purpose. The expected values are 'iso' (disc image a new server can be installed from or mounted in a virtual optical drive), 'repo_rpm' (a package to install on a guest that provides access to Anvil! RPM software), 'script' (pre or post migration scripts), 'image' (images to use for newly created servers, instead of installing from an ISO or PXE), or 'other'. This is the file's type/purpose. The expected values are 'iso' (disc image a new server can be installed from or mounted in a virtual optical drive), 'rpm' (a package to install on a guest that provides access to Anvil! RPM software), 'script' (pre or post migration scripts), 'image' (images to use for newly created servers, instead of installing from an ISO or PXE), or 'other'.
=cut =cut
sub insert_or_update_files sub insert_or_update_files

@ -519,11 +519,12 @@ sub update_progress
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { job_uuid => $job_uuid }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { job_uuid => $job_uuid }});
} }
# Return if we still don't have a job_uuid # Return if we still don't have a job_uuid. This isn't unexpected as some programs can run with or
# without a job_uuid.
if (not $job_uuid) if (not $job_uuid)
{ {
# Nothing we can do. # Nothing we can do.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, priority => "alert", key => "log_0207"}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0207"});
return(1); return(1);
} }

@ -357,7 +357,7 @@ sub change_mode
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Storage->change_mode()", parameter => "mode" }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Storage->change_mode()", parameter => "mode" }});
$error = 1; $error = 1;
} }
elsif (($mode !~ /^\d\d\d$/) && ($mode !~ /^\d\d\d\d$/)) elsif (($mode !~ /^\d\d\d$/) && ($mode !~ /^\d\d\d\d$/) && ($mode !~ /^\w\+\w$/) && ($mode !~ /^\w\-\w$/))
{ {
# Invalid mode # Invalid mode
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "log_0038", variables => { mode => $mode }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "log_0038", variables => { mode => $mode }});
@ -1738,7 +1738,7 @@ sub rsync
=head2 scan_directory =head2 scan_directory
TODO: Wtite this...
=cut =cut
### TODO: Make this work on remote systems ### TODO: Make this work on remote systems

@ -1104,7 +1104,7 @@ CREATE TABLE files (
file_name text not null, -- This is the file's name. It can change without re-uploading the file. file_name text not null, -- This is the file's name. It can change without re-uploading the file.
file_size numeric not null, -- This is the file's size in bytes. If it recorded as a quick way to determine if a file has changed on disk. file_size numeric not null, -- This is the file's size in bytes. If it recorded as a quick way to determine if a file has changed on disk.
file_md5sum text not null, -- This is the sum as calculated when the file is first uploaded. Once recorded, it can't change. file_md5sum text not null, -- This is the sum as calculated when the file is first uploaded. Once recorded, it can't change.
file_type text not null, -- This is; 'iso', 'repo_rpm', 'script', or 'backup'. file_type text not null, -- This is the file's type/purpose. The expected values are 'iso', 'rpm', 'script', 'disk-image', or 'other'.
modified_date timestamp with time zone not null modified_date timestamp with time zone not null
); );
ALTER TABLE files OWNER TO admin; ALTER TABLE files OWNER TO admin;

@ -816,6 +816,8 @@ The update appears to have not completed successfully. The output was:
<key name="error_0051">A request to rename the file: [#!variable!file!#] to: [#!variable!to!#], but there is an existing file or directory with that name.</key> <key name="error_0051">A request to rename the file: [#!variable!file!#] to: [#!variable!to!#], but there is an existing file or directory with that name.</key>
<key name="error_0052">A request to delete a file was made, but no file name was given.</key> <key name="error_0052">A request to delete a file was made, but no file name was given.</key>
<key name="error_0053">A request to delete the file: [#!variable!file!#] was received, but it is not under '/mnt/shared/'. This program can only work on or under that directory.</key> <key name="error_0053">A request to delete the file: [#!variable!file!#] was received, but it is not under '/mnt/shared/'. This program can only work on or under that directory.</key>
<key name="error_0054">Failed!</key>
<key name="error_0055">A request to toggle the script flag was received, but no file name was given.</key>
<!-- These are units, words and so on used when displaying information. --> <!-- These are units, words and so on used when displaying information. -->
<key name="unit_0001">Yes</key> <key name="unit_0001">Yes</key>

@ -119,6 +119,11 @@ elsif ($anvil->data->{switches}{'delete'}))
{ {
handle_delete($anvil); handle_delete($anvil);
} }
elsif ($anvil->data->{switches}{'is-script'}))
{
handle_script($anvil);
}
# We're done # We're done
$anvil->nice_exit({exit_code => 0}); $anvil->nice_exit({exit_code => 0});
@ -128,6 +133,178 @@ $anvil->nice_exit({exit_code => 0});
# Private functions. # # Private functions. #
############################################################################################################# #############################################################################################################
# This gets the file_uuid for a given file name and/or md5sum. If the file isn't found, an empty string is
# returned.
sub get_file_uuid
{
my ($anvil, $file_md5sum, $file_name) = @_;
$file_md5sum = "" if not defined $file_md5sum;
$file_name = "" if not defined $file_name;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
file_md5sum => $file_md5sum,
file_name => $file_name,
}});
### TODO: At some point, we'll need to deal with the possibility that the same file name with
### different md5sums might exist in the database.
# If I have the md5sum, search using that. If I have the filename only, then we'll fall back to that.
my $query = "
SELECT
file_uuid
FROM
files
WHERE
";
if ($file_md5sum)
{
$query .= " file_md5sum = ".$anvil->data->{sys}{database}{use_handle}->quote($file_md5sum)."\n";
}
elsif ($file_name)
{
$query .= " file_name = ".$anvil->data->{sys}{database}{use_handle}->quote($file_name)."\n";
}
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
if (not $count)
{
# File wasn't found in the database
return("");
}
my $file_uuid = $results->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
file_uuid => $file_uuid,
}});
return($file_uuid);
}
# This handles toggling a file to marked or unmarked as a script.
sub handle_script
{
my ($anvil) = @_;
if (not $anvil->data->{switches}{file})
{
# Um...
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0055"});
if ($anvil->data->{jobs}{'job-uuid'})
$anvil->Job->update_progress({
progress => 0,
message => "error_0055",
job_uuid => $anvil->data->{jobs}{'job-uuid'},
});
$anvil->nice_exit({exit_code => 3});
}
# Find the file_uuid.
my ($file_uuid) = get_file_uuid($anvil, "", $anvil->data->{switches}{file});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { file_uuid => $file_uuid }});
# Toggle the executable bits.
if ($anvil->data->{switches}{'is-script'})
{
# Is it already executable?
if (-x $anvil->data->{switches}{file})
{
# Switch it on
$anvil->Storage->change_mode({target => $anvil->data->{switches}{file}, mode => "a+x"});
}
else
{
# Already a script.
}
}
else
{
# Is it executable?
if (-x $anvil->data->{switches}{file})
{
# Switch it off.
$anvil->Storage->change_mode({target => $anvil->data->{switches}{file}, mode => "a-x"});
}
else
{
# Already not a script.
}
}
# If we have a file UUID, update the 'file_type
if ($file_uuid)
{
# Load the details.
my $query = "
SELECT
file_name,
file_size,
file_md5sum,
file_type
FROM
files
WHERE
file_uuid = ".$anvil->data->{sys}{database}{use_handle}->quote($file_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { results => $results }});
my $file_name = $results->[0]->[0];
my $file_size = $results->[0]->[1];
my $file_md5sum = $results->[0]->[2];
my $file_type = $results->[0]->[3];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
file_name => $file_name,
file_size => $file_size,
file_md5sum => $file_md5sum,
file_type => $file_type,
}});
if (($file_type eq "script") && (not $anvil->data->{switches}{'is-script'}))
{
# Figure out what the file type is and update.
my $mimetype = mimetype($full_path);
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mimetype => $mimetype }});
my $say_mimetype = "other";
if ($mimetype =~ /cd-image/)
{
$say_mimetype = "iso";
}
elsif ($mimetype =~ /rpm$/)
{
$say_mimetype = "rpm";
}
elsif ($mimetype =~ /disk-image/)
{
$say_mimetype = "disk-image";
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_mimetype => $say_mimetype }});
$anvil->Database->insert_or_update_files({
file_uuid => $file_uuid,
file_name => $anvil->data->{switches}{file},
file_size => $file_size,
file_md5sum => $file_md5sum,
file_type => $say_mimetype,
});
}
elsif ($file_type ne "script") && ($anvil->data->{switches}{'is-script'}))
{
# Change the file tpye to "script"
$anvil->Database->insert_or_update_files({
file_uuid => $file_uuid,
file_name => $anvil->data->{switches}{file},
file_size => $file_size,
file_md5sum => $file_md5sum,
file_type => "script",
});
}
}
return(0);
}
# This handles deleting a file. If the requested deletion target doesn't exist, we'll just clear the # 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 # 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. # file everywhere. If we're asked to delete it everywhere, then we'll register a job against all hosts.
@ -139,12 +316,23 @@ sub handle_delete
{ {
# Um... # Um...
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0052"}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0052"});
if ($anvil->data->{jobs}{'job-uuid'})
$anvil->Job->update_progress({
progress => 0,
message => "error_0052",
job_uuid => $anvil->data->{jobs}{'job-uuid'},
});
$anvil->nice_exit({exit_code => 3}); $anvil->nice_exit({exit_code => 3});
} }
elsif ($anvil->data->{switches}{file} !~ /^\/mnt\/shared\//) elsif ($anvil->data->{switches}{file} !~ /^\/mnt\/shared\//)
{ {
# We don't do that here... # 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->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0053", variables => { file => $anvil->data->{switches}{file} }});
$anvil->Job->update_progress({
progress => 0,
message => "error_0053,!!file!".$anvil->data->{switches}{file}."!!",
job_uuid => $anvil->data->{jobs}{'job-uuid'},
});
$anvil->nice_exit({exit_code => 6}); $anvil->nice_exit({exit_code => 6});
} }
@ -183,24 +371,44 @@ sub handle_rename
{ {
# Um... # Um...
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0049"}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0049"});
$anvil->Job->update_progress({
progress => 0,
message => "error_0049",
job_uuid => $anvil->data->{jobs}{'job-uuid'},
});
$anvil->nice_exit({exit_code => 3}); $anvil->nice_exit({exit_code => 3});
} }
elsif (not $anvil->data->{switches}{to}) elsif (not $anvil->data->{switches}{to})
{ {
# We need a target # 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->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0050", variables => { file => $anvil->data->{switches}{file} }});
$anvil->Job->update_progress({
progress => 0,
message => "error_0050,!!file!".$anvil->data->{switches}{file}."!!",
job_uuid => $anvil->data->{jobs}{'job-uuid'},
});
$anvil->nice_exit({exit_code => 4}); $anvil->nice_exit({exit_code => 4});
} }
elsif (not -f $anvil->data->{switches}{file}) elsif (not -f $anvil->data->{switches}{file})
{ {
# The file to rename doesn't exist. # 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->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0051", variables => { file => $anvil->data->{switches}{file} }});
$anvil->Job->update_progress({
progress => 0,
message => "error_0051,!!file!".$anvil->data->{switches}{file}."!!",
job_uuid => $anvil->data->{jobs}{'job-uuid'},
});
$anvil->nice_exit({exit_code => 5}); $anvil->nice_exit({exit_code => 5});
} }
elsif (-e $anvil->data->{switches}{to}) elsif (-e $anvil->data->{switches}{to})
{ {
# There's already a file (or directory or something) with that name. # 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->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->Job->update_progress({
progress => 0,
message => "error_0052,!!file!".$anvil->data->{switches}{file}."!!,!!to!".$anvil->data->{switches}{to}."!!",
job_uuid => $anvil->data->{jobs}{'job-uuid'},
});
$anvil->nice_exit({exit_code => 6}); $anvil->nice_exit({exit_code => 6});
} }

Loading…
Cancel
Save