You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by ar...@apache.org on 2016/10/18 17:30:54 UTC
svn commit: r1765484 - in /vcl/trunk/managementnode/lib/VCL:
DataStructure.pm Module/OS.pm Module/OS/Windows.pm reclaim.pm reserved.pm
utils.pm
Author: arkurth
Date: Tue Oct 18 17:30:53 2016
New Revision: 1765484
URL: http://svn.apache.org/viewvc?rev=1765484&view=rev
Log:
VCL-997
Added subroutines:
DataStructure.pm::get_reservation_info_json_string
OS.pm::get_reservation_info_json_file_path
OS.pm::create_reservation_info_json_file
OS.pm::delete_reservation_info_json_file
Windows.pm::get_reservation_info_json_file_path
utils.pm::prune_array_reference
utils.pm::prune_hash_child_references
utils.pm::prune_hash_reference
OS.pm::create_reservation_info_json_file gets called from reserved.pm::process only if a variable named 'enable_experimental_features' is true in the database.
This file is removed when a computer is sanitized in reclaim.pm::call_os_sanitize.
Modified:
vcl/trunk/managementnode/lib/VCL/DataStructure.pm
vcl/trunk/managementnode/lib/VCL/Module/OS.pm
vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
vcl/trunk/managementnode/lib/VCL/reclaim.pm
vcl/trunk/managementnode/lib/VCL/reserved.pm
vcl/trunk/managementnode/lib/VCL/utils.pm
Modified: vcl/trunk/managementnode/lib/VCL/DataStructure.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/DataStructure.pm?rev=1765484&r1=1765483&r2=1765484&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/DataStructure.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/DataStructure.pm Tue Oct 18 17:30:53 2016
@@ -77,6 +77,7 @@ use diagnostics;
use English '-no_match_vars';
use Object::InsideOut;
+use JSON qw(to_json);
use List::Util qw(min max);
use YAML;
use Storable qw(dclone);
@@ -2236,6 +2237,63 @@ sub get_image_minram {
}
#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_reservation_info_json_string
+
+ Parameters : none
+ Returns : string
+ Description : Constucts a JSON string based on the reservation data.
+
+=cut
+
+sub get_reservation_info_json_string {
+ my $self = shift;
+
+ my $reservation_id = $self->reservation_id;
+ my $request_data = $self->request_data;
+
+ # Clone the hash so that the original isn't altered
+ my $request_data_clone = dclone($request_data);
+
+ my $json_data = {};
+
+ # Remove useless keys
+ $request_data_clone = prune_hash_reference($request_data_clone, '.*(resource|current|adminlevel|nextimage|predictive|platform|log|schedule).*');
+
+ $json_data->{request} = prune_hash_child_references($request_data_clone);
+ $json_data->{reservation} = prune_hash_child_references($request_data_clone->{reservation}{$reservation_id});
+ $json_data->{imagerevision} = prune_hash_child_references($request_data_clone->{reservation}{$reservation_id}{imagerevision});
+ $json_data->{image} = prune_hash_child_references($request_data_clone->{reservation}{$reservation_id}{image});
+ $json_data->{computer} = prune_hash_child_references($request_data_clone->{reservation}{$reservation_id}{computer});
+
+ if (defined($request_data_clone->{reservation}{$reservation_id}{computer}{vmhost})) {
+ $json_data->{vmhost} = prune_hash_child_references($request_data_clone->{reservation}{$reservation_id}{computer}{vmhost});
+ $json_data->{vmhost_computer} = prune_hash_child_references($request_data_clone->{reservation}{$reservation_id}{computer}{vmhost}{computer});
+ }
+
+ # TODO: figure out how to handle user info, what structure, etc
+ #$json_data->{users} = $request_data_clone->{reservation}{$reservation_id}{users};
+ #$json_data->{user} = $request_data_clone->{user};
+ #$json_data->{user}{username} = $json_data->{user}{unityid};
+
+ # IMPORTANT: delete vmprofile data and anything else that may contain passwords
+ #delete $json_data->{computer}{vmhost}{vmprofile};
+
+ # Convert the request data to JSON
+ my $json;
+ eval {
+ $json = to_json($json_data, { pretty => 1 });
+ };
+ if ($EVAL_ERROR) {
+ notify($ERRORS{'WARNING'}, 0, "failed to create convert request data to json, error: $EVAL_ERROR");
+ return;
+ }
+
+ notify($ERRORS{'DEBUG'}, 0, "constructed JSON string based on reservation infor:\n$json");
+ return $json;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
1;
__END__
Modified: vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1765484&r1=1765483&r2=1765484&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS.pm Tue Oct 18 17:30:53 2016
@@ -4510,8 +4510,76 @@ sub get_cluster_info_file_path {
return $self->{cluster_info_file_path};
}
-#///////////////////////////////////////////////////////////////////////////
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_reservation_info_json_file_path
+
+ Parameters : none
+ Returns : string
+ Description : Returns the location where the files resides on the computer that
+ contains JSON formatted information about the reservation. For
+ Linux computers, the location is /etc/reservation_info.json.
+
+=cut
+
+sub get_reservation_info_json_file_path {
+ my $self = shift;
+ if (ref($self) !~ /VCL::Module::OS/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+ return $self->{reservation_info_json_file_path} if $self->{reservation_info_json_file_path};
+ $self->{reservation_info_json_file_path} = '/etc/reservation_info.json';
+ notify($ERRORS{'DEBUG'}, 0, "determined reservation info JSON file path file path for " . ref($self) . " OS module: $self->{reservation_info_json_file_path}");
+ return $self->{reservation_info_json_file_path};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 create_reservation_info_json_file
+
+ Parameters : none
+ Returns : boolean
+ Description : Creates a text file on the computer containing reservation data
+ in JSON format.
+
+=cut
+sub create_reservation_info_json_file {
+ my $self = shift;
+ if (ref($self) !~ /VCL::Module::OS/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+
+ my $json_file_path = $self->get_reservation_info_json_file_path() || return;
+ my $json_string = $self->data->get_reservation_info_json_string() || return;
+ return $self->create_text_file($json_file_path, $json_string);
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 delete_reservation_info_json_file
+
+ Parameters : none
+ Returns : boolean
+ Description : Deletes the text file on the computer containing reservation data
+ in JSON format. This is important when sanitizing a computer.
+
+=cut
+
+sub delete_reservation_info_json_file {
+ my $self = shift;
+ if (ref($self) !~ /VCL::Module::OS/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+
+ my $json_file_path = $self->get_reservation_info_json_file_path() || return;
+ return $self->delete_file($json_file_path);
+}
+
+#///////////////////////////////////////////////////////////////////////////
1;
__END__
Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm?rev=1765484&r1=1765483&r2=1765484&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Tue Oct 18 17:30:53 2016
@@ -10973,7 +10973,7 @@ sub run_script {
notify($ERRORS{'WARNING'}, 0, "failed to execute script on $computer_node_name: '$script_path', command: '$command'");
return;
}
-
+
# Create a log file containing the output
my $logfile_contents = "$timestamp - $script_path executed by vcld";
my $header_line_length = length($logfile_contents);
@@ -12019,6 +12019,30 @@ sub get_cluster_info_file_path {
return $self->{cluster_info_file_path};
}
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_reservation_info_json_file_path
+
+ Parameters : none
+ Returns : string
+ Description : Returns the location where the files resides on the computer that
+ contains JSON formatted information about the reservation.
+
+=cut
+
+sub get_reservation_info_json_file_path {
+ my $self = shift;
+ if (ref($self) !~ /VCL::Module::OS/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+ return;
+ }
+ return $self->{reservation_info_json_file_path} if $self->{reservation_info_json_file_path};
+
+ my $systemroot_value = $self->get_environment_variable_value('SYSTEMDRIVE') || 'C:';
+ $self->{reservation_info_json_file_path} = "$systemroot_value/reservation_info.json";
+ notify($ERRORS{'DEBUG'}, 0, "determined reservation info JSON file path file path for " . ref($self) . " OS module: $self->{reservation_info_json_file_path}");
+ return $self->{reservation_info_json_file_path};
+}
#/////////////////////////////////////////////////////////////////////////////
Modified: vcl/trunk/managementnode/lib/VCL/reclaim.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/reclaim.pm?rev=1765484&r1=1765483&r2=1765484&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/reclaim.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/reclaim.pm Tue Oct 18 17:30:53 2016
@@ -329,6 +329,13 @@ sub call_os_sanitize {
my $computer_shortname = $self->data->get_computer_short_name();
+ # Delete the reservation info JSON file
+ my $enable_experimental_features = get_variable('enable_experimental_features', 0);
+ if ($enable_experimental_features && !$self->os->delete_reservation_info_json_file()) {
+ notify($ERRORS{'WARNING'}, 0, "failed to delete reservation info JSON file on $computer_shortname, computer will be reloaded");
+ $self->insert_reload_and_exit();
+ }
+
# Attempt to call OS module's sanitize() subroutine
# This subroutine should perform all the tasks necessary to sanitize the OS if it was reserved and not logged in to
notify($ERRORS{'DEBUG'}, 0, "calling " . ref($self->os) . "::sanitize() subroutine");
Modified: vcl/trunk/managementnode/lib/VCL/reserved.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/reserved.pm?rev=1765484&r1=1765483&r2=1765484&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/reserved.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/reserved.pm Tue Oct 18 17:30:53 2016
@@ -200,6 +200,12 @@ sub process {
$self->reservation_failed("update_cluster failed");
}
+ # Create a JSON file containing the reservation info
+ my $enable_experimental_features = get_variable('enable_experimental_features', 0);
+ if ($enable_experimental_features) {
+ $self->os->create_reservation_info_json_file();
+ }
+
# Check if OS module's post_reserve() subroutine exists
if ($self->os->can("post_reserve") && !$self->os->post_reserve()) {
$self->reservation_failed("OS module post_reserve failed");
Modified: vcl/trunk/managementnode/lib/VCL/utils.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1765484&r1=1765483&r2=1765484&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/utils.pm Tue Oct 18 17:30:53 2016
@@ -70,6 +70,7 @@ use List::Util qw(min max);
use HTTP::Headers;
use RPC::XML::Client;
use Scalar::Util 'blessed';
+use Storable qw(dclone);
use Data::Dumper;
use Cwd;
use Sys::Hostname;
@@ -223,6 +224,9 @@ our @EXPORT = qw(
parent_directory_path
populate_reservation_natport
preplogfile
+ prune_array_reference
+ prune_hash_child_references
+ prune_hash_reference
read_file_to_array
remove_array_duplicates
rename_vcld_process
@@ -2506,7 +2510,7 @@ sub known_hosts {
=head2 getusergroupmembers
Parameters : usergroupid
- Returns : array of user group memebers
+ Returns : array of user group members
Description : queries database and collects user members of supplied usergroupid
=cut
@@ -7164,7 +7168,7 @@ sub get_computer_info {
# Add the column for predictive module info
my @columns = @{$database_table_columns->{module}};
for my $column (@columns) {
- $select_statement .= "predictivemodule.$column AS 'predictivemodule-$column',\n";
+ $select_statement .= "predictivemodule.$column AS 'predictivemodule-$column',\n";
}
# Remove the comma after the last column line
@@ -14377,6 +14381,159 @@ sub wrap_string {
}
#/////////////////////////////////////////////////////////////////////////////
+
+=head2 prune_hash_reference
+
+ Parameters : $hash_ref, $prune_regex
+ Returns : hash reference
+ Description :
+
+=cut
+
+sub prune_hash_reference {
+ my ($hash_ref_argument, $prune_regex) = @_;
+ if (!defined($hash_ref_argument)) {
+ notify($ERRORS{'WARNING'}, 0, "hash reference argument was not supplied");
+ return;
+ }
+ elsif (!ref($hash_ref_argument) || ref($hash_ref_argument) ne 'HASH') {
+ notify($ERRORS{'WARNING'}, 0, "argument is not a hash reference:\n" . format_data($hash_ref_argument));
+ return;
+ }
+ elsif (!defined($prune_regex)) {
+ notify($ERRORS{'WARNING'}, 0, "prune regex argument was not supplied, returning original hash reference");
+ return $hash_ref_argument;
+ }
+
+ # Create a clone if this wasn't recursively called
+ my $calling_subroutine = get_calling_subroutine();
+ my $hash_ref;
+ if ($calling_subroutine =~ /^prune/) {
+ $hash_ref = $hash_ref_argument;
+ }
+ else {
+ $hash_ref = dclone($hash_ref_argument);
+ }
+
+ my $result = {};
+ for my $key (keys %$hash_ref) {
+ # Don't add keys which match the regex
+ if ($key =~ /$prune_regex/) {
+ next;
+ }
+
+ my $type = ref($hash_ref->{$key});
+ if (!$type) {
+ # If the value is not a reference, simply add it to the result
+ $result->{$key} = $hash_ref->{$key};
+ next;
+ }
+ elsif ($type eq 'HASH') {
+ $result->{$key} = prune_hash_reference($hash_ref->{$key}, $prune_regex);
+ }
+ elsif ($type eq 'ARRAY') {
+ $result->{$key} = prune_array_reference($hash_ref->{$key}, $prune_regex);
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "unsupported type: $type");
+ }
+ }
+ return $result;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 prune_array_reference
+
+ Parameters : $array_ref, $prune_regex
+ Returns : array reference
+ Description :
+
+=cut
+
+sub prune_array_reference {
+ my ($array_ref_argument, $prune_regex) = @_;
+ if (!defined($array_ref_argument)) {
+ notify($ERRORS{'WARNING'}, 0, "array reference argument was not supplied");
+ return;
+ }
+ elsif (!ref($array_ref_argument) || ref($array_ref_argument) ne 'ARRAY') {
+ notify($ERRORS{'WARNING'}, 0, "argument is not a array reference:\n" . format_data($array_ref_argument));
+ return;
+ }
+ elsif (!defined($prune_regex)) {
+ notify($ERRORS{'WARNING'}, 0, "prune regex argument was not supplied, returning original array reference");
+ return $array_ref_argument;
+ }
+
+ # Create a clone if this wasn't recursively called
+ my $calling_subroutine = get_calling_subroutine();
+ my $array_ref;
+ if ($calling_subroutine =~ /^prune/) {
+ $array_ref = $array_ref_argument;
+ }
+ else {
+ $array_ref = dclone($array_ref_argument);
+ }
+
+ my $result = [];
+ for my $element (@$array_ref) {
+ my $type = ref($element);
+ if (!$type) {
+ push @$result, $element;
+ }
+ elsif ($type eq 'ARRAY') {
+ push @$result, prune_array_reference($element, $prune_regex);
+ }
+ elsif ($type eq 'HASH') {
+ push @$result, prune_hash_reference($element, $prune_regex);
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "unsupported type: $type");
+ }
+ }
+
+ return $result;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 prune_hash_child_references
+
+ Parameters : $hash_ref
+ Returns : hash reference
+ Description : Makes a copy of the hash reference. Removes all keys that contain
+ references as data.
+
+=cut
+
+sub prune_hash_child_references {
+ my ($hash_ref_argument) = @_;
+ if (!defined($hash_ref_argument)) {
+ notify($ERRORS{'WARNING'}, 0, "hash reference argument was not supplied");
+ return;
+ }
+ elsif (!ref($hash_ref_argument) || ref($hash_ref_argument) ne 'HASH') {
+ notify($ERRORS{'WARNING'}, 0, "argument is not a hash reference:\n" . format_data($hash_ref_argument));
+ return;
+ }
+
+ # Create a clone
+ my $hash_ref = dclone($hash_ref_argument);
+
+ my $result = {};
+ for my $key (keys %$hash_ref) {
+ if (ref($hash_ref->{$key})) {
+ next;
+ }
+ else {
+ $result->{$key} = $hash_ref->{$key};
+ }
+ }
+ return $result;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
1;
__END__