# IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # bos720 src/bos/usr/lpp/bosinst/samples/NIM/Deploy.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 # @(#)52 1.1 src/bos/usr/lpp/bosinst/samples/NIM/Deploy.pm, bosinst, bos720 3/29/09 15:20:44 package NIM::Deploy; # Deployable object / image class #------------------------------------------------------------------------------- =pod =head1 NAME NIM::Deploy =over 2 =item NIM::Deploy base class. =back =head1 VARIABLES =head2 %Settings =over 2 =item * project =item * accept_license =item * nim_res_dir =item * work_dir =item * verbose =back =head2 %Defaults =over 2 =item * type =item * name =item * location =item * ae_dir =item * ae_xml =item * ae_cmd =back =head1 FUNCTIONS =cut #------------------------------------------------------------------------------- BEGIN { # print "NIM::Deploy BEGIN\n"; use Hash::Util; use File::Path; use File::Basename; use NIM::Util qw(:DEFAULT !log_print !log_printf); %Settings = ('project' => 'sysp', 'accept_licenses' => 0, 'nim_res_dir' => '/export/nim', 'work_dir' => '/var/ibm/systemp/nim', 'verbose' => 0); # may need to default some of these values from those of the nim master's %Defaults = ('type' => undef, 'name' => undef, 'location' => undef, 'ae_dir' => undef, 'ae_xml' => undef, 'ae_cmd' => undef); } #------------------------------------------------------------------------------- END { # print "NIM::Deploy END\n"; my $rc = $?; # print "work_dir = $Settings{'work_dir'}/$$\n"; if ($Settings{'work_dir'}) { if (-e "$Settings{'work_dir'}/$$") { if ($NIM::Util::Settings{'log_file_name'}) { my $fn = basename($NIM::Util::Settings{'log_file_name'}); my $result = invoke("ls -1 $Settings{'work_dir'}/$$ | grep -v $fn | wc -l"); if ($#$result >= 0) { my $num_fns = $result->[0]; chomp($num_fns); if ($num_fns > 0) { # print "cd $Settings{'work_dir'}/$$; ls -1 | grep -v $fn | xargs rm -r; cd -\n"; invoke("cd $Settings{'work_dir'}/$$; ls -1 | grep -v $fn | xargs rm -r; cd -"); } } } else { # print "rm -r $Settings{'work_dir'}/$$\n"; `rm -r $Settings{'work_dir'}/$$`; } } } $? = $rc; } #------------------------------------------------------------------------------- sub print_settings { my $this = shift; my ($fh) = @_; if (! $fh) { $fh = STDOUT; } print $fh "NIM::Deploy::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(@_); } } #------------------------------------------------------------------------------- sub get_resource_dir { my $this = shift; my ($resource_type) = @_; my $rc = $Settings{'nim_res_dir'} . '/' . $resource_type; if (! -e $rc) { mkpath($rc); } return $rc } #------------------------------------------------------------------------------- sub new { my $type = shift; my %args = @_; log_print("NIM::Deploy::new()\n"); my $this = {}; bless $this, $type; $Settings{'work_dir'} = NIM::Util::create_work_dir($Settings{'work_dir'}); if ($NIM::Deploy::Settings{'work_dir'}) { if (-e "$Settings{'work_dir'}/$$") { # conflicts with work dir in Util.pm such that the log file is getting erased # `rm -r $Settings{'work_dir'}/$$/*`; } else { `mkdir -p $Settings{'work_dir'}/$$`; } } log_print "\twork_dir = \'$Settings{'work_dir'}\'\n"; if ($Settings{'verbose'}) { $this->print_settings($NIM::Util::Settings{'log_file_handle'}); } my $nim_info = undef; if (defined $NIM::Config{'info'}) { $nim_info = $NIM::Config{'info'}; $nim_info->refresh(); } else { $nim_info = new NIM::Info(); } $this->{'info'} = $nim_info; $this->{'deploy_index'} = $this->set_deploy_index(); $this->{'group_index'} = 0; log_printf("\tdeploy_index = %08x\n", $this->{'deploy_index'}); my $nim_masters = $nim_info->locate_masters(); $this->{'nim_master_name'} = $nim_masters->get_first_object_name(); $this->{'nim_master_name'} || die "Unable to find nim master: $!"; log_print "\tmaster = \'$this->{'nim_master_name'}\'\n"; ### $this->{'type'} = (defined $args{'type'} ? $args{'type'} : $Defaults{'type'}); $this->{'name'} = (defined $args{'name'} ? $args{'name'} : $Defaults{'name'}); $this->{'location'} = (defined $args{'location'} ? $args{'location'} : $Defaults{'location'}); $this->{'ae_dir'} = (defined $args{'ae_dir'} ? $args{'ae_dir'} : ''); $this->{'ae_xml'} = (defined $args{'ae_xml'} ? $args{'ae_xml'} : ''); $this->{'ae_cmd'} = (defined $args{'ae_cmd'} ? $args{'ae_cmd'} : ''); return $this; } #------------------------------------------------------------------------------- sub delete { my $this = shift; log_print("NIM::Deploy::delete()\n"); my $mac_group_name = $this->get_nim_name('mac_group'); my $mac_groups = $this->{'info'}->locate_machine_group_by_name($mac_group_name); if (! $mac_groups->empty()) { invoke("$Cmds{'nim'} -o remove $mac_group_name"); } } #------------------------------------------------------------------------------- sub is_available_deploy_index { my $this = shift; my ($deploy_index) = @_; my $re = sprintf('%s-(?:res_group|spot|mksysb|mac_group)-%08x', $Settings{'project'}, $deploy_index); my $results = $this->{'info'}->select_with_regexp_key_values(('^name$' => "^$re\$")); if ($results->empty()) { return 1; } return 0; } #------------------------------------------------------------------------------- sub set_deploy_index { my $this = shift; my ($num) = @_; my $path_name = "$Settings{'work_dir'}/$Settings{'project'}" . '.nim_deploy.index'; use Fcntl; sysopen(FH, $path_name, O_RDWR|O_CREAT, 0644) or die "Can't open $path_name file: $!"; flock(FH, 2) or die "Can't flock $path_name file: $!"; if (! $num) { $num = || 1; seek(FH, 0, 0) or die "Can't rewind $path_name file: $!"; } for ( ; ! $this->is_available_deploy_index($num); $num++) { } truncate(FH, 0) or die "Can't truncate $path_name file: $!"; (print FH $num+1, "\n") or die "Can't write $path_name file: $!"; # do not unlock this until you close close FH; return $num; } #------------------------------------------------------------------------------- sub get_nim_name { my $this = shift; my ($type) = @_; if ($type eq 'res_group') { } elsif ($type eq 'mac_group') { } elsif ($type eq 'resolv_conf') { return sprintf("%s\-%s\-%08x", $Settings{'project'}, $type, $this->{'deploy_index'}); } else { $type = ''; warn "NIM::Deploy::get_nim_name() called with an invalid type: $type"; } return ($type ? sprintf("%s\-%s\-%08x", $Settings{'project'}, $type, $this->{'group_index'}) : ''); } #------------------------------------------------------------------------------- sub rm_from_mac_group { my $this = shift; my ($machine_name) = @_; log_print("NIM::Deploy::rm_from_mac_group(\'$machine_name\')\n"); # yyy } #------------------------------------------------------------------------------- sub add_to_mac_group { my $this = shift; my ($machine_name) = @_; log_print("NIM::Deploy::add_to_mac_group(\'$machine_name\')\n"); # No need to delete the machine from any other machine group to which # it is already a member - i.e. before we can add it to a new machine group - # because this machine group is used for tracking machines deployed to # and not machines with the image currently running. Reasoning is that # we could be using a shared NIM master in which case, a deployment not done # via this program won't update these machine groups appropriately. my $mac_group_name = $this->get_nim_name('mac_group'); my $mac_groups = $this->{'info'}->locate_machine_group_by_name($mac_group_name); if ($mac_groups->empty()) { log_print "\tCreating machine group \'$mac_group_name\'\n"; invoke("$Cmds{'nim'} -o define -t mac_group -a add_member=$machine_name $mac_group_name"); } else { log_print "\tAdding machine group member \'$machine_name\'\n"; invoke("$Cmds{'nim'} -o change -a add_member=$machine_name $mac_group_name"); } } #------------------------------------------------------------------------------- =head2 create_resolv_conf_resource =over 2 =item C<$deploy-Ecreate_resolv_conf_resource($domain, @nameservers)> =back =head3 DESCRIPTION =over 2 =item Creates a NIM resolv_conf resource. =back =head3 PARAMETERS =over 2 =item * $domain (REQUIRED) =item * @nameservers (REQUIRED) =back =head3 RETURNS =over 2 =item * The name of the NIM resolv_conf resource. =item * empty string on failure =back =head3 EXCEPTIONS =cut #------------------------------------------------------------------------------- sub create_resolv_conf_resource { my $this = shift; my ($domain, @nameservers) = @_; my $rc = ''; if ($domain || ($#nameservers >= 0)) { my $resolv_conf_dir = "$NIM::Deploy::Settings{'nim_res_dir'}/resolv_conf"; mkpath($resolv_conf_dir); my $resolv_conf_name = $this->get_nim_name('resolv_conf'); my $resolv_conf_pn = "$resolv_conf_dir/$resolv_conf_name"; if (! -e $resolv_conf_pn) { if (open(RESOLV_CONF, ">$resolv_conf_pn")) { if ($domain) { print RESOLV_CONF "domain $domain\n"; } foreach my $nameserver (@nameservers) { print RESOLV_CONF "nameserver $nameserver\n"; } } } if (-e $resolv_conf_pn) { invoke("$Cmds{'nim'} -o define -t resolv_conf -a server=$this->{'nim_master_name'} -a location=$resolv_conf_pn $resolv_conf_name"); $rc = $resolv_conf_name; } } return $rc; } #------------------------------------------------------------------------------- =head2 delete_resolv_conf_resource =over 2 =item C<$deploy-Edelete_resolv_conf_resource($resolv_conf_name)> =back =head3 DESCRIPTION =over 2 =item Deletes a NIM resolv_conf resource. =back =head3 PARAMETERS =over 2 =item * $resolv_conf_name (REQUIRED) =back =head3 RETURNS =head3 EXCEPTIONS =cut #------------------------------------------------------------------------------- sub delete_resolv_conf_resource { my $this = shift; my ($resolv_conf_name) = @_; my $resolv_conf = $this->{'info'}->locate_resolv_conf_by_name($resolv_conf_name); if (! $resolv_conf->empty()) { my $location = $resolv_conf->get_first_attr_value($resolv_conf_name, 'location'); unlink($location); invoke("$Cmds{'nim'} -o remove $resolv_conf_name"); } } 1; # __END__ #------------------------------------------------------------------------------- =head1 AUTHOR IBM =head1 BUGS Please report any bugs to the L. =head1 SUPPORT =head1 ACKNOWLEDGEMENTS =head1 SEE ALSO =begin html =end html =cut