# IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # bos720 src/bos/usr/lpp/bosinst/samples/NIM/Info.pm 1.1 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 2008,2009 # All Rights Reserved # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # IBM_PROLOG_END_TAG # @(#)57 1.1 src/bos/usr/lpp/bosinst/samples/NIM/Info.pm, bosinst, bos720 3/29/09 15:20:52 package NIM::Info; =head1 NAME NIM::Info =over 2 =item Used to access NIM information and configuration data. =back =head1 VARIABLES =head2 %Settings =over 2 =item * verbose =back =head1 FUNCTIONS =cut #------------------------------------------------------------------------------- BEGIN { # print "NIM::Info BEGIN\n"; use FileHandle; use NIM::Util qw(:DEFAULT !log_print !log_printf); use Hash::Util; %Settings = ('verbose' => 0); } #------------------------------------------------------------------------------- INIT { # print "NIM::Info INIT\n"; if ($Settings{'verbose'}) { print_settings($NIM::Util::Settings{'log_file_handle'}); } } #------------------------------------------------------------------------------- sub print_settings { my ($fh) = @_; if (! $fh) { $fh = STDOUT; } print $fh "NIM::Info::Settings:\n"; while (my ($key, $value) = each(%Settings)) { print $fh "\t$key = \'$value\'\n"; } } #------------------------------------------------------------------------------- sub log_print { if ($Settings{'verbose'}) { NIM::Util::log_print(@_); } } #------------------------------------------------------------------------------- sub log_printf { if ($Settings{'verbose'}) { NIM::Util::log_printf(@_); } } #------------------------------------------------------------------------------- =head2 new =over 2 =item C =back =head3 DESCRIPTION =over 2 =item Creates a NIM::Info hash object. The instance of the NIM::Info object is a snapshot of the NIM database. =back =head3 PARAMETERS =over 2 =item * $command (OPTIONAL) =back =head3 RETURNS =over 2 =item * Reference to the newly instantiated NIM::Info hash object. =back =head3 EXCEPTIONS =cut #------------------------------------------------------------------------------- sub new { my $type = shift; my ($command) = @_; $command = ((defined $command) ? $command : ''); log_print "NIM::Info::new(\'$command\')\n"; my $this = {}; bless $this, $type; $this->{'command'} = $command; $this->{'hash'} = create_hash($command); # $this->print(); return $this; } #------------------------------------------------------------------------------- =head2 refresh =over 2 =item C<$info-Erefresh($command)> =back =head3 DESCRIPTION =over 2 =item Refreshes the NIM::Info data by querying NIM again. =back =head3 PARAMETERS =over 2 =item * $command (OPTIONAL) =back =head3 RETURNS =over 2 =item * Reference to this instance. =back =head3 EXCEPTIONS =cut #------------------------------------------------------------------------------- sub refresh { my $this = shift; my ($command) = @_; $command = ((defined $command) ? $command : ''); log_print "NIM::Info::refresh(\'$command\')\n"; $this->{'command'} = $command; $this->{'hash'} = create_hash($command); return $this; } #------------------------------------------------------------------------------- =head2 update =over 2 =item C<$info-Eupdate($command)> =back =head3 DESCRIPTION =over 2 =item Updates the NIM::Info data by querying NIM and merging/overwriting the new data with the data already held by this instance. =back =head3 PARAMETERS =over 2 =item * $command (OPTIONAL) =back =head3 RETURNS =over 2 =item * Reference to this instance. =back =head3 EXCEPTIONS =cut #------------------------------------------------------------------------------- sub update { my $this = shift; my ($command) = @_; $command = ((defined $command) ? $command : ''); log_print "NIM::Info::update(\'$command\')\n"; my $updates = create_hash($command); my $this_hash = $this->{'hash'}; while (my ($obj_name, $attr_hash) = each(%$updates)) { $this_hash->{$obj_name} = $attr_hash; # print "$obj_name = \n"; # yyy while (my ($attr_name, $attr_value) = each(%$attr_hash)) { my @attr_array = @$attr_value; # print "\t$attr_name = @attr_array\n"; # yyy } } return $this; } #------------------------------------------------------------------------------- sub create_hash { my ($lsnim_cmd) = @_; if (! $lsnim_cmd) { $lsnim_cmd = "$Lang $Cmds{'lsnim'} -lF 2>/dev/null"; } log_print "NIM::Info::create_hash(\'$lsnim_cmd\')\n"; my %rc = (); open(LSNIM, "$lsnim_cmd |") || die "Can't run $lsnim_cmd: $!"; my $lineno = 0; my $obj_name = ''; my $key = ''; while () { my $line = $_; chomp($line); # print "$obj_name line = \'$line\'\n"; # yyy $lineno++; if ($line =~ m/^([^\s]+):$/) { $obj_name = $1; $key = ''; } elsif ($obj_name ne '') { if ($line =~ m/^ ([^\s]+) += *(.*)$/) { $key = $1; if (! defined $2) { $2 = ''; } if (! defined $rc{$obj_name}{$key}) { $rc{$obj_name}{$key} = [ $2 ]; } else { push @{$rc{$obj_name}{$key}}, ($2); } } elsif (($key ne '') && (defined $rc{$obj_name}{$key}) && ($line =~ m/^(.*)$/)) { my $value = pop @{$rc{$obj_name}{$key}}; $value = $value . "\n" . $1; push @{$rc{$obj_name}{$key}}, ($value); } else { NIM::Util::log_print "Error parsing lsnim results line ${lineno}: \'$line\'\n"; warn "Error parsing results of $lsnim_cmd"; } } else { NIM::Util::log_print "Error parsing lsnim results line ${lineno}: \'$line\'\n"; warn "Error parsing results of $lsnim_cmd"; } } close(LSNIM); return \%rc; } #------------------------------------------------------------------------------- sub print { my $this = shift; if (1) # not sure why this gives a GLOB reference error here so must revert to alternate method { my ($fh) = @_; if (! $fh) { $fh = STDOUT; } my $nim_hash = $this->{'hash'}; while (my ($obj_name, $attr_hash) = each(%$nim_hash)) { print $fh "$obj_name:\n"; while (my ($key, $values) = each(%$attr_hash)) { foreach my $value (@$values) { print $fh "\t$key = $value\n"; } } } } my $comment = q { else { local (*fh) = @_; if (fh) { select fh; } else { select STDOUT; } my $nim_hash = $this->{'hash'}; while (my ($obj_name, $attr_hash) = each(%$nim_hash)) { print fh "$obj_name:\n"; while (my ($key, $values) = each(%$attr_hash)) { foreach my $value (@$values) { print fh "\t$key = $value\n"; } } } select STDOUT; } }; } #------------------------------------------------------------------------------- sub size { my $this = shift; return scalar keys %{$this->{'hash'}}; } #------------------------------------------------------------------------------- sub empty { my $this = shift; return ($this->size() == 0); } #------------------------------------------------------------------------------- sub get_object_names { my $this = shift; my @names = keys %{$this->{'hash'}}; return \@names; } #------------------------------------------------------------------------------- sub get_first_object_name { my $this = shift; my @names = keys %{$this->{'hash'}}; return ((scalar @names) ? $names[0] : ""); } #------------------------------------------------------------------------------- sub get_objects { my $this = shift; return $this->{'hash'}; } #------------------------------------------------------------------------------- sub get_first_object { my $this = shift; my @rc = ("", {}); while (my ($obj_name, $attr_hash) = each(%{$this->{'hash'}})) { @rc = ($obj_name, $attr_hash); last; } keys %{$this->{'hash'}}; # reset each iterator return @rc; } #------------------------------------------------------------------------------- sub get_attr_values { my $this = shift; my ($object_name, $attr_name) = @_; # log_print "NIM::Info::get_attr_values($object_name, $attr_name)\n"; my @rc = (); eval { @rc = @{$this->{'hash'}->{$object_name}{$attr_name}}; }; return ($@ ? () : @rc); } #------------------------------------------------------------------------------- sub get_first_attr_value { my $this = shift; my ($object_name, $attr_name) = @_; my @rc = (); eval { if ($this->{'hash'}->{$object_name}{$attr_name}) { @rc = @{$this->{'hash'}->{$object_name}{$attr_name}}; } }; return ($@ ? '' : $rc[0]); } #------------------------------------------------------------------------------- sub select_with_regexp_key_values { my $this = shift; my (%query) = @_; log_print "NIM::Info::select_with_regexp_key_values(@_)\n"; my $rc = {}; bless $rc; my %rc_hash = %{$this->{'hash'}}; $rc->{'hash'} = \%rc_hash; while (my ($obj_name, $attr_hash) = each(%rc_hash)) { my @attr_keys = keys %$attr_hash; my $num_keys = scalar @attr_keys; # log_print "\tTesting $obj_name - $num_keys\n"; my $keep = 1; while (my ($query_key, $query_value) = each(%query)) { my $matched = 0; # log_print "\tTrying to match $query_key/$query_value\n"; if ('name' =~ $query_key) { if ($obj_name =~ $query_value) { # log_print "\tMatched $obj_name/$query_value\n"; $matched = 1; } } else { foreach my $attr_key (@attr_keys) { if ($attr_key =~ $query_key) { my $values = $attr_hash->{$attr_key}; foreach my $value (@$values) { if ($value =~ $query_value) { # log_print "\tMatched $obj_name/$attr_key/$value\n"; $matched = 1; last; } } if ($matched) { last; } } } } # if can't match current sub-query, then query failed if ($matched == 0) { $keep = 0; last; } } if ($keep == 0) { keys %query; # reset each iterator # log_print "\tDeleting $obj_name\n"; delete $rc_hash{$obj_name}; } } log_printf("\t%d selected\n", $rc->size()); return $rc; } #------------------------------------------------------------------------------- sub select { my $this = shift; my (%query) = @_; log_print "NIM::Info::select(@_)\n"; my $rc = {}; bless $rc; my %rc_hash = %{$this->{'hash'}}; $rc->{'hash'} = \%rc_hash; while (my ($query_key, $query_value) = each(%query)) { if ($query_key eq 'name') { foreach my $obj_name (keys %rc_hash) { if (! ($obj_name =~ $query_value)) { delete $rc_hash{$obj_name}; } } } else { while (my ($obj_name, $attr_hash) = each(%rc_hash)) { my $keep = 0; if (exists $attr_hash->{$query_key}) { my $values = $attr_hash->{$query_key}; foreach my $value (@$values) { if ($value =~ $query_value) { $keep = 1; last; } } } if ($keep == 0) { delete $rc_hash{$obj_name}; } } } } log_printf("\t%d selected\n", $rc->size()); return $rc; } #------------------------------------------------------------------------------- sub join { my $this = shift; my (@objs) = @_; log_print "NIM::Info::join()\n"; my $rc = {}; bless $rc; my %rc_hash = %{$this->{'hash'}}; $rc->{'hash'} = \%rc_hash; foreach my $obj (@objs) { my $hash = $obj->{'hash'}; while (my ($obj_name, $attr_hash) = each(%$hash)) { $rc_hash{$obj_name} = $attr_hash; } } return $rc; } #------------------------------------------------------------------------------- sub locate_mksysb_by_location { my $this = shift; my ($mksysb_pn) = @_; return $this->select(('class' => '^resources$', 'type' => '^mksysb$', 'location' => "^$mksysb_pn\$")); } #------------------------------------------------------------------------------- sub locate_mksysb_by_name { my $this = shift; my ($nim_mksysb_name) = @_; return $this->select(('class' => '^resources$', 'type' => '^mksysb$', 'name' => "^$nim_mksysb_name\$")); } #------------------------------------------------------------------------------- sub locate_available_mksysb_by_name_and_location { my $this = shift; my ($nim_mksysb_name, $mksysb_pn) = @_; return $this->select(('class' => '^resources$', 'type' => '^mksysb$', 'Rstate' => '^ready for use$', 'name' => "^$nim_mksysb_name\$", 'location' => "^$mksysb_pn\$")); } #------------------------------------------------------------------------------- sub locate_spot_by_location { my $this = shift; my ($spot_dir) = @_; return $this->select(('class' => '^resources$', 'type' => '^spot$', 'location' => "^$spot_dir\$")); } #------------------------------------------------------------------------------- sub locate_spot_by_name { my $this = shift; my ($nim_spot_name) = @_; return $this->select(('class' => '^resources$', 'type' => '^spot$', 'name' => "^$nim_spot_name\$")); } #------------------------------------------------------------------------------- sub locate_spot_by_mksysb_source { my $this = shift; my ($mksysb_name) = @_; return $this->select(('class' => '^resources$', 'type' => '^spot$', 'mksysb_source' => "^$mksysb_name\$")); } #------------------------------------------------------------------------------- sub locate_available_spot_by_name_and_location { my $this = shift; my ($nim_spot_name, $spot_dir) = @_; return $this->select(('class' => '^resources$', 'type' => '^spot$', "name" => "^$nim_spot_name\$", 'location' => "^$spot_dir\$", 'Rstate' => '^ready for use$')); } #------------------------------------------------------------------------------- sub locate_available_spots_by_oslevel_r { my $this = shift; my ($oslevel_r) = @_; return $this->select(('class' => '^resources$', 'type' => '^spot$', 'oslevel_r' => "^$oslevel_r\$", 'Rstate' => '^ready for use$')); } #------------------------------------------------------------------------------- sub locate_masters { my $this = shift; return $this->select(('class' => '^machines$', 'type' => '^master$')); } #------------------------------------------------------------------------------- sub locate_machine_by_name { my $this = shift; my ($name) = @_; return $this->select(('class' => '^machines$', 'type' => '^standalone$', 'name' => "^$name\$")); } #------------------------------------------------------------------------------- sub locate_resource_group_by_name { my $this = shift; my ($name) = @_; return $this->select(('class' => '^groups$', 'type' => '^res_group$', 'name' => "^$name\$")); } #------------------------------------------------------------------------------- sub locate_resource_groups_by_member { my $this = shift; my ($member_name) = @_; return $this->select_with_regexp_key_values(('^class$' => '^groups$', '^type$' => '^res_group$', '^member[1-9][0-9]*$' => "^$member_name\$")); } #------------------------------------------------------------------------------- sub get_resource_group_members { my $this = shift; my ($name) = @_; log_print("NIM::Deploy::Mksysb::get_resource_group_members(\'$name\')\n"); my @rc = (); my $groups = $this->select(('name' => "^$name\$", 'class' => '^groups$', 'type' => '^res_group$')); if (! $groups->empty()) { my ($obj_name, $attr_hash) = $groups->get_first_object(); while (my ($key, $values) = each(%$attr_hash)) { if ($key =~ m/^member[1-9][0-9]*$/) { # log_print "\t\`$key\` = \`$values->[0]\`\n"; push @rc, ($values->[0]); } } } return @rc; } #------------------------------------------------------------------------------- sub locate_machine_group_by_name { my $this = shift; my ($name) = @_; return $this->select(('class' => '^groups$', 'type' => '^mac_group$', 'name' => "^$name\$")); } #------------------------------------------------------------------------------- sub locate_machine_groups_by_member { my $this = shift; my ($member_name) = @_; return $this->select_with_regexp_key_values(('^class$' => '^groups$', '^type$' => '^mac_group$', '^member[1-9][0-9]*$' => "^$member_name\$")); } #------------------------------------------------------------------------------- sub locate_bosinst_data_by_name { my $this = shift; my ($name) = @_; return $this->select(('class' => '^resources$', 'type' => '^bosinst_data$', 'name' => "^$name\$")); } #------------------------------------------------------------------------------- sub locate_script_by_name { my $this = shift; my ($name) = @_; return $this->select(('class' => '^resources$', 'type' => '^script$', 'name' => "^$name\$")); } #------------------------------------------------------------------------------- sub locate_fb_script_by_name { my $this = shift; my ($name) = @_; return $this->select(('class' => '^resources$', 'type' => '^fb_script$', 'name' => "^$name\$")); } #------------------------------------------------------------------------------- sub locate_image_data_by_name { my $this = shift; my ($name) = @_; return $this->select(('class' => '^resources$', 'type' => '^image_data$', 'name' => "^$name\$")); } #------------------------------------------------------------------------------- sub locate_resolv_conf_by_name { my $this = shift; my ($name) = @_; return $this->select(('class' => '^resources$', 'type' => '^resolv_conf$', 'name' => "^$name\$")); } #------------------------------------------------------------------------------- sub locate_resource_by_name { my $this = shift; my ($name) = @_; return $this->select(('class' => '^resources$', 'name' => "^$name\$")); } #------------------------------------------------------------------------------- sub set_comments { my $this = shift; my ($object_name, $comments) = @_; my $commentsStr = CORE::join("\n", @$comments); invoke("$Cmds{'nim'} -o change -a comments=\"$commentsStr\" $object_name"); } #------------------------------------------------------------------------------- sub get_comments { my $this = shift; my ($object_name) = @_; return $this->get_attr_values($object_name, 'comments'); } #------------------------------------------------------------------------------- sub test { my $nim_info = new NIM::Info(); $nim_info->refresh(); my $num_entries = $nim_info->size(); print "## Init Results - $num_entries\n"; $nim_info->print(); my $results = $nim_info->select(('serves' => 'master_net_conf')); print "## serves => master_net_conf results\n"; $results->print(); my $mksysb_results = $nim_info->select(('type' => '^mksysb$', "version" => '^6$', 'Rstate' => '^ready for use$')); print "## mksysb results\n"; $mksysb_results->print(); my $spot_results = $nim_info->select(('type' => '^spot', 'oslevel_r' => '^6100-00$', 'Rstate' => '^ready for use$')); print "## spot results\n"; $spot_results->print(); my $group_results = $nim_info->locate_resource_groups_by_member('6100-00master_sysb'); print "## res_group results\n"; $group_results->print(); my $joined_results = $results->join(($mksysb_results)); $num_entries = $joined_results->size(); print "## joined results - $num_entries\n"; $joined_results->print($joined_results); } 1; # __END__ =head1 AUTHOR IBM =head1 BUGS Please report any bugs to the L. =head1 SUPPORT =head1 ACKNOWLEDGEMENTS =head1 SEE ALSO =cut