* Added a lot more testing.

* Created Get->uuid to generate random UUIDs via 'uuidgen'.
* Created Storage->read_mode that returns the standard 4-digit mode of a directory or file.
* Created System->stop_daemon to stop daemons.
* Altered Template->get to take fully defined path names.
* Altered Template->skin to use the 'set' parameter (as documented) instead of 'skin'. Also made it so that a skin could be set even if the skin directory doesn't exist via the new 'fatal' parameter.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 8 years ago
parent 367eb1a12f
commit 6b5185fe61
  1. 1
      AN/Tools.pm
  2. 327
      AN/Tools.t
  3. 16
      AN/Tools/Get.pm
  4. 103
      AN/Tools/Storage.pm
  5. 84
      AN/Tools/System.pm
  6. 50
      AN/Tools/Template.pm
  7. 13
      AN/Tools/Validate.pm
  8. 5
      AN/an-tools.xml

@ -600,6 +600,7 @@ sub _set_paths
'postgresql-setup' => "/usr/bin/postgresql-setup",
su => "/usr/bin/su",
systemctl => "/usr/bin/systemctl",
uuidgen => "/usr/bin/uuidgen",
},
secure => {
postgres_pgpass => "/var/lib/pgsql/.pgpass",

@ -228,71 +228,306 @@ $an->data->{switches}{v} = "#!set!#";
$an->Log->_adjust_log_level;
is($an->Log->level, "1", "Verifying the log level was set back to '1' with Log->_adjust_log_leve() with 'v' switch set.");
die;
### AN::Tools::Storage tests - These happen a little out of order.
# We need to pick a user name and group name to use for these tests. So we'll start by reading in passwd.
my $passwd = $an->Storage->read_file({file => "/etc/passwd"});
my $group = $an->Storage->read_file({file => "/etc/group"});
my $read_ok = 0;
my $use_user = "";
my $use_group = "";
foreach my $line (split/\n/, $passwd)
{
if ($line =~ /^root:/)
{
$read_ok = 1;
}
elsif ($line =~ /^(\w+):x:\d/)
{
$use_user = $1;
last;
}
}
foreach my $line (split/\n/, $group)
{
if ($line =~ /^root:/)
{
# skip
}
elsif ($line =~ /^(\w+):x:\d/)
{
$use_group = $1;
last;
}
}
# print "[ Debug ] - Using the user: [$use_user] and the group: [$use_group] for testing.\n";
is($read_ok, "1", "Verified that 'Storage->read_file' could read a file.");
# Write a file /tmp/foo
#
die;
### AN::Tools::System tests
#
die;
### AN::Tools::Template tests
#
die;
### AN::Tools::Validate tests
#
die;
### AN::Tools::Words tests
#
die;
### AN::Tools::Storage methods
# Search directory tests
my $body = "This is a test file created as part of the AN::Tools test suite.\nYou can safely delete it if you wish.\n";
my $test_file = "/tmp/an-tools.test";
if (-e $test_file)
{
# remove the old test file.
unlink $test_file or die "The test file: [$test_file] exists (from a previous run?) and can't be removed. The error was: $!\n";
}
$an->Storage->write_file({body => $body, file => $test_file, group => $use_group, user => $use_user, mode => "0666"});
my $write_ok = 0;
if (-e $test_file)
{
$write_ok = 1;
}
is($write_ok, "1", "Verifying that 'Storage->write_file' could write a file (tested writing to: [$test_file]).");
my $mode = $an->Storage->read_mode({target => $test_file});
my ($uid, $gid) = (stat($test_file))[4,5];
my $file_user_name = getpwuid($uid);
my $file_group_name = getgrgid($gid);
#print "[ Debug ] - test_file: [$test_file], mode: [$mode], owning user: [$file_user_name ($uid)], owning group: [$file_group_name ($gid)]\n";
is($mode, "0666", "Verifying that 'Storage->write_file' set the mode correctly when writing a file.");
is($file_user_name, $use_user, "Verifying that 'Storage->write_file' set the user name properly when the file was written.");
is($file_group_name, $use_group, "Verifying that 'Storage->write_file' set the group name properly when the file was written.");
# change_mode
$an->Storage->change_mode({target => $test_file, mode => "4755"});
$mode = $an->Storage->read_mode({target => $test_file});
is($mode, "4755", "Verifying that 'Storage->change_mode' was able to change the mode of the test file (including setting the setuid and setgid sticky bits).");
$an->Storage->change_mode({target => $test_file, mode => "644"});
$mode = $an->Storage->read_mode({target => $test_file});
is($mode, "0644", "Verifying that 'Storage->change_mode' was able to change the mode of the test file using three digits instead of four.");
# change_owner
$an->Storage->change_owner({target => $test_file, user => 0});
$file_user_name = "";
$file_group_name = "";
($uid, $gid) = (stat($test_file))[4,5];
$file_user_name = getpwuid($uid);
$file_group_name = getgrgid($gid);
is($file_user_name, "root", "Verifying that 'Storage->change_user', when passed only a user ID, changed the user.");
is($file_group_name, $use_group, "Verifying that 'Storage->change_user', when passed only a user ID, did not change the group.");
$an->Storage->change_owner({target => $test_file, user => $use_user});
$file_user_name = "";
$file_group_name = "";
($uid, $gid) = (stat($test_file))[4,5];
$file_user_name = getpwuid($uid);
$file_group_name = getgrgid($gid);
is($file_user_name, $use_user, "Verifying that 'Storage->change_user', when passed only a user name, changed the user.");
is($file_group_name, $use_group, "Verifying that 'Storage->change_user', when passed only a user ID, did not change the group.");
$an->Storage->change_owner({target => $test_file, group => 0});
$file_user_name = "";
$file_group_name = "";
($uid, $gid) = (stat($test_file))[4,5];
$file_user_name = getpwuid($uid);
$file_group_name = getgrgid($gid);
is($file_user_name, $use_user, "Verifying that 'Storage->change_user', when passed only a group ID, did not change the user.");
is($file_group_name, "root", "Verifying that 'Storage->change_user', when passed only a group ID, changed the group.");
$an->Storage->change_owner({target => $test_file, group => $use_group});
$file_user_name = "";
$file_group_name = "";
($uid, $gid) = (stat($test_file))[4,5];
$file_user_name = getpwuid($uid);
$file_group_name = getgrgid($gid);
is($file_user_name, $use_user, "Verifying that 'Storage->change_user', when passed only a group name, did not change the user.");
is($file_group_name, $use_group, "Verifying that 'Storage->change_user', when passed only a group name, changed the group.");
$an->Storage->change_owner({target => $test_file, user => "root", group => "root"});
$file_user_name = "";
$file_group_name = "";
($uid, $gid) = (stat($test_file))[4,5];
$file_user_name = getpwuid($uid);
$file_group_name = getgrgid($gid);
is($file_user_name, "root", "Verifying that 'Storage->change_user', when passed both a user and group name, changed the user.");
is($file_group_name, "root", "Verifying that 'Storage->change_user', when passed both a user and group name, changed the group.");
my $change_owner_rc = $an->Storage->change_owner({target => "", user => "root", group => "root"});
is($change_owner_rc, "1", "Verifying that 'Storage->change_user', when passed no target, returned '1'.");
$change_owner_rc = "";
$change_owner_rc = $an->Storage->change_owner({target => "/fake/file", user => "root", group => "root"});
is($change_owner_rc, "1", "Verifying that 'Storage->change_user', when passed a bad file, returned '1'.");
# copy_file
my $copy_file = "/tmp/an-tools.copy";
my $copied_ok = 0;
if (-e $copy_file)
{
unlink $copy_file or die "The test copy file: [$copy_file] exists (from a previous run?) and can't be removed. The error was: $!\n";
}
$an->Storage->copy_file({source => $test_file, target => $copy_file});
if (-e $copy_file)
{
$copied_ok = 1;
}
is($copied_ok, "1", "Verifying that 'Storage->copy_file' was able to copy the test file.");
my $copy_rc = $an->Storage->copy_file({target => $copy_file});
is($copy_rc, "1", "Verifying that 'Storage->copy_file' returned '1' when no source file was passed.");
$copy_rc = "";
$copy_rc = $an->Storage->copy_file({source => $test_file});
is($copy_rc, "2", "Verifying that 'Storage->copy_file' returned '2' when no target file was passed.");
$copy_rc = "";
$copy_rc = $an->Storage->copy_file({source => $test_file, target => $copy_file});
is($copy_rc, "3", "Verifying that 'Storage->copy_file' returned '3' when the target file already exists.");
$copy_rc = "";
$copy_rc = $an->Storage->copy_file({source => $test_file, target => $copy_file, overwrite => 1});
is($copy_rc, "0", "Verifying that 'Storage->copy_file' returned '0' when the target file already exists and overwrite was set.");
$copy_rc = "";
$copy_rc = $an->Storage->copy_file({source => "/fake/file", target => $copy_file});
is($copy_rc, "4", "Verifying that 'Storage->copy_file' returned '4' when the target file is passed but doesn't exist.");
# find
my $test_path = $an->Storage->find({ file => "AN/Tools.t" });
is($test_path, "/usr/share/perl5/AN/Tools.t", "Verifying that Storage->find successfully found 'AN/Tools.t'.");
my $bad_path = $an->Storage->find({ file => "AN/wa.t" });
is($bad_path, "#!not_found!#", "Verifying that Storage->find properly returned '#!not_found!#' for a non-existed file.");
# make_directory
my $test_directory = "/tmp/an-tools/test/directory";
if (-d $test_directory)
{
foreach my $this_directory ("/tmp/an-tools/test/directory", "/tmp/an-tools/test", "/tmp/an-tools")
{
rmdir $this_directory or die "Failed to remove the test directory: [$this_directory] (from a previous test?). The error was: $!\n";
}
}
# This uses an odd mode on purpose
$an->Storage->make_directory({directory => $test_directory, group => $use_group, user => $use_user, mode => "0757"});
my $created_directory = 0;
if (-d $test_directory)
{
$created_directory = 1;
}
is($created_directory, "1", "Verifying that 'Storage->create_directory' created a directory and its parents.");
my $directory_mode = $an->Storage->read_mode({target => $test_directory});
($uid, $gid) = (stat($test_directory))[4,5];
my $directory_user_name = getpwuid($uid);
my $directory_group_name = getgrgid($gid);
is($directory_mode, "0757", "Verifying that 'Storage->create_directory' created a directory with the requested mode.");
is($directory_user_name, $use_user, "Verifying that 'Storage->create_directory' created a directory with the requested owner.");
is($directory_group_name, $use_group, "Verifying that 'Storage->create_directory' created a directory with the requested group.");
# read_config
$an->data->{foo}{bar}{a} = "test";
is($an->Storage->read_config({ file => "AN/test.conf" }), 0, "Verifying that 'Storage->read_config' successfully found 'AN/test.conf'.");
is($an->Storage->read_config({ file => "" }), 1, "Verifying that 'Storage->read_config' returns '1' when called without a 'file' parameter being set.");
is($an->Storage->read_config({ file => "AN/moo.conf" }), 2, "Verifying that 'Storage->read_config' returns '2' when the non-existent 'AN/moo.conf' is passed.");
cmp_ok($an->data->{foo}{bar}{a}, 'eq', 'I am "a"', "Verifying that 'AN/test.conf's 'foo::bar::a' overwrote an earlier set value.");
cmp_ok($an->data->{foo}{bar}{b}, 'eq', 'I am "b", split with tabs and having trailing spaces.', "Verifying that 'AN/test.conf's 'foo::bar::b' has whitespaces removed as expected.");
cmp_ok($an->data->{foo}{baz}{1}, 'eq', 'This is \'1\' with no spaces', "Verifying that 'AN/test.conf's 'foo::baz::1' parsed without spaces around '='.");
cmp_ok($an->data->{foo}{baz}{2}, 'eq', 'I had a $dollar = sign and split with tabs.', "Verifying that 'AN/test.conf's 'foo::baz::2' had no trouble with a '\$' and '=' characters in the string.");
# read_file was tested earlier.
# read_mode was tested earlier.
# search_directories
my $array1 = $an->Storage->search_directories;
my $a1_count = @{$array1};
cmp_ok($a1_count, '>', 0, "Verifying that Storage->search_directories has at least one entry. Found: [$a1_count] directories.");
$an->Storage->search_directories({directories => "/root,/usr/bin,/some/fake/directory"});
my $array2 = $an->Storage->search_directories;
my $a2_count = @{$array2};
cmp_ok($a2_count, '==', 2, "Verifying that Storage->search_directories now has 2 entries from a passed in CSV, testing that the list changed and a fake directory was dropped.");
$an->Storage->search_directories({directories => ["/usr/bin", "/tmp", "/home"] });
my $array3 = $an->Storage->search_directories;
my $a3_count = @{$array3};
cmp_ok($a3_count, '==', 3, "Verifying that Storage->search_directories now has 3 entries from a passed in array reference, verifying that the list changed again.");
$an->Storage->search_directories({directories => "invalid" });
my $array4 = $an->Storage->search_directories;
my $a4_count = @{$array4};
cmp_ok($a4_count, '==', $a1_count, "Verifying that Storage->search_directories has the original number of directories: [$a4_count] after being called with an invalid 'directories' parameter, showing that it reset properly.");
# write_file was tested earlier
# Cleanup.
unlink $test_file;
unlink $copy_file;
foreach my $this_directory ("/tmp/an-tools/test/directory", "/tmp/an-tools/test", "/tmp/an-tools")
{
rmdir $this_directory or die "Failed to remove the test directory: [$this_directory] (from a previous test?). The error was: $!\n";
}
### AN::Tools::System tests
# call was tested during the Log->entry test and will be tested further below.
# Daemon tests require that we create a test daemon and a unit for it...
my $test_daemon_file = "/tmp/an-tools-test.daemon";
my $test_daemon_body = q|#!/usr/bin/perl
# This is a test daemon created for the AN::Tools test suite. It can safely be deleted.
use strict;
use warnings;
use AN::Tools;
my $an = AN::Tools->new();
$an->Log->entry({level => 1, priority => "info", raw => "AN::Tools Test daemon started."});
while(1)
{
sleep 2;
$an->Log->entry({level => 1, priority => "info", raw => "AN::Tools Test daemon looped..."});
}
exit;
|;
$an->Storage->write_file({body => $test_daemon_body, file => $test_daemon_file, group => "root", user => "root", mode => "755", overwrite => 1});
my $test_service_name = "an-tools-test.service";
my $test_service_file = "/usr/lib/systemd/system/".$test_service_name;
my $test_service_body = "[Unit]
Description=Test daemon used by AN::Tools test suite. It can safely be ignored/deleted.
[Service]
Type=simple
ExecStart=$test_daemon_file
ExecStop=/bin/kill -WINCH \${MAINPID}
";
$an->Storage->write_file({body => $test_service_body, file => $test_service_file, group => "root", user => "root", mode => "644", overwrite => 1});
$an->System->call({shell_call => $an->data->{path}{exe}{systemctl}." daemon-reload"});
$an->System->stop_daemon({daemon => $test_service_name}); # Just in case...
# check_daemon
my $test_daemon_rc = $an->System->check_daemon({daemon => $test_service_name});
is($test_daemon_rc, "0", "Verifying that 'System->check_daemon' was able to confirm that the test service: [".$test_service_name."] was stopped.");
$test_daemon_rc = "";
$test_daemon_rc = $an->System->start_daemon({daemon => $test_service_name});
is($test_daemon_rc, "0", "Verifying that 'System->start_daemon' was able to start the test service: [".$test_service_name."].");
$test_daemon_rc = "";
$test_daemon_rc = $an->System->check_daemon({daemon => $test_service_name});
is($test_daemon_rc, "1", "Verifying that 'System->check_daemon' was able to confirm that the test service: [".$test_service_name."] is now running.");
$test_daemon_rc = "";
$test_daemon_rc = $an->System->stop_daemon({daemon => $test_service_name});
is($test_daemon_rc, "0", "Verifying that 'System->stop_daemon' was able to stop the test service: [".$test_service_name."].");
$test_daemon_rc = "";
$test_daemon_rc = $an->System->check_daemon({daemon => $test_service_name});
is($test_daemon_rc, "0", "Verifying that 'System->check_daemon' was able to confirm that the test service: [".$test_service_name."] was stopped.");
# Cleanup
unlink $test_service_file;
unlink $test_daemon_file;
$an->System->call({shell_call => $an->data->{path}{exe}{systemctl}." daemon-reload"});
### AN::Tools::Template tests
# We're going to need a fake template file to test.
my $test_template_file = "/tmp/an-tools.html";
my $test_template_body = '<!-- start test1 -->
This is test template #1.
<!-- end test1 -->
<!-- start test2 -->
This is test template #2. It has a replacement: [#!variable!test!#].
<!-- end test2 -->
';
$an->Storage->write_file({body => $test_template_body, file => $test_template_file, mode => "644", overwrite => 1});
# get
my $test1_template = $an->Template->get({file => $test_template_file, name => "test1"});
is($test1_template, "This is test template #1.\n", "Verifying that 'Template->get' was able to read a test template.");
my $test2_template = $an->Template->get({file => $test_template_file, name => "test2", variables => { test => "boo!" }});
is($test2_template, "This is test template #2. It has a replacement: [boo!].\n", "Verifying that 'Template->get' was able to read a test template with a variable insertion.");
is($an->Template->skin, "alteeve", "Verifying that 'Template->skin' is initially set to 'alteeve'.");
$an->Template->skin({fatal => 0, set => "test"}); # We disable fatal because there may be no skin directory yet.
is($an->Template->skin, "test", "Verifying that 'Template->skin' was changed to 'test'.");
$an->Template->skin({fatal => 0, set => "alteeve"});
is($an->Template->skin, "alteeve", "Verifying that 'Template->skin' was changed back to 'alteeve'.");
# Clean up
unlink $test_template_file;
### AN::Tools::Validate tests
# is_ipv4
is($an->Validate->is_ipv4({ip => "0.0.0.0"}), "1", "Verifying that 'Validate->is_ipv4' recognizes '0.0.0.0' as a valid IP address.");
is($an->Validate->is_ipv4({ip => "255.255.255.255"}), "1", "Verifying that 'Validate->is_ipv4' recognizes '255.255.255.255' as a valid IP address.");
is($an->Validate->is_ipv4({ip => "256.255.255.255"}), "0", "Verifying that 'Validate->is_ipv4' recognizes '256.255.255.255' as an invalid IP address.");
is($an->Validate->is_ipv4({ip => "alteeve.com"}), "0", "Verifying that 'Validate->is_ipv4' recognizes 'alteeve.com' as an invalid IP address.");
is($an->Validate->is_ipv4({ip => "::1"}), "0", "Verifying that 'Validate->is_ipv4' recognizes '::1' as an invalid IP address.");
my $test_uuid = $an->Get->uuid;
die;
### AN::Tools::Words tests
#
die;
my $test_path = $an->Storage->find({ file => "AN/Tools.t" });
is($test_path, "/usr/share/perl5/AN/Tools.t", "Verifying that Storage->find successfully found 'AN/Tools.t'.");
my $bad_path = $an->Storage->find({ file => "AN/wa.t" });
is($bad_path, "#!not_found!#", "Verifying that Storage->find properly returned '#!not_found!#' for a non-existed file.");
# Config file read tests.
$an->data->{foo}{bar}{a} = "test";
is($an->Storage->read_config({ file => "AN/test.conf" }), 0, "Verifying that 'Storage->read_config' successfully found 'AN/test.conf'.");
is($an->Storage->read_config({ file => "" }), 1, "Verifying that 'Storage->read_config' returns '1' when called without a 'file' parameter being set.");
is($an->Storage->read_config({ file => "AN/moo.conf" }), 2, "Verifying that 'Storage->read_config' returns '2' when the non-existent 'AN/moo.conf' is passed.");
cmp_ok($an->data->{foo}{bar}{a}, 'eq', 'I am "a"', "Verifying that 'AN/test.conf's 'foo::bar::a' overwrote an earlier set value.");
cmp_ok($an->data->{foo}{bar}{b}, 'eq', 'I am "b", split with tabs and having trailing spaces.', "Verifying that 'AN/test.conf's 'foo::bar::b' has whitespaces removed as expected.");
cmp_ok($an->data->{foo}{baz}{1}, 'eq', 'This is \'1\' with no spaces', "Verifying that 'AN/test.conf's 'foo::baz::1' parsed without spaces around '='.");
cmp_ok($an->data->{foo}{baz}{2}, 'eq', 'I had a $dollar = sign and split with tabs.', "Verifying that 'AN/test.conf's 'foo::baz::2' had no trouble with a '\$' and '=' characters in the string.");
### AN::Tools::Words methods
# Make sure we can read words files

@ -15,6 +15,7 @@ my $THIS_FILE = "Get.pm";
# host_uuid
# network_details
# switches
# uuid
=pod
@ -360,6 +361,21 @@ sub switches
return(0);
}
=head2 uuid
This method returns a new UUID (using 'uuidgen' from the system). It takes no parameters.
=cut
sub uuid
{
my $self = shift;
my $an = $self->parent;
my $uuid = $an->System->call({shell_call => $an->data->{path}{exe}{uuidgen}});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { uuid => $uuid }});
return($uuid);
}
# =head3
#

@ -18,6 +18,7 @@ my $THIS_FILE = "Storage.pm";
# make_directory
# read_config
# read_file
# read_mode
# search_directories
# write_file
@ -152,7 +153,7 @@ This changes the owner and/or group of a file or directory.
$an->Storage->change_owner({target => "/tmp/foo", mode => "0644"});
If it fails to write the file, an alert will be logged.
If it fails to write the file, an alert will be logged and 'C<< 1 >>' will be returned. Otherwise, 'C<< 0 >>' will be returned.
Parameters;
@ -178,7 +179,8 @@ sub change_owner
my $target = defined $parameter->{target} ? $parameter->{target} : "";
my $group = defined $parameter->{group} ? $parameter->{group} : "";
my $user = defined $parameter->{user} ? $parameter->{user} : "";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
my $debug = 3;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
target => $target,
group => $group,
user => $user,
@ -187,16 +189,11 @@ sub change_owner
# Make sure the user and group and just one digit or word.
$user =~ s/^(\S+)\s.*$/$1/;
$group =~ s/^(\S+)\s.*$/$1/;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
group => $group,
user => $user,
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
group => $group,
user => $user,
}});
# If the group is a series of digits, remove all but the first.
if (defined $group)
{
}
my $string = "";
my $error = 0;
if (not $target)
@ -205,31 +202,42 @@ sub change_owner
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "log_0039"});
$error = 1;
}
if (not -e $target)
{
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "log_0051", variables => {target => $target }});
$error = 1;
}
if (defined $user)
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { user => $user }});
if ($user ne "")
{
$string = $user;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { string => $string }});
}
if (defined $group)
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { group => $group }});
if ($group ne "")
{
$string .= ":".$group;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { string => $string }});
}
if ((not $error) && ($string))
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { error => $error, string => $string }});
if ((not $error) && ($string ne ""))
{
my $shell_call = $an->data->{path}{exe}{'chown'}." $string $target";
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0011", variables => { shell_call => $shell_call }});
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0011", variables => { shell_call => $shell_call }});
open (my $file_handle, $shell_call." 2>&1 |") or $an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0014", variables => { shell_call => $shell_call, error => $! }});
while(<$file_handle>)
{
chomp;
my $line = $_;
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0017", variables => { line => $line }});
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0017", variables => { line => $line }});
}
close $file_handle;
}
return(0);
return($error);
}
=head2 copy_file
@ -249,7 +257,7 @@ If this is not passed and the target exists, this module will return 'C<< 3 >>'.
=head3 source (required)
This is the source file. if it doesn't exist, this method will return 'C<< 1 >>'.
This is the source file. If it isn't specified, 'C<< 1 >>' will be returned. If it doesn't exist, this method will return 'C<< 4 >>'.
=head3 target (required)
@ -279,6 +287,11 @@ sub copy_file
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0044"});
return(1);
}
elsif (not -e $source)
{
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0052", variables => { source => $source }});
return(4);
}
if (not $target)
{
# No target passed.
@ -668,6 +681,62 @@ sub read_file
return($body);
}
=head2 read_mode
This reads a file or directory's mode (sticky-bit and ownership) and returns the mode as a four-digit string (ie: 'c<< 0644 >>', 'C<< 4755 >>', etc.
my $mode = $an->Storage->read_mode({file => "/tmp/foo"});
If it fails to find the file, or the file is not readable, 'C<< 0 >>' is returned.
Parameters;
=head3 file (required)
This is the name of the file or directory to check the mode of.
=cut
sub read_mode
{
my $self = shift;
my $parameter = shift;
my $an = $self->parent;
my $debug = 1;
my $target = defined $parameter->{target} ? $parameter->{target} : "";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { target => $target }});
if (not $target)
{
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0050"});
return(1);
}
# Read the mode and convert it to digits.
my $mode = (stat($target))[2];
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { mode => $mode }});
# Return the full mode, unless it is a directory or file. In those cases, return the last four digits.
my $say_mode = $mode;
if (-d $target)
{
# Directory - five digits
$say_mode = sprintf("%04o", $mode);
$say_mode =~ s/^\d(\d\d\d\d)$/$1/;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { say_mode => $say_mode }});
}
elsif (-f $target)
{
# File - six digits
$say_mode = sprintf("%04o", $mode);
$say_mode =~ s/^\d\d(\d\d\d\d)$/$1/;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { say_mode => $say_mode }});
}
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { mode => $mode, say_mode => $say_mode }});
return($say_mode);
}
=head2 search_directories
This method returns an array reference of directories to search within for files and directories.

@ -14,6 +14,7 @@ my $THIS_FILE = "System.pm";
# call
# check_daemon
# start_daemon
# stop_daemon
=pod
@ -102,7 +103,7 @@ sub call
my $shell_call = defined $parameter->{shell_call} ? $parameter->{shell_call} : "";
my $secure = defined $parameter->{secure} ? $parameter->{secure} : 0;
my $source = defined $parameter->{source} ? $parameter->{source} : $THIS_FILE;
$an->Log->variables({source => $source, line => $line, level => 2, secure => $secure, list => { shell_call => $shell_call }});
$an->Log->variables({source => $source, line => $line, level => 3, secure => $secure, list => { shell_call => $shell_call }});
my $output = "#!error!#";
if (not $shell_call)
@ -151,24 +152,30 @@ sub check_daemon
my $parameter = shift;
my $an = $self->parent;
my $return = 2;
my $daemon = defined $parameter->{daemon} ? $parameter->{daemon} : "";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { daemon => $daemon }});
my $return = 2;
my $daemon = defined $parameter->{daemon} ? $parameter->{daemon} : "";
my $say_daemon = $daemon =~ /\.service$/ ? $daemon : $daemon.".service";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { daemon => $daemon, say_daemon => $say_daemon }});
my $output = $an->System->call({shell_call => $an->data->{path}{exe}{systemctl}." status ".$daemon.".service; ".$an->data->{path}{exe}{'echo'}." return_code:\$?"});
my $output = $an->System->call({shell_call => $an->data->{path}{exe}{systemctl}." status ".$say_daemon."; ".$an->data->{path}{exe}{'echo'}." return_code:\$?"});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }});
foreach my $line (split/\n/, $output)
{
if ($line =~ /return_code:(\d+)/)
{
my $return_code = $1;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { return_code => $return_code }});
if ($return_code eq "3")
{
# Stopped
$return = 0;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'return' => $return }});
}
elsif ($return_code eq "0")
{
# Running
$return = 1;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'return' => $return }});
}
}
}
@ -179,7 +186,9 @@ sub check_daemon
=head2 start_daemon
This method starts a daemon.
This method starts a daemon. The return code from the start request will be returned.
If the return code for the start command wasn't read, C<< undef >> is returned.
Parameters;
@ -194,29 +203,62 @@ sub start_daemon
my $parameter = shift;
my $an = $self->parent;
my $return = 2;
my $daemon = defined $parameter->{daemon} ? $parameter->{daemon} : "";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { daemon => $daemon }});
my $return = undef;
my $daemon = defined $parameter->{daemon} ? $parameter->{daemon} : "";
my $say_daemon = $daemon =~ /\.service$/ ? $daemon : $daemon.".service";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { daemon => $daemon, say_daemon => $say_daemon }});
my $output = $an->System->call({shell_call => $an->data->{path}{exe}{systemctl}." start ".$daemon.".service; ".$an->data->{path}{exe}{'echo'}." return_code:\$?"});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output }});
my $output = $an->System->call({shell_call => $an->data->{path}{exe}{systemctl}." start ".$say_daemon."; ".$an->data->{path}{exe}{'echo'}." return_code:\$?"});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }});
foreach my $line (split/\n/, $output)
{
if ($line =~ /return_code:(\d+)/)
{
my $return_code = $1;
if ($return_code eq "3")
{
$return = 0;
}
elsif ($return_code eq "0")
{
$return = 1;
}
$return = $1;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'return' => $return }});
}
}
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'return' => $return }});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'return' => $return }});
return($return);
}
=head2 stop_daemon
This method stops a daemon. The return code from the stop request will be returned.
If the return code for the stop command wasn't read, C<< undef >> is returned.
Parameters;
=head3 daemon (required)
This is the name of the daemon to stop.
=cut
sub stop_daemon
{
my $self = shift;
my $parameter = shift;
my $an = $self->parent;
my $return = undef;
my $daemon = defined $parameter->{daemon} ? $parameter->{daemon} : "";
my $say_daemon = $daemon =~ /\.service$/ ? $daemon : $daemon.".service";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { daemon => $daemon, say_daemon => $say_daemon }});
my $output = $an->System->call({shell_call => $an->data->{path}{exe}{systemctl}." stop ".$say_daemon."; ".$an->data->{path}{exe}{'echo'}." return_code:\$?"});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }});
foreach my $line (split/\n/, $output)
{
if ($line =~ /return_code:(\d+)/)
{
$return = $1;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'return' => $return }});
}
}
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'return' => $return }});
return($return);
}

@ -109,6 +109,7 @@ sub get
my $parameter = shift;
my $an = $self->parent;
my $debug = 1;
my $file = defined $parameter->{file} ? $parameter->{file} : "";
my $language = defined $parameter->{language} ? $parameter->{language} : $an->Words->language;
my $name = defined $parameter->{name} ? $parameter->{name} : "";
@ -117,7 +118,7 @@ sub get
$skin = $an->data->{path}{directories}{skins}."/".$skin;
my $template = "";
my $source = "";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
file => $file,
language => $language,
name => $name,
@ -134,8 +135,18 @@ sub get
else
{
# Make sure the file exists.
$source = $skin."/".$file;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { source => $source }});
if ($file =~ /^\//)
{
# Fully defined path, don't alter it.
$source = $file;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { source => $source }});
}
else
{
# Just a file name, prepend the skin path.
$source = $skin."/".$file;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { source => $source }});
}
if (not -e $source)
{
@ -162,13 +173,13 @@ sub get
{
my $in_template = 0;
my $shell_call = $source;
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0012", variables => { shell_call => $shell_call }});
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0012", variables => { shell_call => $shell_call }});
open (my $file_handle, "<", $shell_call) or $an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0015", variables => { shell_call => $shell_call, error => $! }});
while(<$file_handle>)
{
chomp;
my $line = $_;
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, key => "log_0023", variables => { line => $line }});
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0023", variables => { line => $line }});
if ($line =~ /^<!-- start $name -->/)
{
$in_template = 1;
@ -188,14 +199,14 @@ sub get
}
}
close $file_handle;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { template => $template }});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { template => $template }});
# Now that I have the skin, inject my variables. We'll use Words->string() to do this for us.
$template = $an->Words->string({
string => $template,
variables => $variables,
});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { source => $source }});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { source => $source }});
}
return($template);
@ -215,6 +226,16 @@ Set the active skin to 'C<< foo >>'. Only pass the skin name, not the full path.
$an->Template->skin({set => "foo"});
Parameters;
=head3 fatal (optional)
If passed along with C<< set >>, the skin will be set even if the skin directory does not exit.
=head3 set (optional)
If passed a string, that will become the new active skin. If the skin directory does not exist, however, and C<< fatal >> is not set, the request will be ignored.
=cut
sub skin
{
@ -222,17 +243,19 @@ sub skin
my $parameter = shift;
my $an = $self->parent;
my $set = defined $parameter->{skin} ? $parameter->{skin} : "";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { file => $set }});
my $debug = 3;
my $fatal = defined $parameter->{fatal} ? $parameter->{fatal} : 1;
my $set = defined $parameter->{set} ? $parameter->{set} : "";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { fatal => $fatal, file => $set }});
if ($set)
{
my $skin_directory = $an->data->{path}{directories}{skins}."/".$set;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { skin_directory => $skin_directory }});
if (-d $skin_directory)
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { skin_directory => $skin_directory }});
if ((-d $skin_directory) or (not $fatal))
{
$self->{SKIN}{HTML} = $set;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'SKIN::HTML' => $self->{SKIN}{HTML} }});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'SKIN::HTML' => $self->{SKIN}{HTML} }});
}
else
{
@ -240,11 +263,14 @@ sub skin
}
}
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'SKIN::HTML' => $self->{SKIN}{HTML} }});
if (not $self->{SKIN}{HTML})
{
$self->{SKIN}{HTML} = $an->data->{defaults}{template}{html};
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'SKIN::HTML' => $self->{SKIN}{HTML}, 'defaults::template::html' => $an->data->{defaults}{template}{html} }});
}
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { 'SKIN::HTML' => $self->{SKIN}{HTML} }});
return($self->{SKIN}{HTML});
}

@ -94,8 +94,9 @@ sub is_ipv4
my $parameter = shift;
my $an = $self->parent;
my $ip = defined $parameter->{ip} ? $parameter->{ip} : "";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { ip => $ip }});
my $debug = 3;
my $ip = defined $parameter->{ip} ? $parameter->{ip} : "";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { ip => $ip }});
my $valid = 1;
if ($ip =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)
@ -105,7 +106,7 @@ sub is_ipv4
my $second_octet = $2;
my $third_octet = $3;
my $fourth_octet = $4;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
first_octet => $first_octet,
second_octet => $second_octet,
third_octet => $third_octet,
@ -119,17 +120,17 @@ sub is_ipv4
{
# One of the octets is out of range.
$valid = 0;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { valid => $valid }});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }});
}
}
else
{
# Not in the right format.
$valid = 0;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { valid => $valid }});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }});
}
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { valid => $valid }});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { valid => $valid }});
return($valid);
}

@ -50,7 +50,7 @@ It also has replacement variables: [#!variable!first!#] and [#!variable!second!#
<key name="log_0028">Successfully read the words file: [#!variable!file!#].</key>
<key name="log_0029"><![CDATA[[ Error ] - Storage->find() failed to find: [#!variable!file!#].]]></key>
<key name="log_0030"><![CDATA[[ Warning ] - Template->skin() was asked to set the skin: [#!variable!set!#], but the source directory: [#!variable!skin_directory!#] doesn't exist. Ignoring.]]></key>
<key name="log_0031"><![CDATA[[ Warning ] - Storage->search_directories() was passed the array: [#!variable!array!#], but it wasn't actually an array. Using \@INC + path::directories::tools + \$ENV{'PATH'} for the list of directories to search instead.]]></key>
<key name="log_0031"><![CDATA[[ Warning ] - Storage->search_directories() was passed the array: [#!variable!array!#], but it wasn't actually an array. Using @INC + path::directories::tools + \$ENV{'PATH'} for the list of directories to search instead.]]></key>
<key name="log_0032"><![CDATA[[ Warning ] - Words->read()' called without a file name to read.]]></key>
<key name="log_0033"><![CDATA[[ Warning ] - Words->read()' asked to read: [#!variable!file!#] which was not found.]]></key>
<key name="log_0034"><![CDATA[[ Warning ] - AN::Tools::Words->read()' asked to read: [#!variable!file!#] which was not readable by: [#!variable!user!#] (uid/euid: [#!variable!uid!#]).]]></key>
@ -69,6 +69,9 @@ It also has replacement variables: [#!variable!first!#] and [#!variable!second!#
<key name="log_0047"><![CDATA[[ Error ] - The module Log->level() was passed an invalid log level: [#!variable!set!#]. Only '0', '1', '2', '3' or '4' are valid.]]></key>
<key name="log_0048"><![CDATA[[ Warning ] - Testing of AN::Tools is beginning. This will generate warnings and alerts and are not a concern.]]></key>
<key name="log_0049"><![CDATA[[ Warning ] - Testing of AN::Tools is complete.]]></key>
<key name="log_0050"><![CDATA[[ Error ] - The module Storage->read_mode() was called without a 'target' parameter, or the parameter was empty.]]></key>
<key name="log_0051"><![CDATA[[ Error ] - The module Storage->change_owner() was asked to change the ownership of: [#!variable!target!#] which doesn't exist.]]></key>
<key name="log_0052"><![CDATA[[ Error ] - The module Storage->copy_file() was called but the source file: [#!variable!source!#] doesn't exist.]]></key>
<!-- Test words. Do NOT change unless you update 't/Words.t' or tests will needlessly fail. -->
<key name="t_0000">Test</key>

Loading…
Cancel
Save