From 9cfd7b9b94319c7ea938a3ba18fc3e10a99b9f74 Mon Sep 17 00:00:00 2001 From: Digimer Date: Wed, 1 Dec 2021 18:43:50 -0500 Subject: [PATCH] Created the new (and still in development) striker-file-manager to manage files from a Striker dashboard's command line. So far. it will add files only. Signed-off-by: Digimer --- Anvil/Tools/Database.pm | 2 + tools/anvil-sync-shared | 2 +- tools/striker-file-manager | 318 ++++++++++++++++++++++++++++ tools/striker-manage-install-target | 2 +- 4 files changed, 322 insertions(+), 2 deletions(-) create mode 100755 tools/striker-file-manager diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index 2dfadcb9..9bda9807 100644 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -15401,6 +15401,8 @@ sub query }}); }; if ($@) { + ### TODO: Report back somehow that the handle is dead. + $anvil->Database->disconnect({debug => $debug}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0675", variables => { query => (not $secure) ? $query : $anvil->Log->is_secure($query), server => $say_server, diff --git a/tools/anvil-sync-shared b/tools/anvil-sync-shared index d88294fe..a1cb6965 100755 --- a/tools/anvil-sync-shared +++ b/tools/anvil-sync-shared @@ -48,7 +48,7 @@ if (not $anvil->data->{switches}{'job-uuid'}) $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }}); } -# If we still don't have a job-uuit, go into interactive mode. +# If we still don't have a job-uuid, go into interactive mode. if ($anvil->data->{switches}{'job-uuid'}) { # Load the job data. diff --git a/tools/striker-file-manager b/tools/striker-file-manager new file mode 100755 index 00000000..aed0d50c --- /dev/null +++ b/tools/striker-file-manager @@ -0,0 +1,318 @@ +#!/usr/bin/perl +# +# This is the command line user interface for managing files on /mnt/shared/files on Strikers and made +# available on Anvil! systems. +# + +use strict; +use warnings; +use Anvil::Tools; +use Data::Dumper; +require POSIX; +use Term::Cap; + +my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; +my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; +if (($running_directory =~ /^\./) && ($ENV{PWD})) +{ + $running_directory =~ s/^\./$ENV{PWD}/; +} + +# Turn off buffering so that the pinwheel will display while waiting for the SSH call(s) to complete. +$| = 1; + +my $anvil = Anvil::Tools->new(); + +# Read switches (target ([user@]host[:port]) and the file with the target's password. +$anvil->Get->switches; +$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }}); + +# Connect to the database(s). +$anvil->Database->connect; +$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0132"}); + + +my $termios = new POSIX::Termios; +$termios->getattr; +my $ospeed = $termios->getospeed; + +my $terminal = Tgetent Term::Cap { TERM => undef, OSPEED => $ospeed }; +$terminal->Trequire(qw/ce ku kd/); + +interactive_menu($anvil, $termios); + +$anvil->nice_exit({exit_code => 0}); + + + +############################################################################################################# +# Functions # +############################################################################################################# + +sub interactive_menu +{ + my ($anvil, $termios) = @_; + + # This has to run on a striker, so is this a Striker? + my $host_type = $anvil->Get->host_type; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }}); + if ($host_type ne "striker") + { + print "Managing files must be run on a Striker dashboard. Exiting\n"; + $anvil->nice_exit({exit_code => 1}); + } + + $anvil->data->{manaing}{file} = ""; + $anvil->data->{manaing}{anvil} = ""; + while(1) + { + # Get a list of files we already know about. Database->get_anvils() also loads files and + # file_locations data + $anvil->Database->get_anvils; + my $longest_file_name = 0; + + print $terminal->Tputs('cl'); + print "-=] Anvil! File Management\n\n"; + # Show the main menu. + print "[ 1 ] - Add a new file.\n"; + print "[ 2 ] - Manage an existing file.\n"; + print "[ 3 ] - Manage files on an Anvil!\n"; + print "\n"; + print "[ Q ] - Quit\n"; + print "\n"; + print $terminal->Tgoto('cm', 0, 8)."? "; + my $answer = ; + chomp $answer; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); + + if ($answer eq "1") + { + interactive_menu_add_file($anvil, $terminal); + } + elsif ($answer eq "2") + { + interactive_menu_manage_file($anvil, $terminal); + } + elsif ($answer eq "2") + { + interactive_menu_manage_anvil($anvil, $terminal); + } + elsif (lc($answer) eq "q") + { + print "NO CARRIER, good bye.\n"; + $anvil->nice_exit({exit_code => 0}); + } + } + + return(0); +} + +sub interactive_menu_add_file +{ + my ($anvil, $terminal) = @_; + + print $terminal->Tputs('cl'); + print "-=] Anvil! File Management - Add a new file\n\n"; + + # Build a list of files in /mnt/shared/incoming/ that are not yet in the database. + get_file_list($anvil); + + # Start the array with an empty entry so that users can answer '1' for the first file. + my $files = [""]; + foreach my $file_name (sort {$a cmp $b} keys %{$anvil->data->{manage_files}}) + { + if ($anvil->data->{manage_files}{$file_name}{file_new}) + { + push @{$files}, $file_name; + } + } + my $file_count = (@{$files} - 1); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { file_count => $file_count }}); + + if (not $file_count) + { + print "data->{path}{directories}{shared}{incoming}."]>\n"; + # Show the main menu. + print "\n"; + print "[ B ] - Back\n"; + print "[ Q ] - Quit\n"; + print "\n"; + print $terminal->Tgoto('cm', 0, 7)."? "; + my $answer = ; + chomp $answer; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); + if (lc($answer) eq "b") + { + interactive_menu($anvil, $terminal); + } + elsif (lc($answer) eq "q") + { + print "NO CARRIER, good bye.\n"; + $anvil->nice_exit({exit_code => 0}); + } + else + { + interactive_menu_add_file($anvil, $terminal); + } + } + else + { + my $pad = 1; + if ($file_count > 9) + { + $pad = 2; + } + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { pad => $pad }}); + + foreach my $i (0..$file_count) + { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "files->[".$i."]" => $files->[$i] }}); + next if $files->[$i] eq ""; + my $file_name = $files->[$i]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { file_name => $file_name }}); + print "[ ".sprintf("%${pad}s", $i)." ] - ".$file_name."\n"; + } + print "\n"; + print "[ B ] - Back\n"; + print "[ Q ] - Quit\n"; + print "\n"; + print $terminal->Tgoto('cm', 0, ($file_count + 6))."Which file would you like to add? "; + my $answer = ; + chomp $answer; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); + if (($answer =~ /^\d+$/) && (exists $files->[$answer]) and ($files->[$answer])) + { + my $file_name = $files->[$answer]; + print $terminal->Tputs('cl'); + print "-=] Anvil! File Management - Add a new file\n\n"; + print "Confirm addition of: [".$file_name."] [y/N] ?\n"; + my $answer = ; + chomp $answer; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); + if ($answer =~ /^y/i) + { + print "Creating a job to add the file. Please be patient, it should be added shortly.\n"; + my $out_file = $anvil->data->{path}{directories}{shared}{incoming}."/".$file_name; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { out_file => $out_file }}); + + my ($job_uuid) = $anvil->Database->insert_or_update_jobs({ + file => $THIS_FILE, + line => __LINE__, + job_command => $anvil->data->{path}{exe}{'anvil-sync-shared'}, + job_data => "file=".$out_file, + job_name => "storage::move_incoming", + job_title => "job_0132", + job_description => "job_0133", + job_progress => 0, + job_host_uuid => $anvil->data->{sys}{host_uuid}, + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }}); + print "- Job created as: [".$job_uuid."]\n\n"; + print "Press any key to return to the main menu.\n"; + my $answer = ; + chomp $answer; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { answer => $answer }}); + interactive_menu($anvil, $terminal); + } + else + { + print "Aborted.\n"; + sleep 1; + interactive_menu_add_file($anvil, $terminal); + } + } + elsif (lc($answer) eq "b") + { + interactive_menu($anvil, $terminal); + } + elsif (lc($answer) eq "q") + { + print "NO CARRIER, good bye.\n"; + $anvil->nice_exit({exit_code => 0}); + } + else + { + interactive_menu_add_file($anvil, $terminal); + } + } + + return(0); +} + +sub interactive_menu_manage_file +{ + my ($anvil, $terminal) = @_; + + print $terminal->Tputs('cl'); + print "-=] Anvil! File Management - Manage an existing file\n\n"; + + if (0) + { + } + else + { + print "NO CARRIER, good bye.\n"; + $anvil->nice_exit({exit_code => 0}); + } + + return(0); +} + +sub interactive_menu_manage_anvil +{ + my ($anvil, $terminal) = @_; + + + print $terminal->Tputs('cl'); + print "-=] Anvil! File Management - Manage Files on an Anvil!\n\n"; + + if (0) + { + } + else + { + print "NO CARRIER, good bye.\n"; + $anvil->nice_exit({exit_code => 0}); + } + + return(0); +} + +# This looks for files in /mnt/shared/incoming and collects their file_uuid, if found in the database. +sub get_file_list +{ + my ($anvil) = @_; + + if (exists $anvil->data->{manage_files}) + { + delete $anvil->data->{manage_files}; + } + my $directory = $anvil->data->{path}{directories}{shared}{incoming}; + local(*DIRECTORY); + opendir(DIRECTORY, $directory); + while(my $file_name = readdir(DIRECTORY)) + { + next if $file_name eq "."; + next if $file_name eq ".."; + # Ignore hidden files (which includes files still being copied) + next if $file_name =~ /^\./; + my $full_path = $directory."/".$file_name; + + # No file should match, but just in case... + if (exists $anvil->data->{files}{file_name}{$file_name}) + { + ### TODO: Log that this is a duplicate. + $anvil->data->{manage_files}{$file_name}{file_uuid} = $anvil->data->{files}{file_name}{$file_name}{file_uuid}; + $anvil->data->{manage_files}{$file_name}{file_new} = 0; + + } + else + { + $anvil->data->{manage_files}{$file_name}{file_uuid} = ""; + $anvil->data->{manage_files}{$file_name}{file_new} = 1; + } + } + closedir(DIRECTORY); + + return(0); +} diff --git a/tools/striker-manage-install-target b/tools/striker-manage-install-target index 6fa6f859..cbf97873 100755 --- a/tools/striker-manage-install-target +++ b/tools/striker-manage-install-target @@ -176,7 +176,7 @@ if ($anvil->data->{switches}{disable}) # Exit if we're not configured yet my $configured = $anvil->System->check_if_configured; -$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { configured => $configured }}); +$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { configured => $configured }}); if (not $configured) { print $anvil->Words->string({key => "error_0046"})."\n";