From d662c5e8b53ca033e1f6f3ae96907ce9135ae407 Mon Sep 17 00:00:00 2001 From: zhaoertao Date: Sun, 26 Jan 2014 22:02:50 -0800 Subject: [PATCH] The scripts used for configuring and provisioning VIOS partition --- xCAT-server/lib/xcat/plugins/nimol.pm | 534 ++++++++++++++++++ xCAT-server/share/xcat/scripts/xcatvio.script | 382 +++++++++++++ xCAT/postscripts/config_bootnicsea | 144 +++++ 3 files changed, 1060 insertions(+) create mode 100644 xCAT-server/lib/xcat/plugins/nimol.pm create mode 100755 xCAT-server/share/xcat/scripts/xcatvio.script create mode 100644 xCAT/postscripts/config_bootnicsea diff --git a/xCAT-server/lib/xcat/plugins/nimol.pm b/xCAT-server/lib/xcat/plugins/nimol.pm new file mode 100644 index 000000000..9f3f94f60 --- /dev/null +++ b/xCAT-server/lib/xcat/plugins/nimol.pm @@ -0,0 +1,534 @@ +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html + +# This module is only used for provisionging VIOS partition through rh MN. + +package xCAT_plugin::nimol; +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; + +use strict; + +use POSIX qw(WNOHANG nice); +use POSIX qw(WNOHANG setsid :errno_h); +use File::Path; +use File::Copy; +use Fcntl qw/:flock/; + +use Data::Dumper; +use Getopt::Long; +Getopt::Long::Configure("bundling"); +Getopt::Long::Configure("pass_through"); + +use xCAT::Table; +use xCAT::MsgUtils; +use xCAT::DBobjUtils; + +sub handled_commands { + return { + copycd => "nimol", + nodeset => "noderes:netboot", + }; +} + +my $global_callback; +sub copy_mksysb { + my $srcpath = shift; + my $dstpath = shift; + my @mksysb_files = (); + my %filehash = (); + my $dstfile = $dstpath."/mksysb/mksysb"; + unless (-e $srcpath."/nimol/ioserver_res/") { + return "No mksysb files found in this CD."; + } + unless (-e $dstpath."/mksysb") { + return "No mksysb directory available in $dstpath."; + } + #my $all_filesize = 0; + my $dir; + opendir($dir, $srcpath."/nimol/ioserver_res/"); + while (my $file = readdir($dir)) { + if ($file =~ /^mksysb/) { + $filehash{$file} = 1; + #my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = $stat($file); + #$all_filesize += $size / 1024 / 1024; + } + } + closedir($dir); + @mksysb_files = sort (keys %filehash); + foreach (@mksysb_files) { + my $rsp; + push @{$rsp->{data}}, "Copying file $_ to $dstfile"; + xCAT::MsgUtils->message("I", $rsp, $global_callback); + system("cat $srcpath/nimol/ioserver_res/$_ >> $dstfile"); + } + return undef; +} +sub copy_spot { + my $srcpath = shift; + my $dstpath = shift; + my $srcfile = $srcpath."/nimol/ioserver_res/ispot.tar.Z"; + my $dstfile = $dstpath."/spot/ispot.tar.Z"; + unless (-e $srcfile) { + return "No spot file found in this CD."; + } + if (-e $dstfile) { + return undef; + } + my $rsp; + push @{$rsp->{data}}, "Copying ispot.tar.z to $dstfile"; + xCAT::MsgUtils->message("I", $rsp, $global_callback); + + copy($srcfile, $dstfile); + xCAT::MsgUtils->message("I", {data=>["Extract file: $dstfile"]}, $global_callback); + system("/bin/tar zxvf $dstfile -C $dstpath/spot > /dev/null"); + return undef; +} +sub copy_bootimg { + my $srcpath = shift; + my $dstpath = shift; + my $srcfile = $srcpath."/nimol/ioserver_res/booti.chrp.mp.ent.Z"; + my $dstfile = $dstpath."/bootimg/booti.chrp.mp.ent.Z"; + unless (-e $srcfile) { + return "No bootimg file found in this CD."; + } + if (-e $dstfile) { + return undef; + } + my $rsp; + push @{$rsp->{data}}, "Copying file booti.chrp.mp.ent.Z to $dstfile"; + xCAT::MsgUtils->message("I", $rsp, $global_callback); + copy($srcfile, $dstfile); + xCAT::MsgUtils->message("I", {data=>["Extract file: $dstfile"]}, $global_callback); + system("/bin/gunzip $dstfile > /dev/null"); + + return undef; +} +sub copy_bosinstdata { + my $srcpath = shift; + my $dstpath = shift; + my $srcfile = $srcpath."/nimol/ioserver_res/bosinst.data"; + my $dstfile = $dstpath."/bosinst_data/bosinst.data"; + unless (-e $srcfile) { + return "No bosinst.data file found in this CD."; + } + if (-e $dstfile) { + return undef; + } + my $rsp; + push @{$rsp->{data}}, "Copying file bosinst.data to $dstfile"; + xCAT::MsgUtils->message("I", $rsp, $global_callback); + copy($srcfile, $dstfile); + return undef; +} +sub preprocess_request { + my $request = shift; + my $callback = shift; + my $command = $request->{command}->[0]; + + if ($command eq 'copycd') { + return [$request]; + } elsif ($command eq 'nodeset') { + my @args = (); + if (ref($request->{arg})) { + @args=@{$request->{arg}}; + } else { + @args=($request->{arg}); + } + if ($args[0] =~ /^osimage=(.*)$/) { + $request->{opt}->{osimage} = $1; + } else { + $callback->({error=>["Only option 'osimage' support"]}, errorcode=>[1]); + $request = {}; + return; + } + print Dumper($request); + return [$request]; + } + + return undef; +} + +sub process_request { + my $request = shift; + my $callback = shift; + my $subreq = shift; + my $command = $request->{command}->[0]; + + if ($command eq 'copycd') { + return copycd($request, $callback, $subreq); + } elsif ($command eq 'nodeset') { + print Dumper($request); + return nodeset($request, $callback, $subreq); + } +} + +sub copycd { + my $request = shift; + my $callback = shift; + my $subreq = shift; + @ARGV = @{$request->{arg}}; + $global_callback = $callback; +# copycd +# -m mntpath +# -p path +# -i inspection +# -a arch +# -f $file +# -w nonoverwrite + my $mntpath; + my $file; + my $distname; + my $path; + my $arch; + GetOptions( 'm=s' => \$mntpath, + 'a=s' => \$arch, + 'f=s' => \$file, + 'p=s' => \$path, + 'n=s' => \$distname, + ); + unless($distname && $file && $mntpath && $arch) { + $callback->({error=>"distname, file or mntpath not specified, $distname, $file, $mntpath"}); + return ; + } + if ($distname && $distname !~ /^vios/i) { + $callback->({error=>"distname incorrect"}); + return ; + } elsif ($arch !~ /^ppc64/i) { + $callback->({error=>"arch incorrect"}); + } elsif (!$file) { + $callback->({error=>"Only suport to use the iso file vios"}); + return; + } + print __LINE__."=====>vios=====.\n"; + print Dumper($request); + my $installroot = "/install"; + my @entries = xCAT::TableUtils->get_site_attribute("installdir"); + my $t_entry = $entries[0]; + if (defined($t_entry)) { + $installroot = $t_entry; + } + # OSLEVEL= 6.1.8.15 + #my $oslevel; + #if (-r "$mntpath/OSLEVEL" and -f "$mntpath/OSLEVEL") { + # my $oslevel_fd; + # open ($mkcd_fd, $mntpath."/OSLEVEL"); + # my $line = <$mkcd_fd>; + # if ($line =~ /^OSLEVEL=\s*(\d*\.\d*\.\d*\.\d*)/) { + # $oslevel_fd = $1; + # } + #} else { + # $callback->({error=>"There is no 'OSLEVEL' file found for this iso file"}); + # return; + #} + my $rsp; + push @{$rsp->{data}}, "Copying media to $installroot/nim/$distname/"; + xCAT::MsgUtils->message("I", $rsp, $callback); + unless($path) { + $path = "$installroot/nim/$distname"; + } + my $omask = umask 0022; + # check the disk number, the 1st or 2nd CD + unless (-e $path) { + mkpath("$path"); + } + unless (-e $path."/mksysb") { + mkpath($path."/mksysb"); + } + unless (-e $path."/spot") { + mkpath($path."/spot"); + } + unless (-e $path."/bootimg") { + mkpath($path."/bootimg"); + } + unless (-e $path."/bosinst_data") { + mkpath($path."/bosinst_data"); + } + umask $omask; + my $expect_cd; + my $oslevel; + unless (-e "$path/expect_cd") { + $expect_cd = 1; + } else { + my $expectcd_fd; + open ($expectcd_fd, "<", "$path/expect_cd"); + $expect_cd = <$expectcd_fd>; + chomp($expect_cd); + close($expectcd_fd); + } + if ($expect_cd eq "END") { + goto CREATE_OBJ; + $callback->({error=>"All the cds for $distname are gotten."}); + return; + } + if (-r "$mntpath/mkcd.data" and -f "$mntpath/mkcd.data") { + my $mkcd_fd; + open ($mkcd_fd, "<", "$mntpath/mkcd.data"); + while (<$mkcd_fd>) { + if (/VOLUME=(\d+)/) { + if ($expect_cd ne $1) { + $callback->({error=>"The $expect_cd cd is expected."}); + return; + } else { + $expect_cd += 1; + } + } elsif (/LASTVOLUME/) { + $expect_cd = "END"; + } + } + close($mkcd_fd); + } else { + $callback->({error=>"There is no 'mkcd' file found for this iso file"}); + return; + } + { # write the expect cd num + my $expectcd_fd; + open ($expectcd_fd, ">", "$path/expect_cd"); + print $expectcd_fd $expect_cd; + close ($expectcd_fd); + } + { + my $oslevel_fd; + open($oslevel_fd, "<", "$mntpath/OSLEVEL"); + $oslevel = <$oslevel_fd>; + chomp $oslevel; + $oslevel =~ s/OSLEVEL=\s*(\d+\.\d+\.\d+\.\d+)/$1/; + close($oslevel_fd); + } + my $res; + $res = ©_mksysb($mntpath, $path); + if (defined($res)) { + $callback->({error=>$res}); + return; + } + $res = ©_spot($mntpath, $path); + if (defined($res)) { + $callback->({error=>$res}); + return; + } + $res = ©_bootimg($mntpath, $path); + if (defined($res)) { + $callback->({error=>$res}); + return; + } + $res = ©_bosinstdata($mntpath, $path); + if (defined($res)) { + $callback->({error=>$res}); + return; + } +CREATE_OBJ: + if ($expect_cd eq "END") { + my $imagename = $distname.'_sysb'; + xCAT::MsgUtils->message("I", {data=>["create osimage object: $imagename"]}, $callback); + my $osimagetab = xCAT::Table->new('osimage', -create=>1); + if ($osimagetab) { + my %key_col = (imagename=>$imagename); + my %tb_cols = (imagetype=>"NIM", + provmethod=>"nimol", + osname=>"AIX", + osdistroname=>$distname, + osvers=>$oslevel, + osarch=>$arch); + print Dumper(%tb_cols); + $osimagetab->setAttribs(\%key_col, \%tb_cols); + } else { + $callback->({error=>"Can not open 'osimage' table"}); + return; + } + $osimagetab->close(); + } +} + +sub update_export { + my $export_fd; + open ($export_fd, "<", "/etc/exports"); + flock($export_fd,LOCK_SH); + my @curr_export=<$export_fd>; + flock($export_fd,LOCK_UN); + close($export_fd); + my @new_export = (); + my $need_update = 0; + my $i = 0; + for ($i = 0; $i < scalar(@curr_export); $i++) { + my $line = $curr_export[$i]; + if ($line =~ /^\/install\s*\*\((.*)\)/) { + my @tmp_options = split /,/,$1; + unless (grep(/insecure/,@tmp_options)) { + push @tmp_options, "insecure"; + $need_update = 1; + } + push @new_export, join(',',@tmp_options); + } else { + push @new_export, $line; + } + } + unless ($need_update) { + return; + } + my $new_export_fd; + open($new_export_fd, ">>", "/etc/exports"); + flock($new_export_fd,LOCK_EX); + seek($new_export_fd,0,0); + truncate($new_export_fd,0); + for my $l (@new_export) { print $new_export_fd $l; } + flock($new_export_fd,LOCK_UN); + close($new_export_fd); + system("service nfs restart"); +} + +sub update_syslog { + my $syslog_fd; + open ($syslog_fd, "<", "/etc/rsyslog.conf"); + flock($syslog_fd,LOCK_SH); + my @curr_syslog=<$syslog_fd>; + flock($syslog_fd,LOCK_UN); + close($syslog_fd); + unless (grep /local2.*nimol\.log/, @curr_syslog) { + my $new_syslog_fd; + open($new_syslog_fd, ">>", "/etc/exports"); + print $new_syslog_fd "local2.* /var/log/nimol.log\n"; + close($new_syslog_fd); + system("service rsyslog restart"); + } else { + print "Don't need to update syslog configure file.\n"; + } +} + + + +sub create_imgconf_file { + my $nodes = shift; + my $subreq = shift; + my $nim_root = shift; + my $bootimg_root = shift; + my $relative_path = $bootimg_root; + $relative_path =~ s/^\/tftpboot//; + # Get nodes network information + my %nethash = (); + %nethash = xCAT::DBobjUtils->getNetwkInfo($nodes); + my $rootpw = undef; + my $passwdtab = xCAT::Table->new('passwd'); + if ($passwdtab) { + my $et = $passwdtab->getAttribs({key => 'system', username => 'root'}, 'password'); + if ($et and defined ($et->{'password'})) { + $rootpw = $et->{'password'}; + } + } + unless (defined($rootpw)) { + return "Unable to find requested password from passwd, with key=system,username=root"; + } + unless (-e $bootimg_root."/viobootimg") { + return "Unable to find VIOS bootimg file"; + } + chdir($bootimg_root); + foreach my $node (@$nodes) { + my $bootimg_conf_fd; + my $gateway = $nethash{$node}{gateway}; + my $mask = $nethash{$node}{mask}; + my $gateway_ip = xCAT::NetworkUtils->getipaddr($gateway); + my $master_node = xCAT::TableUtils->GetMasterNodeName($node); + my $master = xCAT::NetworkUtils->gethostname($master_node); + my $master_ip = xCAT::NetworkUtils->getipaddr($master); + my $node_ip = xCAT::NetworkUtils->getipaddr($node); + my $relative_bootfile = $relative_path."/viobootimg-$node"; + unless (-e "viobootimg-$node") { + symlink("viobootimg", "viobootimg-$node"); + } + if (-e $bootimg_root."/viobootimg-$node.info") { + unlink($bootimg_root."/viobootimg-$node.info"); + } + open ($bootimg_conf_fd, ">", $bootimg_root."/viobootimg-$node.info"); + print $bootimg_conf_fd "export NIM_SERVER_TYPE=linux\n"; + print $bootimg_conf_fd "export NIM_SYSLOG_PORT=514\n"; + print $bootimg_conf_fd "export NIM_SYSLOG_FACILITY=local2\n"; + print $bootimg_conf_fd "export NIM_NAME=viobootimg-$node\n"; + print $bootimg_conf_fd "export NIM_HOSTNAME=$node\n"; + print $bootimg_conf_fd "export NIM_CONFIGURATION=standalone\n"; + print $bootimg_conf_fd "export NIM_MASTER_HOSTNAME=$master\n"; + print $bootimg_conf_fd "export REMAIN_NIM_CLIENT=no\n"; + print $bootimg_conf_fd "export RC_CONFIG=rc.bos_inst\n"; + print $bootimg_conf_fd "export NIM_BOSINST_ENV=\"/../SPOT/usr/lpp/bos.sysmgt/nim/methods/c_bosinst_env\"\n"; + print $bootimg_conf_fd "export NIM_BOSINST_RECOVER=\"/../SPOT/usr/lpp/bos.sysmgt/nim/methods/c_bosinst_env -a hostname=$node\"\n"; + print $bootimg_conf_fd "export NIM_BOSINST_DATA=/NIM_BOSINST_DATA\n"; + print $bootimg_conf_fd "export SPOT=$master:$nim_root/spot/SPOT/usr\n"; + print $bootimg_conf_fd "export NIM_CUSTOM=\"/../SPOT/usr/lpp/bos.sysmgt/nim/methods/c_script -a location=$master:$nim_root/scripts/xcatvio.script\"\n"; + print $bootimg_conf_fd "export NIM_BOS_IMAGE=/NIM_BOS_IMAGE\n"; + print $bootimg_conf_fd "export NIM_BOS_FORMAT=mksysb\n"; + print $bootimg_conf_fd "export NIM_HOSTS=\" $node_ip:$node $master_ip:$master \"\n"; + print $bootimg_conf_fd "export NIM_MOUNTS=\" $master:$nim_root/bosinst_data/bosinst.data:/NIM_BOSINST_DATA:file $master:$nim_root/mksysb/mksysb:/NIM_BOS_IMAGE:file \"\n"; + print $bootimg_conf_fd "export ROUTES=\" default:0:$gateway_ip \"\n"; + print $bootimg_conf_fd "export NIM_IPADDR=$node_ip\n"; + print $bootimg_conf_fd "export NIM_NETMASK=$mask\n"; + print $bootimg_conf_fd "export PADMIN_PASSWD=$rootpw\n"; + print $bootimg_conf_fd "export SEA_ADAPTERS=bootnic\n"; + close($bootimg_conf_fd); + + $subreq->({command=>['makedhcp'], + node=>[$node], + arg=>['-s', 'supersede server.filename=\"'.$relative_bootfile.'\";']}, $global_callback); + } +} + +sub nodeset { + my $request = shift; + my $callback = shift; + my $subreq = shift; + + my $command = $request->{command}->[0]; + my $args = $request->{arg}; + my $nodes = $request->{node}; + + my $osimage = $request->{opt}->{osimage}; + my $nim_root; + my $bootimg_root; + unless ($osimage) { + $callback->({error=>["No param specified."], errorcode=>[1]}); + return; + } + { + my $installroot = "/install"; + my @entries = xCAT::TableUtils->get_site_attribute("installdir"); + my $t_entry = $entries[0]; + if (defined($t_entry)) { + $installroot = $t_entry; + } + + my $osimagetab = xCAT::Table->new('osimage'); + (my $ref) = $osimagetab->getAttribs({imagename=>$osimage}, 'osdistroname', 'provmethod'); + if ($ref) { + if ($ref->{provmethod} and $ref->{provmethod} eq 'nimol' and $ref->{osdistroname}) { + $nim_root = $installroot."/nim/".$ref->{osdistroname}; + $bootimg_root = "/tftpboot/".$ref->{osdistroname}."/nodes"; + } else { + $callback->({error=>["The 'provmethod' for OS image $osimage can only be 'nimol'."], errorcode=>[1]}); + return; + } + } else { + $callback->({error=>["No OS image $osimage found on the osimage table."], errorcode=>[1]}); + return; + } + } + + update_export(); + update_syslog(); + unless (-e $bootimg_root) { + mkpath($bootimg_root); + copy($nim_root."/bootimg/booti.chrp.mp.ent", $bootimg_root."/viobootimg"); + } + + unless (-e $nim_root."/scripts/xcatvio.script") { + mkpath($nim_root."/scripts/"); + copy($::XCATROOT."/share/xcat/scripts/xcatvio.script", $nim_root."/scripts/"); + } + + my $res = &create_imgconf_file($nodes, $subreq, $nim_root, $bootimg_root); + if ($res) { + $callback->({error=>["$res"], errorcode=>[1]}); + return; + } +} + + +1; diff --git a/xCAT-server/share/xcat/scripts/xcatvio.script b/xCAT-server/share/xcat/scripts/xcatvio.script new file mode 100755 index 000000000..61efa1390 --- /dev/null +++ b/xCAT-server/share/xcat/scripts/xcatvio.script @@ -0,0 +1,382 @@ +#!/usr/bin/env perl -w +# IBM(c) 2013 EPL license http://www.eclipse.org/legal/epl-v10.html +##################################################### +# +# xCAT script resource for VIOS installation +# +##################################################### + +use File::Path; +use Getopt::Long; + +# script file name +$::script = $0; +$::script =~ s/.*\///; + +##################################################### +# +# run the command +# +##################################################### + +sub runcmd +{ + my ($cmd) = @_; + my $rc=0; + $cmd .= ' 2>&1' ; + msg("Running command $cmd"); + $::outref = `$cmd`; + if ($?) + { + $rc = $? >> 8; + if ($rc > 0) + { + print "$::sdate $0: $::outref\n"; + print $::LOG_FILE "$::sdate $0: $::outref\n"; + } + } + return $rc; +} + +sub msg +{ + my $str = shift; + $sdate = `/bin/date`; + chomp $sdate; + print "$sdate $::script $str\n"; + print $::LOG_FILE "$sdate $::script $str\n"; +} + + +# since we don't have syslog set up yet we'll +# just save msgs in a local log file +$logdir = "/var/log/xcat"; + +if (!-d $logdir) { + mkpath($logdir); +} + +my $logfile = $logdir . "/xcat.log"; +# this log should not contain much so it might be ok to let it grow? +# at least we'll have the errors preserved +open(LOGFILE,">>",$logfile); +$::LOG_FILE = \*LOGFILE; +foreach my $env (keys %ENV) +{ + msg("ENV{$env} = $ENV{$env}"); +} + +my $cmd; +my $hostname; +my $ipaddr; +my $servnode; +# TODO: use the environment variable instead of reading /etc/niminfo +# get the name of my service node/NIM master from the /etc/niminfo file + +if (-f "/etc/niminfo") { + + $cmd = "/bin/cat /etc/niminfo | /bin/grep 'NIM_HOSTNAME'"; + &runcmd($cmd); + my $hostline = $::outref; + my $junk; + ($junk, $hostname) = split(/=/, $hostline); + $hostname =~ s/^\s*//; + chomp $hostname; + msg("Info: the hostname is $hostname"); + + $cmd = "host $hostname"; + &runcmd($cmd); + $ipaddr = $::outref; + $ipaddr =~ s/.*is\s+//; + chomp $ipaddr; + msg("Info: the ip address is $ipaddr"); + + $cmd = "/bin/cat /etc/niminfo | /bin/grep 'NIM_MASTER_HOSTNAME'"; + &runcmd($cmd); + my $SNline = $::outref; + ($junk, $servnode) = split(/=/, $SNline); + $servnode =~ s/^\s*//; + chomp $servnode; + + + my $xcatinfo="/etc/xcatinfo"; + open(XCATINFO,">",$xcatinfo); + print XCATINFO "XCATSERVER=$servnode\n"; + close(XCATINFO); +} else { + msg("Error: could not find /etc/niminfo file, exiting..."); + exit 1; +} +# Configure TCP/IP +# Get the boot nic +my $bootnic; +if (defined($ENV{'BOOTDEV'})) +{ + $bootnic = $ENV{'BOOTDEV'}; +} +if (!$bootnic) +{ + $cmd = "/usr/sbin/bootinfo -b"; + if (&runcmd($cmd) != 0) { + msg("Error: could not get the boot nic, exiting..."); + exit 1; + } + $bootnic = $::outref; + chomp $bootnic; +} + +msg("Info: bootnic is $bootnic"); +my $skiptcpip = 0; +if ($bootnic !~ /^en/) +{ + msg("Error: bootnic $bootnic is not a nic, skipping the TCP/IP configuration"); + $skiptcpip = 1; +} + +$cmd = "lsdev -C -l $bootnic"; +if (&runcmd($cmd) != 0) { + msg("Warning: could not get information for $bootnic, skipping the TCP/IP configuration"); + $skiptcpip = 1; +} +my @vir_nic = (); +$cmd = qq~lsdev -c adapter \| grep ent \| grep "Virtual I\/O Ethernet Adapter" \| awk -F ' ' '{print \$1}'~; +if (&runcmd($cmd) != 0) { + msg("Warning: could not find virtual I/O Ethernet Adapter"); + msg("Error: $::outref"); + $skiptcpip = 1; +} else { + if (!grep(/ent/, $::outref)) { + msg("Error($cmd): $::outref"); + $skiptcpip = 1; + } else { + @vir_nic = sort (split(/\n/, $::outref)); + msg("Find virtual NIC: @vir_nic"); + } +} + +my %sea_adapters = (); +if (defined($ENV{'SEA_ADAPTERS'}) and $ENV{'SEA_ADAPTERS'} =~ /bootnic/i) { + msg("Info: Environment variable SEA_ADAPTERS is $ENV{'SEA_ADAPTERS'}"); + if (scalar(@vir_nic) == 0) { + msg("Warning: No Virtual Ethernet Adapter found"); + $skiptcpip = 1; + } else { + my $xcatinfo="/etc/xcatinfo"; + open(XCATINFO,">>",$xcatinfo); + print XCATINFO "SEA_ADAPTERS=$bootnic:$vir_nic[0]:1:$ENV{'NIM_IPADDR'}:$ENV{'NIM_NETMASK'}:$hostname\n"; + close(XCATINFO); + + my $lsicmd = "/usr/sbin/lsitab bootnicsea > /dev/null 2>&1"; + if (&runcmd($lsicmd) != 0) { + my $mkicmd = '/usr/sbin/mkitab "bootnicsea:2:wait:/xcatpost/config_bootnicsea > /dev/console 2>&1"'; + if (&runcmd($mkicmd) != 0) { + msg("Warning: config_bootnicsea: Could not add config_bootnicsea to /etc/inittab.\n") + } + } + + } +} elsif (defined($ENV{'SEA_ADAPTERS'})) { + msg("Info: Environment variable SEA_ADAPTERS is $ENV{'SEA_ADAPTERS'}"); + my @sea_array = split(/\s+/, $ENV{'SEA_ADAPTERS'}); + foreach my $sea (@sea_array) + { + my ($phy, $virt, $vlan, $ip, $mask) = split(/:/, $sea); + if (!$phy || !$virt || !$vlan) + { + msg("Warning: incorrect SEA_ADAPTERS format, the syntax is physcial_adapter:virtual_adapter:vlan_id:ip_addr:netmask, where the ip_addr and netmask could be blank if you do not want to configure ip for this SEA adapter, skipping TCP/IP configuration"); + $skiptcpip = 1; + last; + } + $sea_adapters{$phy}{'phy'} = $phy; + $sea_adapters{$phy}{'virt'} = $virt; + $sea_adapters{$phy}{'vlan'} = $vlan; + $sea_adapters{$phy}{'ip'} = $ip; + $sea_adapters{$phy}{'mask'} = $mask; + } +} else { + msg("Info: The environment variable SEA_ADAPTERS is not defined"); +} + +if (!$skiptcpip) { + my $bootnicsea = 0; + my $netmask; + if (defined($ENV{'NIM_NETMASK'})) + { + $netmask = $ENV{'NIM_NETMASK'}; + } + if (!$netmask) + { + msg("Warning: NIM_NETMASK is not specified, using the default 255.255.255.0"); + $netmask = "255.255.255.0"; + } + + foreach my $phy (keys %sea_adapters) + { + my $phy = $sea_adapters{$phy}{'phy'}; + my $virt = $sea_adapters{$phy}{'virt'}; + my $vlan = $sea_adapters{$phy}{'vlan'}; + my $ip = $sea_adapters{$phy}{'ip'}; + my $mask = $sea_adapters{$phy}{'mask'}; + if ($phy eq $bootnic) + { + $bootnicsea = 1; + } + { + $cmd = "/usr/ios/cli/ioscli license -swma"; + &runcmd($cmd); + $cmd = "/usr/ios/cli/ioscli license -accept"; + &runcmd($cmd); + } + { # detach bootnic + if ($bootnicsea and $phy =~ /^ent(\d+)/) { + my $phynic_id = $1; + my $en_nic = "en".$phynic_id; + my $ent_nic = "ent".$phynic_id; + my $et_nic = "et".$phynic_id; + $cmd = "ifconfig $en_nic down; ifconfig $en_nic detach; rmdev -dl $en_nic; rmdev -dl $ent_nic; rmdev -dl $et_nic; cfgmgr;"; + if (&runcmd($cmd) != 0) { + msg("Error: could not detach bootnic:$bootnic"); + next; + } + } + + } + #$cmd = qq~su - padmin "-c ioscli license -accept; ioscli mkvdev -sea $phy -vadapter $virt -default $virt -defaultid $vlan"~; + $cmd = "/usr/ios/cli/ioscli mkvdev -sea $phy -vadapter $virt -default $virt -defaultid $vlan"; + if (&runcmd($cmd) != 0) { + msg("Error: could not create SEA with physical adapter $phy, virtual adapter $virt and vlan id $vlan"); + next; + } + my $sea_out = $::outref; + my $sea = undef; + my @out_array = split (/\n/, $sea_out); + foreach (@out_array) { + if (/(ent\d+)\s*Available/) { + $sea = $1; + $sea =~ s/t//; + } + } + unless ($sea) { + msg("Error: did not get available SEA adapter, $sea_out==="); + next; + } + msg("Info: The interface created with mkvdev is: $sea"); + #$cmd = qq~su - padmin "-c ioscli license -accept; ioscli mktcpip -hostname $hostname -inetaddr $ip -interface $sea -netmask $mask"~; + $cmd = "/usr/ios/cli/ioscli mktcpip -hostname $hostname -inetaddr $ip -interface $sea -netmask $mask"; + if (&runcmd($cmd) != 0) { + msg("Error: could not configure ip address for SEA $sea"); + } + } + + if (!$bootnicsea) + { + # ent1 -> en1 + if ($bootnic =~ /^ent/) + { + $bootnic =~ s/t//; + } + $cmd = "mktcpip -h \"$hostname\" -a $ipaddr -m $netmask -i $bootnic -A 'no' -t 'N/A' -s ''"; + if (&runcmd($cmd) != 0) { + msg("Error: could not configure IP for nic $bootnic, exiting ..."); + exit 1; + } + } +} + +# create the xcatpost dir +$cmd = "/bin/mkdir -m 755 -p /xcatpost"; +if (&runcmd($cmd) != 0) { + print "$::sdate xcataixscript: Could not make the /xcatpost directory.\n"; + print $::LOG_FILE "$::sdate xcataixscript: Could not make the /xcatpost directory.\n"; +} + +# Set a temporary root password +# - the user-provided root passwd will be set by xcataixpost +my $padmin_passwd; +if(defined($ENV{'PADMIN_PASSWD'})) +{ + $padmin_passwd = $ENV{'PADMIN_PASSWD'}; +} + +if(!$padmin_passwd) +{ + msg("Warning: padmin password is not specified, using the default password \"cluster\""); + $padmin_passwd = "cluster"; +} +my $pwcmd = qq~/bin/echo "padmin:$padmin_passwd" | /bin/chpasswd -c >/dev/null 2>&1~; +if (&runcmd($pwcmd) != 0) { + print "$::sdate xcatvio.script: Could not set password for padmin.\n"; + print $::LOG_FILE "$::sdate xcatvio.script: Could not set password for padmin.\n"; +} + +# The license accept does not work in postscript phase, +# should be done in postbootscript phase +# my $liccmd = qq~su - padmin "-c ioscli license -accept"~; +# if (&runcmd($liccmd) != 0) { +# msg("Error: failed to run license accept command"); +# } +# +# +# need fix to support INSTALLDIR !!!!! +# socket doesn't work at this point of install so need another +# way to get INSTALLDIR value!!! + +my $installdir; +if (!$installdir) { + $installdir="/install"; +} + +# get the contents of the $installdir/postscripts dir on the server +# - mount dir from server and copy files +# IPv6, should only use NFS version 4 mount + +my $mcmd; +my $snipcmd = "host $servnode"; +if (((&runcmd($snipcmd) == 0) && ($::outref =~ /:/)) || ($ENV{'USENFSV4ONAIX'} && ($ENV{'USENFSV4ONAIX'} =~ /1|Yes|yes|YES|Y|y/))) +{ + $mcmd = "mkdir -p /xcatmnt; mount -o nolock -o vers=4 $servnode:$installdir/postscripts /xcatmnt"; +} else { + $mcmd = "mkdir -p /xcatmnt; mount -o nolock $servnode:$installdir/postscripts /xcatmnt"; +} +if (&runcmd($mcmd) != 0) { + print "$::sdate xcataixscript: Could not mount $installdir/postscripts from $servnode.\n"; + print $::LOG_FILE "$::sdate xcataixscript: Could not mount $installdir/postscripts from $servnode.\n"; +} + +my $cpcmd; +if ((@ARGV==0) || ($ARGV[0] != 2)) { + $cpcmd = "/bin/cp -r /xcatmnt/* /xcatpost >/dev/null 2>&1"; +} else { +# when argv[1]=2, there is only one postscript file, +# user wants only download it to save time + $cpcmd= "/bin/cp /xcatmnt/$ARGV[1] /xcatpost >/dev/null 2>&1"; +} + +if (&runcmd($cpcmd) != 0) { + print "$::sdate xcataixscript: Could not copy postscripts to /xcatpost.\n"; + print $::LOG_FILE "$::sdate xcataixscript: Could not copy postscripts to /xcatpost.\n"; +} +# make sure all are executable + +my $chcmd = "/bin/chmod +x /xcatpost/*"; +if (&runcmd($chcmd) != 0) { + print "$::sdate xcataixscript: Could not change /xcatpost file permissions.\n"; + print $::LOG_FILE "$::sdate xcataixscript: Could not change /xcatpost file permissions.\n"; +} + +my $ucmd = "/usr/sbin/umount /xcatmnt; /bin/rmdir /xcatmnt"; +if (&runcmd($ucmd) != 0) { + print "$::sdate xcataixscript: Could not unmount $installdir.\n"; + print $::LOG_FILE "$::sdate xcataixscript: Could not unmount $installdir/postscripts.\n"; +} + +# Setup remote shell +if (-f "/xcatpost/_ssh/authorized_keys") +{ + runcmd("cat /xcatpost/_ssh/authorized_keys >> /home/padmin/.ssh/authorized_keys2"); +} +close($::LOG_FILE); + +exit 0; + + diff --git a/xCAT/postscripts/config_bootnicsea b/xCAT/postscripts/config_bootnicsea new file mode 100644 index 000000000..f38d2cb90 --- /dev/null +++ b/xCAT/postscripts/config_bootnicsea @@ -0,0 +1,144 @@ +#!/usr/bin/env perl -w + + +if ($^O =~ /^aix/i) { + unshift(@INC, qw(/usr/opt/perl5/lib/5.8.2/aix-thread-multi /usr/opt/perl5/lib/5.8.2 /usr/opt/perl5/lib/site_perl/5.8.2/aix-thread-multi /usr/opt/perl5/lib/site_perl/5.8.2)); +} + +use strict; +use File::Path; +use Getopt::Long; +# script file name +$::script = $0; +$::script =~ s/.*\///; +##################################################### +# +# run the command +# +##################################################### + +sub runcmd +{ + my ($cmd) = @_; + my $rc=0; + $cmd .= ' 2>&1' ; + msg("Running command $cmd"); + $::outref = `$cmd`; + if ($?) + { + $rc = $? >> 8; + if ($rc > 0) + { + print "$::sdate $0: $::outref\n"; + print $::LOG_FILE "$::sdate $0: $::outref\n"; + } + } + return $rc; +} + +sub msg +{ + my $str = shift; + $::sdate = `/bin/date`; + chomp $::sdate; + #print "$::sdate $::script $str\n"; + print $::LOG_FILE "$::sdate $::script $str\n"; +} + +my $cmd; + +my $logdir = "/var/log/xcat"; + +if (!-d $logdir) { + mkpath($logdir); +} + +my $logfile = $logdir . "/xcat.log"; +# this log should not contain much so it might be ok to let it grow? +# at least we'll have the errors preserved +open(LOGFILE,">>",$logfile); +$::LOG_FILE = \*LOGFILE; + +my $xcatinfo; +open($xcatinfo,"<","/etc/xcatinfo"); +my @sea_info = <$xcatinfo>; +close($xcatinfo); +my ($phy,$vir,$vlan,$ip,$mask,$host); +foreach my $sea_line (@sea_info) { + if ($sea_line =~ /SEA_ADAPTERS=(.*)$/) { + ($phy,$vir,$vlan,$ip,$mask,$host) = split (/:/,$1); + last; + } +} + +if (!$phy || !$vir || !$vlan) { + msg("Warning: incorrect SEA_ADAPTERS format, the syntax is physcial_adapter:virtual_adapter:vlan_id:ip_addr:netmask, where the ip_addr and netmask could be blank if you do not want to configure ip for this SEA adapter, skipping TCP/IP configuration"); + exit 1; +} else { + msg("Info: phy:$phy,vir:$vir,vlan:$vlan,ip:$ip-$mask, hostname:$host"); +} + +unless($mask) { + $mask = "255.255.255.0"; +} + +{ + #$cmd = "/usr/ios/cli/ioscli license -swma"; + #&runcmd($cmd); + $cmd = "/usr/ios/cli/ioscli license -accept"; + &runcmd($cmd); +} +{ # detach bootnic + if ($phy =~ /^ent(\d+)/) { + my $phynic_id = $1; + my $en_nic = "en".$phynic_id; + my $ent_nic = "ent".$phynic_id; + my $et_nic = "et".$phynic_id; + $cmd = "ifconfig $en_nic down; ifconfig $en_nic detach; rmdev -dl $en_nic; rmdev -dl $ent_nic; rmdev -dl $et_nic; cfgmgr;"; + if (&runcmd($cmd) != 0) { + msg("Error: could not detach nic:$phy"); + exit 1; + } + } +} +{ # create sea adapter and config it + #$cmd = qq~su - padmin "-c ioscli license -accept; ioscli mkvdev -sea $phy -vadapter $virt -default $virt -defaultid $vlan"~; + $cmd = "/usr/ios/cli/ioscli mkvdev -sea $phy -vadapter $vir -default $vir -defaultid $vlan"; + if (&runcmd($cmd) != 0) { + msg("Error: could not create SEA with physical adapter $phy, virtual adapter $vir and vlan id $vlan"); + exit 1; + } + my $sea_out = $::outref; + my $sea = undef; + my @out_array = split (/\n/, $sea_out); + foreach (@out_array) { + if (/(ent\d+)\s*Available/) { + $sea = $1; + $sea =~ s/t//; + } + } + unless ($sea) { + msg("Error: did not get available SEA adapter, $sea_out==="); + exit 1; + } + msg("Info: The interface created with mkvdev is: $sea"); + #$cmd = qq~su - padmin "-c ioscli license -accept; ioscli mktcpip -host $host -inetaddr $ip -interface $sea -netmask $mask"~; + $cmd = "/usr/ios/cli/ioscli mktcpip -hostname $host -inetaddr $ip -interface $sea -netmask $mask"; + if (&runcmd($cmd) != 0) { + msg("Error: could not configure ip address for SEA $sea"); + } +} + +close($::LOG_FILE); +{ + my $lsicmd = "/usr/sbin/lsitab bootnicsea > /dev/null 2>&1"; + if (&runcmd($lsicmd) == 0) { + #my $mkicmd = '/usr/sbin/mkitab "bootnicsea:2:wait:/xcatpost/config_bootnicsea > /dev/console 2>&1"'; + my $rmicmd = 'rmitab "bootnicsea" > /dev/null 2>&1'; + if (&runcmd($rmicmd) != 0) { + msg("Warning: config_bootnicsea: Could not remove config_bootnicsea from /etc/inittab.\n") + } + } +} + +exit 0;