diff --git a/xCAT-server/lib/xcat/plugins/zvm.pm b/xCAT-server/lib/xcat/plugins/zvm.pm index a5656aef2..9cbb3b3c3 100644 --- a/xCAT-server/lib/xcat/plugins/zvm.pm +++ b/xCAT-server/lib/xcat/plugins/zvm.pm @@ -36,13 +36,15 @@ use warnings; sub handled_commands { return { - rpower => "zvm", - rinv => "zvm", - mkvm => "zvm", - rmvm => "zvm", - lsvm => "zvm", - chvm => "zvm", - rscan => "zvm", + rpower => 'nodehm:mgt', + rinv => 'nodehm:mgt', + mkvm => 'nodehm:mgt', + rmvm => 'nodehm:mgt', + lsvm => 'nodehm:mgt', + chvm => 'nodehm:mgt', + rscan => 'nodehm:mgt', + nodeset => 'nodehm:mgt', + getmacs => 'nodehm:mgt', }; } @@ -308,7 +310,7 @@ sub process_request { } # End of foreach } # End of case - # Collects node information from one or more hardware control points. + # Collects node information from one or more hardware control points elsif ( $command eq "rscan" ) { foreach (@nodes) { $pid = fork(); @@ -334,6 +336,58 @@ sub process_request { } # End of foreach } # End of case + # Set the boot state for a noderange + elsif ( $command eq "nodeset" ) { + foreach (@nodes) { + $pid = fork(); + + # Parent process + if ($pid) { + push( @children, $pid ); + } + + # Child process + elsif ( $pid == 0 ) { + nodeSet( $callback, $_, $args ); + + # Exit process + exit(0); + } + else { + + # Ran out of resources + die "Error: Could not fork\n"; + } + + } # End of foreach + } # End of case + + # Collects node MAC address + elsif ( $command eq "getmacs" ) { + foreach (@nodes) { + $pid = fork(); + + # Parent process + if ($pid) { + push( @children, $pid ); + } + + # Child process + elsif ( $pid == 0 ) { + getMacs( $callback, $_, $args ); + + # Exit process + exit(0); + } + else { + + # Ran out of resources + die "Error: Could not fork\n"; + } + + } # End of foreach + } # End of case + # Wait for all processes to end foreach (@children) { waitpid( $_, 0 ); @@ -346,10 +400,10 @@ sub process_request { =head3 removeVM - Description : Removes server + Description : Remove a virtual server Arguments : Node Returns : Nothing - Example : removeVM($node); + Example : removeVM($callback, $node); =cut @@ -359,35 +413,39 @@ sub removeVM { # Get inputs my ( $callback, $node ) = @_; + # Get node properties from 'zvm' table + my @propNames = ( 'hcp', 'userid' ); + my $propVals = xCAT::zvmUtils->getNodeProps( 'zvm', $node, @propNames ); + # Get HCP - my $hcp = xCAT::zvmUtils->getTabProp( 'zvm', $node, 'hcp' ); + my $hcp = $propVals->{'hcp'}; if ( !$hcp ) { xCAT::zvmUtils->printLn( $callback, "Error: Missing node HCP" ); return; } # Get node userID - my $userId = xCAT::zvmUtils->getTabProp( 'zvm', $node, 'userid' ); + my $userId = $propVals->{'userid'}; if ( !$userId ) { xCAT::zvmUtils->printLn( $callback, "Error: Missing node ID" ); return; } # Power off userID - my $out = `ssh $hcp $::DIR/stopvs $userId`; + my $out = `ssh $hcp "$::DIR/stopvs $userId"`; xCAT::zvmUtils->printLn( $callback, "$out" ); - # Get device address for each MDISK - my @mdisks = xCAT::zvmUtils->getMdisks( $callback, $node ); + # Get device address of each MDISK + my @disks = xCAT::zvmUtils->getMdisks( $callback, $node ); my @parms; my $addr; - foreach (@mdisks) { + foreach (@disks) { @parms = split( ' ', $_ ); $addr = $parms[1]; # Remove MDISK # This cleans up the disks before it is put back in the pool - $out = `ssh $hcp $::DIR/removemdisk $userId $addr`; + $out = `ssh $hcp "$::DIR/removemdisk $userId $addr"`; xCAT::zvmUtils->printLn( $callback, "$out" ); } @@ -396,21 +454,17 @@ sub removeVM { sleep(5); # Delete user directory entry - $out = `ssh $hcp $::DIR/deletevs $userId`; + $out = `ssh $hcp "$::DIR/deletevs $userId"`; xCAT::zvmUtils->printLn( $callback, "$out" ); # Check for errors - my $rtn = xCAT::zvmUtils->isOutputGood( $callback, $out ); - if ( $rtn == -1 ) { + my $rc = xCAT::zvmUtils->isOutputGood( $callback, $out ); + if ( $rc == -1 ) { return; } - # Remove node from 'zvm', 'nodelist', 'nodehm', and 'hosts' table - xCAT::zvmUtils->delTabNode( 'zvm', $node ); - xCAT::zvmUtils->delTabNode( 'nodelist', $node ); - xCAT::zvmUtils->delTabNode( 'nodetype', $node ); - xCAT::zvmUtils->delTabNode( 'nodehm', $node ); - xCAT::zvmUtils->delTabNode( 'hosts', $node ); + # Remove node from tables + $out = `noderm $node`; return; } @@ -442,7 +496,7 @@ sub removeVM { setpassword [password] Returns : Nothing - Example : changeVM($node, $args); + Example : changeVM($callback, $node, $args); =cut @@ -452,46 +506,51 @@ sub changeVM { # Get inputs my ( $callback, $node, $args ) = @_; + # Get node properties from 'zvm' table + my @propNames = ( 'hcp', 'userid' ); + my $propVals = xCAT::zvmUtils->getNodeProps( 'zvm', $node, @propNames ); + # Get HCP - my $hcp = xCAT::zvmUtils->getTabProp( 'zvm', $node, 'hcp' ); + my $hcp = $propVals->{'hcp'}; if ( !$hcp ) { xCAT::zvmUtils->printLn( $callback, "Error: Missing node HCP" ); return; } # Get node userID - my $userId = xCAT::zvmUtils->getTabProp( 'zvm', $node, 'userid' ); + my $userId = $propVals->{'userid'}; if ( !$userId ) { xCAT::zvmUtils->printLn( $callback, "Error: Missing node ID" ); return; } + # Output string my $out; - # add3390 [disk pool] [device address] [mode] [cylinders] + # add3390 [disk pool] [device address] [cylinders] [mode] [read password] [write password] [multi password] if ( $args->[0] eq "--add3390" ) { my $pool = $args->[1]; my $addr = $args->[2]; - my $mode = $args->[3]; - my $cyl = $args->[4]; + my $cyl = $args->[3]; + my $mode = $args->[4]; my $readPw = $args->[5]; my $writePw = $args->[6]; my $multiPw = $args->[7]; - $out = `ssh $hcp $::DIR/add3390 $userId $pool $addr $mode $cyl $readPw $writePw $multiPw`; + $out = `ssh $hcp "$::DIR/add3390 $userId $pool $addr $mode $cyl $readPw $writePw $multiPw"`; } - # add9336 [disk pool] [virtual device address] [mode] [block size] [blocks] +# add9336 [disk pool] [virtual device address] [block size] [blocks] [mode] [read password] [write password] [multi password] elsif ( $args->[0] eq "--add9336" ) { my $pool = $args->[1]; my $addr = $args->[2]; - my $mode = $args->[3]; - my $blksize = $args->[4]; - my $blks = $args->[5]; + my $blksize = $args->[3]; + my $blks = $args->[4]; + my $mode = $args->[5]; my $readPw = $args->[6]; my $writePw = $args->[7]; my $multiPw = $args->[8]; - $out = `ssh $hcp $::DIR/add9336 $userId $pool $addr $mode $blksize $blks $readPw $writePw $multiPw`; + $out = `ssh $hcp "$::DIR/add9336 $userId $pool $addr $mode $blksize $blks $readPw $writePw $multiPw"`; } # addnic [address] [type] [device count] @@ -500,14 +559,14 @@ sub changeVM { my $type = $args->[2]; my $devcount = $args->[3]; - $out = `ssh $hcp $::DIR/addnic $userId $addr $type $devcount`; + $out = `ssh $hcp "$::DIR/addnic $userId $addr $type $devcount"`; } # addprocessor [address] elsif ( $args->[0] eq "--addprocessor" ) { my $addr = $args->[1]; - $out = `ssh $hcp $::DIR/addprocessor $userId $addr`; + $out = `ssh "$hcp $::DIR/addprocessor $userId $addr"`; } # addvdisk [device address] [size] @@ -515,7 +574,7 @@ sub changeVM { my $addr = $args->[1]; my $size = $args->[2]; - $out = `ssh $hcp $::DIR/addvdisk $userId $addr $size`; + $out = `ssh $hcp "$::DIR/addvdisk $userId $addr $size"`; } # connectnic2guestlan [address] [lan] [owner] @@ -524,7 +583,7 @@ sub changeVM { my $lan = $args->[2]; my $owner = $args->[3]; - $out = `ssh $hcp $::DIR/connectnic2guestlan $userId $addr $lan $owner`; + $out = `ssh $hcp "$::DIR/connectnic2guestlan $userId $addr $lan $owner"`; } # connectnic2vswitch [address] [vswitch] @@ -533,11 +592,11 @@ sub changeVM { my $vswitch = $args->[2]; # Connect to VSwitch - $out = `ssh $hcp $::DIR/connectnic2vswitch $userId $addr $vswitch`; + $out = `ssh $hcp "$::DIR/connectnic2vswitch $userId $addr $vswitch"`; # Grant access to VSWITCH for Linux user $out .= "Granting access to VSWITCH for $userId...\n "; - $out .= `ssh $hcp vmcp set vswitch $vswitch grant $userId`; + $out .= `ssh $hcp "vmcp set vswitch $vswitch grant $userId"`; } # dedicatedevice [virtual device] [real device] [mode] @@ -546,12 +605,12 @@ sub changeVM { my $raddr = $args->[2]; my $mode = $args->[3]; - $out = `ssh $hcp $::DIR/dedicatedevice $userId $vaddr $raddr $mode`; + $out = `ssh $hcp "$::DIR/dedicatedevice $userId $vaddr $raddr $mode"`; } # deleteipl elsif ( $args->[0] eq "--deleteipl" ) { - $out = `ssh $hcp $::DIR/deleteipl $userId`; + $out = `ssh $hcp "$::DIR/deleteipl $userId"`; } # formatdisk [address] [multi password] @@ -563,27 +622,27 @@ sub changeVM { my $multiPw = $args->[2]; # Check if there is an existing address (disk address) - $out = xCAT::zvmUtils->isAddressUsed( $hcp, $addr ); + my $rc = xCAT::zvmUtils->isAddressUsed( $hcp, $addr ); # If there is an existing address - while ( $out == 0 ) { + while ( $rc == 0 ) { # Generate a new address # Sleep 2 seconds to let existing disk appear sleep(2); $lnkAddr = $lnkAddr + 1; - $out = xCAT::zvmUtils->isAddressUsed( $hcp, $lnkAddr ); + $rc = xCAT::zvmUtils->isAddressUsed( $hcp, $lnkAddr ); } - # Load VMCP module - $out = xCAT::zvmCPUtils->loadVmcp($node); + # Load VMCP module on HCP + $out = xCAT::zvmCPUtils->loadVmcp($hcp); # Link target disk - $out = `ssh -o ConnectTimeout=5 $hcp vmcp link $userId $addr $lnkAddr MW $multiPw`; + $out = `ssh -o ConnectTimeout=5 $hcp "vmcp link $userId $addr $lnkAddr MW $multiPw"`; # Check for errors - my $rtn = xCAT::zvmUtils->isOutputGood( $callback, $out ); - if ( $rtn == -1 ) { + $rc = xCAT::zvmUtils->isOutputGood( $callback, $out ); + if ( $rc == -1 ) { xCAT::zvmUtils->printLn( $callback, "Linking disk... Failed" ); xCAT::zvmUtils->printLn( $callback, "$out" ); return; @@ -593,16 +652,16 @@ sub changeVM { $out = xCAT::zvmUtils->disableEnableDisk( $callback, $hcp, "-e", $lnkAddr ); # Determine device node - $out = `ssh $hcp cat /proc/dasd/devices | grep ".$lnkAddr("`; + $out = `ssh $hcp "cat /proc/dasd/devices" | grep ".$lnkAddr("`; my @parms = split( ' ', $out ); my $devNode = $parms[6]; - # Format target disk - $out = `ssh $hcp dasdfmt -b 4096 -y -f /dev/$devNode`; + # Format target disk (only ECKD supported) + $out = `ssh $hcp "dasdfmt -b 4096 -y -f /dev/$devNode"`; # Check for errors - $rtn = xCAT::zvmUtils->isOutputGood( $callback, $out ); - if ( $rtn == -1 ) { + $rc = xCAT::zvmUtils->isOutputGood( $callback, $out ); + if ( $rc == -1 ) { xCAT::zvmUtils->printLn( $callback, "Formating disk... Failed" ); xCAT::zvmUtils->printLn( $callback, "$out" ); @@ -610,11 +669,11 @@ sub changeVM { $out = xCAT::zvmUtils->disableEnableDisk( $callback, $hcp, "-d", $lnkAddr ); # Detatch disk - $out = `ssh -o ConnectTimeout=5 $hcp vmcp det $lnkAddr`; + $out = `ssh -o ConnectTimeout=5 $hcp "vmcp det $lnkAddr"`; # Check for errors - $rtn = xCAT::zvmUtils->isOutputGood( $callback, $out ); - if ( $rtn == -1 ) { + $rc = xCAT::zvmUtils->isOutputGood( $callback, $out ); + if ( $rc == -1 ) { xCAT::zvmUtils->printLn( $callback, "Detaching disk... Failed" ); xCAT::zvmUtils->printLn( $callback, "$out" ); return; @@ -630,11 +689,11 @@ sub changeVM { $out = xCAT::zvmUtils->disableEnableDisk( $callback, $hcp, "-d", $lnkAddr ); # Detatch disk - $out = `ssh -o ConnectTimeout=5 $hcp vmcp det $lnkAddr`; + $out = `ssh -o ConnectTimeout=5 $hcp "vmcp det $lnkAddr"`; # Check for errors - $rtn = xCAT::zvmUtils->isOutputGood( $callback, $out ); - if ( $rtn == -1 ) { + $rc = xCAT::zvmUtils->isOutputGood( $callback, $out ); + if ( $rc == -1 ) { xCAT::zvmUtils->printLn( $callback, "Detaching disk... Failed" ); xCAT::zvmUtils->printLn( $callback, "$out" ); return; @@ -652,40 +711,41 @@ sub changeVM { # disconnectnic [address] elsif ( $args->[0] eq "--disconnectnic" ) { my $addr = $args->[1]; - $out = `ssh $hcp $::DIR/disconnectnic $userId $addr`; + $out = `ssh $hcp "$::DIR/disconnectnic $userId $addr"`; } # removedisk [virtual device address] elsif ( $args->[0] eq "--removedisk" ) { my $addr = $args->[1]; - $out = `ssh $hcp $::DIR/removemdisk $userId $addr`; + $out = `ssh $hcp "$::DIR/removemdisk $userId $addr"`; } # removenic [address] elsif ( $args->[0] eq "--removenic" ) { my $addr = $args->[1]; - $out = `ssh $hcp $::DIR/removenic $userId $addr`; + $out = `ssh $hcp "$::DIR/removenic $userId $addr"`; } # removeprocessor [address] elsif ( $args->[0] eq "--removeprocessor" ) { my $addr = $args->[1]; - $out = `ssh $hcp $::DIR/removeprocessor $userId $addr`; + $out = `ssh $hcp "$::DIR/removeprocessor $userId $addr"`; } - # replacevs [file] - elsif ( $args->[0] eq "--replacevs" ) { + # replaceuserentry [file] + elsif ( $args->[0] eq "--replaceuserentry" ) { my $file = $args->[1]; - my $dest = "root@"; - $dest .= $hcp; + # Target system (HCP) -- root@gpok2.endicott.ibm.com + my $target = "root@"; + $target .= $hcp; if ($file) { # SCP file over to HCP - $out = `scp $file $dest:$file`; + $out = `scp $file $target:$file`; # Replace user directory entry - $out = `ssh $hcp $::DIR/replacevs $userId $file`; + $out = `ssh $hcp "$::DIR/replacevs $userId $file"`; } else { $out = "Error: No directory entry file specified"; @@ -699,16 +759,16 @@ sub changeVM { my $trgt = $args->[1]; my $loadparms = $args->[2]; my $parms = $args->[3]; - $out = `ssh $hcp $::DIR/setipl $userId $trgt $loadparms $parms`; + $out = `ssh $hcp "$::DIR/setipl $userId $trgt $loadparms $parms"`; } # setpassword [password] elsif ( $args->[0] eq "--setpassword" ) { my $pw = $args->[1]; - $out = `ssh $hcp $::DIR/setpassword $userId $pw`; + $out = `ssh $hcp "$::DIR/setpassword $userId $pw"`; } - # Print out error + # Otherwise, print out error else { $out = "Error: Option not supported"; } @@ -721,11 +781,11 @@ sub changeVM { =head3 powerVM - Description : Powers on/off a server + Description : Powers on/off a virtual server Arguments : Node Option [on|off|reset|stat] Returns : Nothing - Example : powerVM($node, $args); + Example : powerVM($callback, $node, $args); =cut @@ -735,45 +795,59 @@ sub powerVM { # Get inputs my ( $callback, $node, $args ) = @_; + # Get node properties from 'zvm' table + my @propNames = ( 'hcp', 'userid' ); + my $propVals = xCAT::zvmUtils->getNodeProps( 'zvm', $node, @propNames ); + # Get HCP - my $hcp = xCAT::zvmUtils->getTabProp( 'zvm', $node, 'hcp' ); + my $hcp = $propVals->{'hcp'}; if ( !$hcp ) { xCAT::zvmUtils->printLn( $callback, "Error: Missing node HCP" ); return; } # Get node userID - my $userId = xCAT::zvmUtils->getTabProp( 'zvm', $node, 'userid' ); + my $userId = $propVals->{'userid'}; if ( !$userId ) { xCAT::zvmUtils->printLn( $callback, "Error: Missing node ID" ); return; } my $out; - if ( $args->[0] eq 'on' ) { - $out = `ssh $hcp $::DIR/startvs $userId`; - xCAT::zvmUtils->printLn( $callback, "$out" ); - } - elsif ( $args->[0] eq 'off' ) { - $out = `ssh $hcp $::DIR/stopvs $userId`; + # Power on virtual server + if ( $args->[0] eq 'on' ) { + $out = `ssh $hcp "$::DIR/startvs $userId"`; xCAT::zvmUtils->printLn( $callback, "$out" ); } + + # Power off virtual server + elsif ( $args->[0] eq 'off' ) { + $out = `ssh $hcp "$::DIR/stopvs $userId"`; + xCAT::zvmUtils->printLn( $callback, "$out" ); + } + + # Get status (on|off) elsif ( $args->[0] eq 'stat' ) { # Output is different on SLES 11 $out = `vmcp q user $userId 2>/dev/null | sed 's/HCPCQU045E.*/off/' | sed 's/$userId.*/on/'`; xCAT::zvmUtils->printLn( $callback, "$node: $out" ); } + + # Reset virtual server elsif ( $args->[0] eq 'reset' ) { - $out = `ssh $hcp $::DIR/stopvs $userId`; + $out = `ssh $hcp "$::DIR/stopvs $userId"`; xCAT::zvmUtils->printLn( $callback, "$out" ); # Wait for output - while ( `vmcp q user $node 2>/dev/null | sed 's/HCPCQU045E.*/proceed/'` != "proceed" ) { + while ( `vmcp q user $userId 2>/dev/null | sed 's/HCPCQU045E.*/Done/'` != "Done" ) { + + # Do nothing } - $out = `ssh $hcp $::DIR/startvs $userId`; + + $out = `ssh $hcp "$::DIR/startvs $userId"`; xCAT::zvmUtils->printLn( $callback, "$out" ); } else { @@ -786,10 +860,10 @@ sub powerVM { =head3 scanVM - Description : Collects node information from one or more hardware control points. - Arguments : zHCP node + Description : Collects node information from one or more hardware control points + Arguments : HCP node Returns : Nothing - Example : scanVM($node); + Example : scanVM($callback, $node, $args); =cut @@ -799,15 +873,19 @@ sub scanVM { # Get inputs my ( $callback, $node ) = @_; - # Get HCP DNS host name - my $hcp = xCAT::zvmUtils->getTabProp( 'zvm', $node, 'hcp' ); + # Get node properties from 'zvm' table + my @propNames = ( 'hcp', 'userid' ); + my $propVals = xCAT::zvmUtils->getNodeProps( 'zvm', $node, @propNames ); + + # Get HCP + my $hcp = $propVals->{'hcp'}; if ( !$hcp ) { xCAT::zvmUtils->printLn( $callback, "Error: Missing node HCP" ); return; } # Get node userID - my $userId = xCAT::zvmUtils->getTabProp( 'zvm', $node, 'userid' ); + my $userId = $propVals->{'userid'}; if ( !$userId ) { xCAT::zvmUtils->printLn( $callback, "Error: Missing node ID" ); return; @@ -832,6 +910,7 @@ sub scanVM { # groups=all # mgt=zvm + # Output string my $str = ""; # Get nodes managed by this HCP @@ -845,22 +924,22 @@ sub scanVM { my $arch; my $groups; + # Search for nodes managed by specified HCP # Get 'node' and 'userid' properties my @results = $tab->getAllAttribsWhere( "hcp like '%" . $hcp . "%'", 'node', 'userid' ); foreach (@results) { $managedNode = $_->{'node'}; - $id = $_->{'userid'}; - $groups = xCAT::zvmUtils->getTabProp( 'nodelist', $managedNode, 'groups' ); - # Get userID if one is not in the table - if ( !$id ) { + # Get groups + @propNames = ('groups'); + $propVals = xCAT::zvmUtils->getNodeProps( 'nodelist', $managedNode, @propNames ); + $groups = $propVals->{'groups'}; - # Load VMCP module - $out = xCAT::zvmCPUtils->loadVmcp($managedNode); + # Load VMCP module + $out = xCAT::zvmCPUtils->loadVmcp($managedNode); - # Get userID - $id = xCAT::zvmCPUtils->getUserId($managedNode); - } + # Get userID + $id = xCAT::zvmCPUtils->getUserId($managedNode); # Get operating system $os = xCAT::zvmCPUtils->getOs($managedNode); @@ -887,10 +966,10 @@ sub scanVM { =head3 inventoryVM - Description : Get server hardware and software inventory - Arguments : Node and arguments + Description : Get virtual server hardware and software inventory + Arguments : Node and arguments (config|all) Returns : Nothing - Example : inventoryVM($node, $args); + Example : inventoryVM($callback, $node, $args); =cut @@ -900,19 +979,27 @@ sub inventoryVM { # Get inputs my ( $callback, $node, $args ) = @_; - # Output string - my $str = ""; + # Get node properties from 'zvm' table + my @propNames = ( 'hcp', 'userid' ); + my $propVals = xCAT::zvmUtils->getNodeProps( 'zvm', $node, @propNames ); # Get HCP - my $hcp = xCAT::zvmUtils->getTabProp( 'zvm', $node, 'hcp' ); + my $hcp = $propVals->{'hcp'}; + if ( !$hcp ) { + xCAT::zvmUtils->printLn( $callback, "Error: Missing node HCP" ); + return; + } # Get node userID - my $userId = xCAT::zvmUtils->getTabProp( 'zvm', $node, 'userid' ); + my $userId = $propVals->{'userid'}; if ( !$userId ) { xCAT::zvmUtils->printLn( $callback, "Error: Missing node ID" ); return; } + # Output string + my $str = ""; + # Load VMCP module my $out = xCAT::zvmCPUtils->loadVmcp($node); @@ -985,12 +1072,12 @@ sub inventoryVM { $str .= "NICs: \n$nic\n"; } else { - $str = "Error: Invalid argument"; + $str = "Error: Option not supported"; xCAT::zvmUtils->printLn( $callback, "$str" ); return; } - # Append hostname in front + # Append hostname (e.g. gpok3) in front $str = xCAT::zvmUtils->appendHostname( $node, $str ); xCAT::zvmUtils->printLn( $callback, "$str" ); @@ -1004,7 +1091,7 @@ sub inventoryVM { Description : Get user directory entry Arguments : Node Returns : Nothing - Example : listVM($node); + Example : listVM($callback, $node); =cut @@ -1014,22 +1101,26 @@ sub listVM { # Get inputs my ( $callback, $node ) = @_; + # Get node properties from 'zvm' table + my @propNames = ( 'hcp', 'userid' ); + my $propVals = xCAT::zvmUtils->getNodeProps( 'zvm', $node, @propNames ); + # Get HCP - my $hcp = xCAT::zvmUtils->getTabProp( 'zvm', $node, 'hcp' ); + my $hcp = $propVals->{'hcp'}; if ( !$hcp ) { xCAT::zvmUtils->printLn( $callback, "Error: Missing node HCP" ); return; } # Get node userID - my $userId = xCAT::zvmUtils->getTabProp( 'zvm', $node, 'userid' ); + my $userId = $propVals->{'userid'}; if ( !$userId ) { xCAT::zvmUtils->printLn( $callback, "Error: Missing node ID" ); return; } - # Get virtual server directory entry - my $out = `ssh $hcp $::DIR/getuserentry $userId`; + # Get user entry + my $out = `ssh $hcp "$::DIR/getuserentry $userId"`; xCAT::zvmUtils->printLn( $callback, "$out" ); return; @@ -1039,11 +1130,11 @@ sub listVM { =head3 makeVM - Description : Create a server + Description : Create a virtual server Arguments : Node - User directory entry as text file + User entry as text file Returns : Nothing - Example : makeVM($node, $args); + Example : makeVM($callback, $node, $args); =cut @@ -1058,16 +1149,19 @@ sub makeVM { # Get inputs my ( $callback, $node, $args ) = @_; + # Get node properties from 'zvm' table + my @propNames = ( 'hcp', 'userid' ); + my $propVals = xCAT::zvmUtils->getNodeProps( 'zvm', $node, @propNames ); + # Get HCP - # It was defined in mkdef command - my $hcp = xCAT::zvmUtils->getTabProp( 'zvm', $node, 'hcp' ); + my $hcp = $propVals->{'hcp'}; if ( !$hcp ) { - xCAT::zvmUtils->printLn( $callback, "Error: No HCP defined for this node" ); + xCAT::zvmUtils->printLn( $callback, "Error: Missing node HCP" ); return; } - # Get new node userID - my $userId = xCAT::zvmUtils->getTabProp( 'zvm', $node, 'userid' ); + # Get node userID + my $userId = $propVals->{'userid'}; if ( !$userId ) { xCAT::zvmUtils->printLn( $callback, "Error: Missing node ID" ); return; @@ -1077,23 +1171,22 @@ sub makeVM { my $file = $args->[0]; my $out; - # Create destination string, e.g. - # root@gpok123.endicott.ibm.com - my $dest = "root@"; - $dest .= $hcp; + # Target system (HCP) -- root@gpok123.endicott.ibm.com + my $target = "root@"; + $target .= $hcp; if ($file) { # SCP file over to HCP - $out = `scp $file $dest:$file`; + $out = `scp $file $target:$file`; # Create virtual server - $out = `ssh $hcp $::DIR/createvs $userId $file`; + $out = `ssh $hcp "$::DIR/createvs $userId $file"`; xCAT::zvmUtils->printLn( $callback, "$out" ); } else { # Create NOLOG virtual server - $out = `ssh $hcp $::DIR/createvs $userId`; + $out = `ssh $hcp "$::DIR/createvs $userId"`; xCAT::zvmUtils->printLn( $callback, "$out" ); } @@ -1105,10 +1198,10 @@ sub makeVM { =head3 cloneVM - Description : Clone a server + Description : Clone a virtual server Arguments : Node and configuration Returns : Nothing - Example : cloneVM($node, $args); + Example : cloneVM($callback, $targetNode, $args); =cut @@ -1124,19 +1217,23 @@ sub cloneVM { my ( $callback, $targetNode, $args ) = @_; # Return code for each command - my $rtn; + my $rc; xCAT::zvmUtils->printLn( $callback, "$targetNode: Cloning" ); + # Get node properties from 'zvm' table + my @propNames = ( 'hcp', 'userid' ); + my $propVals = xCAT::zvmUtils->getNodeProps( 'zvm', $targetNode, @propNames ); + # Get HCP - my $hcp = xCAT::zvmUtils->getTabProp( 'zvm', $targetNode, 'hcp' ); + my $hcp = $propVals->{'hcp'}; if ( !$hcp ) { - xCAT::zvmUtils->printLn( $callback, "Error: No HCP defined for this node" ); + xCAT::zvmUtils->printLn( $callback, "Error: Missing node HCP" ); return; } - # Get target node userID - my $targetUserId = xCAT::zvmUtils->getTabProp( 'zvm', $targetNode, 'userid' ); + # Get node userID + my $targetUserId = $propVals->{'userid'}; if ( !$targetUserId ) { xCAT::zvmUtils->printLn( $callback, "Error: Missing node ID" ); return; @@ -1145,37 +1242,49 @@ sub cloneVM { # Get source node my $sourceNode = $args->[0]; if ( !$sourceNode ) { - xCAT::zvmUtils->printLn( $callback, "Error: Missing master node" ); + xCAT::zvmUtils->printLn( $callback, "Error: Missing source node" ); return; } - # Get source node userID - my $sourceId = xCAT::zvmUtils->getTabProp( 'zvm', $sourceNode, 'userid' ); - if ( !$sourceId ) { - xCAT::zvmUtils->printLn( $callback, "Error: Missing master node ID" ); - return; - } + # Get source node properties from 'zvm' table + @propNames = ( 'hcp', 'userid' ); + $propVals = xCAT::zvmUtils->getNodeProps( 'zvm', $sourceNode, @propNames ); - # Get source node HCP - my $sourceHcp = xCAT::zvmUtils->getTabProp( 'zvm', $sourceNode, 'hcp' ); + # Get HCP + my $sourceHcp = $propVals->{'hcp'}; if ( !$sourceHcp ) { - xCAT::zvmUtils->printLn( $callback, "Error: Missing master node ID" ); + xCAT::zvmUtils->printLn( $callback, "Error: Missing source node HCP" ); + return; + } + + # Get node userID + my $sourceId = $propVals->{'userid'}; + if ( !$sourceId ) { + xCAT::zvmUtils->printLn( $callback, "Error: Missing source node ID" ); return; } # Exit if source node HCP is not the same as target node HCP - elsif ( !( $sourceHcp eq $hcp ) ) { + if ( !( $sourceHcp eq $hcp ) ) { xCAT::zvmUtils->printLn( $callback, "Error: Source node HCP ($sourceHcp) is not the same as target node HCP ($hcp)" ); return; } - # Get other inputs (4 in total) - # Disk pool, read, write, and multi passwords + # Get target IP from /etc/hosts + my $out = `cat /etc/hosts | grep $targetNode`; + my @parms = split( ' ', $out ); + my $targetIp = $parms[0]; + if ( !$targetIp ) { + xCAT::zvmUtils->printLn( $callback, "Error: Missing IP for $targetNode in /etc/hosts" ); + return; + } + + # Get other inputs (2 in total) + # Disk pool and multi password my $i; - my @parms; my %inputs; - foreach $i ( 1 .. 4 ) { + foreach $i ( 1 .. 2 ) { if ( $args->[$i] ) { # Split parameters by '=' @@ -1204,27 +1313,27 @@ sub cloneVM { my @srcDisks = xCAT::zvmUtils->getMdisks( $callback, $sourceNode ); # Get directory entry of source node - # Save user directory entry as /tmp/dirEntry.txt + # Save user directory entry as /tmp/userEntry.txt my $dirFile = "/tmp/dirEntry.txt"; - my $out = xCAT::zvmUtils->saveDirEntryNoDisk( $callback, $sourceNode, $dirFile ); + $out = xCAT::zvmUtils->saveDirEntryNoDisk( $callback, $sourceNode, $dirFile ); # SCP directory entry file over to HCP $out = xCAT::zvmUtils->sendFile( $hcp, $dirFile ); # Create new virtual server xCAT::zvmUtils->printLn( $callback, "$targetNode: Creating user directory entry" ); - $out = `ssh $hcp $::DIR/createvs $targetUserId $dirFile`; + $out = `ssh $hcp "$::DIR/createvs $targetUserId $dirFile"`; # Check for errors - $rtn = xCAT::zvmUtils->isOutputGood( $callback, $out ); - if ( $rtn == -1 ) { + $rc = xCAT::zvmUtils->isOutputGood( $callback, $out ); + if ( $rc == -1 ) { # Exit on bad output xCAT::zvmUtils->printLn( $callback, "$out" ); return; } - # Load VMCP module + # Load VMCP module on HCP and source node $out = xCAT::zvmCPUtils->loadVmcp($hcp); $out = xCAT::zvmCPUtils->loadVmcp($sourceNode); @@ -1238,8 +1347,8 @@ sub cloneVM { $out = xCAT::zvmCPUtils->grantVSwitch( $callback, $hcp, $targetUserId, $_ ); # Check for errors - $rtn = xCAT::zvmUtils->isOutputGood( $callback, $out ); - if ( $rtn == -1 ) { + $rc = xCAT::zvmUtils->isOutputGood( $callback, $out ); + if ( $rc == -1 ) { # Exit on bad output xCAT::zvmUtils->printLn( $callback, "$out" ); @@ -1268,17 +1377,17 @@ sub cloneVM { if ( $type eq '3390' ) { # Get disk size (cylinders) - $out = `ssh -o ConnectTimeout=5 $sourceNode vmcp q v dasd | grep "DASD $addr"`; + $out = `ssh -o ConnectTimeout=5 $sourceNode "vmcp q v dasd" | grep "DASD $addr"`; @parms = split( ' ', $out ); - $cyl = xCAT::zvmUtils->trim( $parms[5] ); + $cyl = xCAT::zvmUtils->trimStr( $parms[5] ); # Add disk xCAT::zvmUtils->printLn( $callback, "$targetNode: Adding minidisk" ); - $out = `ssh $hcp $::DIR/add3390 $targetUserId $pool $addr $mode $cyl $trgtPw $trgtPw $trgtPw`; + $out = `ssh $hcp "$::DIR/add3390 $targetUserId $pool $addr $mode $cyl $trgtPw $trgtPw $trgtPw"`; # Check for errors - $rtn = xCAT::zvmUtils->isOutputGood( $callback, $out ); - if ( $rtn == -1 ) { + $rc = xCAT::zvmUtils->isOutputGood( $callback, $out ); + if ( $rc == -1 ) { xCAT::zvmUtils->printLn( $callback, "$out" ); # Exit on bad output @@ -1289,15 +1398,14 @@ sub cloneVM { # Add FBA disk elsif ( $type eq '9336' ) { + # -- To be supported -- # Get disk size (blocks) + # Add disk } } - # Load VMCP module on HCP - $out = xCAT::zvmCPUtils->loadVmcp($hcp); - - # Link , format, and copy source disks + # Link, format, and copy source disks my $srcAddr; my $targetAddr; my $sourceDevNode; @@ -1307,47 +1415,47 @@ sub cloneVM { $targetAddr = $_ + 2000; # Check if there is an existing address (source address) - $out = xCAT::zvmUtils->isAddressUsed( $hcp, $srcAddr ); + $rc = xCAT::zvmUtils->isAddressUsed( $hcp, $srcAddr ); - # If there is an existing address - while ( $out == 0 ) { + # If there is an existing address (source address) + while ( $rc == 0 ) { # Generate a new address # Sleep 2 seconds to let existing disk appear sleep(2); $srcAddr = $srcAddr + 1; - $out = xCAT::zvmUtils->isAddressUsed( $hcp, $srcAddr ); + $rc = xCAT::zvmUtils->isAddressUsed( $hcp, $srcAddr ); } # Check if there is an existing address (target address) - $out = xCAT::zvmUtils->isAddressUsed( $hcp, $targetAddr ); + $rc = xCAT::zvmUtils->isAddressUsed( $hcp, $targetAddr ); # If there is an existing address - while ( $out == 0 ) { + while ( $rc == 0 ) { # Generate a new address # Sleep 2 seconds to let existing disk appear sleep(2); $targetAddr = $targetAddr + 1; - $out = xCAT::zvmUtils->isAddressUsed( $hcp, $targetAddr ); + $rc = xCAT::zvmUtils->isAddressUsed( $hcp, $targetAddr ); } - # Link source disk - $out = `ssh -o ConnectTimeout=5 $hcp vmcp link $sourceId $_ $srcAddr MW $srcMultiPw`; + # Link source disk to HCP + $out = `ssh -o ConnectTimeout=5 $hcp "vmcp link $sourceId $_ $srcAddr MW $srcMultiPw"`; # Check for errors - $rtn = xCAT::zvmUtils->isOutputGood( $callback, $out ); - if ( $rtn == -1 ) { + $rc = xCAT::zvmUtils->isOutputGood( $callback, $out ); + if ( $rc == -1 ) { xCAT::zvmUtils->printLn( $callback, "$out" ); return; } - # Link target disk - $out = `ssh -o ConnectTimeout=5 $hcp vmcp link $targetUserId $_ $targetAddr MW $trgtPw`; + # Link target disk to HCP + $out = `ssh -o ConnectTimeout=5 $hcp "vmcp link $targetUserId $_ $targetAddr MW $trgtPw"`; # Check for errors - $rtn = xCAT::zvmUtils->isOutputGood( $callback, $out ); - if ( $rtn == -1 ) { + $rc = xCAT::zvmUtils->isOutputGood( $callback, $out ); + if ( $rc == -1 ) { xCAT::zvmUtils->printLn( $callback, "$out" ); return; } @@ -1357,8 +1465,8 @@ sub cloneVM { $out = xCAT::zvmCPUtils->flashCopy( $hcp, $srcAddr, $targetAddr ); # Check for errors - $rtn = xCAT::zvmUtils->isOutputGood( $callback, $out ); - if ( $rtn == -1 ) { + $rc = xCAT::zvmUtils->isOutputGood( $callback, $out ); + if ( $rc == -1 ) { # FLASHCOPY is not supported xCAT::zvmUtils->printLn( $callback, "$targetNode: FLASHCOPY not supported. Using Linux DD" ); @@ -1370,22 +1478,22 @@ sub cloneVM { $out = xCAT::zvmUtils->disableEnableDisk( $callback, $hcp, "-e", $targetAddr ); # Determine source device node - $out = `ssh $hcp cat /proc/dasd/devices | grep ".$srcAddr("`; + $out = `ssh $hcp "cat /proc/dasd/devices" | grep ".$srcAddr("`; @parms = split( ' ', $out ); $sourceDevNode = $parms[6]; # Determine target device node - $out = `ssh $hcp cat /proc/dasd/devices | grep ".$targetAddr("`; + $out = `ssh $hcp "cat /proc/dasd/devices" | grep ".$targetAddr("`; @parms = split( ' ', $out ); $targetDevNode = $parms[6]; # Format target disk xCAT::zvmUtils->printLn( $callback, "$targetNode: Formating disk" ); - $out = `ssh $hcp dasdfmt -b 4096 -y -f /dev/$targetDevNode`; + $out = `ssh $hcp "dasdfmt -b 4096 -y -f /dev/$targetDevNode"`; # Check for errors - $rtn = xCAT::zvmUtils->isOutputGood( $callback, $out ); - if ( $rtn == -1 ) { + $rc = xCAT::zvmUtils->isOutputGood( $callback, $out ); + if ( $rc == -1 ) { # Exit on bad output xCAT::zvmUtils->printLn( $callback, "$out" ); @@ -1397,11 +1505,11 @@ sub cloneVM { # Copy source disk to target disk xCAT::zvmUtils->printLn( $callback, "$targetNode: Copying source disk" ); - $out = `ssh $hcp dd if=/dev/$sourceDevNode of=/dev/$targetDevNode bs=4096`; + $out = `ssh $hcp "dd if=/dev/$sourceDevNode of=/dev/$targetDevNode bs=4096"`; # Check for error - $rtn = xCAT::zvmUtils->isOutputGood( $callback, $out ); - if ( $rtn == -1 ) { + $rc = xCAT::zvmUtils->isOutputGood( $callback, $out ); + if ( $rc == -1 ) { xCAT::zvmUtils->printLn( $callback, "$out" ); return; } @@ -1415,7 +1523,7 @@ sub cloneVM { $out = xCAT::zvmUtils->disableEnableDisk( $callback, $hcp, "-e", $targetAddr ); # Determine target device node (it might have changed) - $out = `ssh $hcp cat /proc/dasd/devices | grep ".$targetAddr("`; + $out = `ssh $hcp "cat /proc/dasd/devices" | grep ".$targetAddr("`; @parms = split( ' ', $out ); $targetDevNode = $parms[6]; @@ -1429,15 +1537,27 @@ sub cloneVM { # Mount target disk my $cloneMntPt = "/mnt/$targetUserId"; $targetDevNode .= "1"; - $out = `ssh $hcp mkdir $cloneMntPt`; - $out = `ssh $hcp mount /dev/$targetDevNode $cloneMntPt`; + $out = `ssh $hcp "mkdir $cloneMntPt"`; + $out = `ssh $hcp "mount /dev/$targetDevNode $cloneMntPt"`; # Set hostname $out = `ssh $hcp sed --in-place -e "s/$sourceNode/$targetNode/g" $cloneMntPt/etc/HOSTNAME`; + # If Red Hat -- Set hostname in /etc/sysconfig/network + $out = xCAT::zvmCPUtils->getOs($sourceNode); + if ( $out =~ m/Red Hat/i ) { + $out = `ssh $hcp sed --in-place -e "s/$sourceNode/$targetNode/g" $cloneMntPt/etc/sysconfig/network`; + } + + # Set /etc/resolve.conf (If necessary) + # Set IP address - my $sourceIp = xCAT::zvmUtils->getIp($sourceNode); - my $targetIp = xCAT::zvmUtils->getTabProp( "hosts", $targetNode, "ip" ); + my $sourceIp = xCAT::zvmUtils->getIp($sourceNode); + + # Set MAC address for Layer 2 (If necessary) + + # Get network configuration file + # Location of this file depends on the OS my $ifcfg = xCAT::zvmUtils->getIfcfg($sourceNode); my $ifcfgPath = $cloneMntPt; $ifcfgPath .= $ifcfg; @@ -1446,28 +1566,28 @@ sub cloneVM { $out = `ssh $hcp sed --in-place -e "s/$sourceIp/$targetIp/g" \ -e "s/$sourceNode/$targetNode/g" $ifcfgPath`; # Flush disk - $out = `ssh $hcp sync`; + $out = `ssh $hcp "sync"`; # Unmount disk - $out = `ssh $hcp umount $cloneMntPt`; + $out = `ssh $hcp "umount $cloneMntPt"`; } # Disable disks $out = xCAT::zvmUtils->disableEnableDisk( $callback, $hcp, "-d", $srcAddr ); $out = xCAT::zvmUtils->disableEnableDisk( $callback, $hcp, "-d", $targetAddr ); - # Detatch disks - $out = `ssh $hcp vmcp det $srcAddr`; - $out = `ssh $hcp vmcp det $targetAddr`; + # Detatch disks from HCP + $out = `ssh $hcp "vmcp det $srcAddr"`; + $out = `ssh $hcp "vmcp det $targetAddr"`; } # Power on target virtual server xCAT::zvmUtils->printLn( $callback, "$targetNode: Powering on" ); - $out = `ssh $hcp $::DIR/startvs $targetUserId`; + $out = `ssh $hcp "$::DIR/startvs $targetUserId"`; # Check for error - $rtn = xCAT::zvmUtils->isOutputGood( $callback, $out ); - if ( $rtn == -1 ) { + $rc = xCAT::zvmUtils->isOutputGood( $callback, $out ); + if ( $rc == -1 ) { # Exit on bad output xCAT::zvmUtils->printLn( $callback, "$out" ); @@ -1478,3 +1598,448 @@ sub cloneVM { return; } + +#------------------------------------------------------- + +=head3 nodeSet + + Description : Set the boot state for a noderange + (Perform installation of zLinux) + Arguments : Node + Returns : Nothing + Example : nodeSet($callback, $node, $args); + +=cut + +#------------------------------------------------------- +sub nodeSet { + + # Get inputs + my ( $callback, $node, $args ) = @_; + + # Get action + my $action = $args->[0]; + if ( !( $action eq "install" ) ) { + xCAT::zvmUtils->printLn( $callback, "Error: Option not supported" ); + return; + } + + # Get node properties from 'zvm' table + my @propNames = ( 'hcp', 'userid' ); + my $propVals = xCAT::zvmUtils->getNodeProps( 'zvm', $node, @propNames ); + + # Get HCP + my $hcp = $propVals->{'hcp'}; + if ( !$hcp ) { + xCAT::zvmUtils->printLn( $callback, "Error: Missing node HCP" ); + return; + } + + # Get node userID + my $userId = $propVals->{'userid'}; + if ( !$userId ) { + xCAT::zvmUtils->printLn( $callback, "Error: Missing node ID" ); + return; + } + + # Get Linux distribution + @propNames = ( 'os', 'profile' ); + $propVals = xCAT::zvmUtils->getNodeProps( 'nodetype', $node, @propNames ); + my $distr = $propVals->{'os'}; + if ( !$distr ) { + xCAT::zvmUtils->printLn( $callback, "Error: Missing operating system to be deployed on this node" ); + return; + } + + # Get profile + my $profile = $propVals->{'profile'}; + if ( !$distr ) { + xCAT::zvmUtils->printLn( $callback, "Error: Missing profile for this node" ); + return; + } + + # Get network adapter + @propNames = ( 'primarynic', 'tftpserver' ); + $propVals = xCAT::zvmUtils->getNodeProps( 'noderes', $node, @propNames ); + my $interface = $propVals->{'primarynic'}; + if ( !$interface ) { + xCAT::zvmUtils->printLn( $callback, "Error: Missing network adapter of this node" ); + return; + } + + # Get host IP and hostname from /etc/hosts + my $out = `cat /etc/hosts | grep $node`; + my @parms = split( ' ', $out ); + my $hostIP = $parms[0]; + my $hostname = $parms[1]; + if ( !$hostIP || !$hostname ) { + xCAT::zvmUtils->printLn( $callback, "Error: Missing IP for $node in /etc/hosts" ); + return; + } + + # Get NIC address from user entry + $out = `ssh $hcp "$::DIR/getuserentry $userId" | grep "NICDEF"`; + my @lines = split( '\n', $out ); + if ( !$lines[0] ) { + xCAT::zvmUtils->printLn( $callback, "Error: Missing NICDEF statement in user entry of node" ); + return; + } + + # Grab the first NICDEF address + @parms = split( ' ', $lines[0] ); + my $readChannel = "0.0.0" . ( $parms[1] + 0 ); + my $writeChannel = "0.0.0" . ( $parms[1] + 1 ); + my $dataChannel = "0.0.0" . ( $parms[1] + 2 ); + + # Get domain from site table + my $siteTab = xCAT::Table->new('site'); + my $domainHash = $siteTab->getAttribs( { key => "domain" }, 'value' ); + my $domain = $domainHash->{'value'}; + + # Get network properties for network adapter + @propNames = ( 'net', 'mask', 'gateway', 'tftpserver', 'nameservers' ); + $propVals = xCAT::zvmUtils->getTabPropsByKey( 'networks', 'mgtifname', $interface, @propNames ); + my $network = $propVals->{'net'}; + my $mask = $propVals->{'mask'}; + my $gateway = $propVals->{'gateway'}; + my $ftp = $propVals->{'tftpserver'}; + my $nameserver = $propVals->{'nameservers'}; + if ( !$network || !$mask || !$ftp || !$nameserver ) { + + # It is acceptable to not have a gateway + xCAT::zvmUtils->printLn( $callback, "Error: Missing network information for $interface" ); + return; + } + + # Get broadcast address of NIC + my $ifcfg = xCAT::zvmUtils->getIfcfgByNic( $hcp, $readChannel ); + $out = `cat $ifcfg | grep "BROADCAST"`; + @parms = split( '=', $out ); + my $broadcast = $parms[1]; + $broadcast = xCAT::zvmUtils->trimStr($broadcast); + $broadcast = xCAT::zvmUtils->replaceStr( $broadcast, "'", "" ); + + # Load VMCP module on HCP + $out = xCAT::zvmCPUtils->loadVmcp($hcp); + + # Sample paramter file exists in installation CD + # Use that as a guide + my $sampleParm; + my $parmHeader; + my $parms; + my $parmFile; + + # If punch is successful -- Look for this string + my $searchStr = "created and transferred"; + + # Default parameters -- SLES + my $instNetDev = "osa"; # Only OSA interface type is supported + my $osaInterface = "qdio"; # OSA interface = qdio or lcs + my $osaMedium = "eth"; # OSA medium = eth (ethernet) or tr (token ring) + + # Default parameters -- RHEL + my $netType = "qeth"; + my $portName = "FOOBAR"; + my $portNo = "0"; + my $layer = "0"; + + # SUSE installation + my $template; + if ( $distr =~ m/sles/i ) { + + # Create directory in FTP root (/install) to hold template + $out = `mkdir -p /install/custom/install/sles`; + + # Copy autoyast template + $template = "/install/custom/install/sles/$profile"; + $out = `cp /opt/xcat/share/xcat/install/sles/$profile $template`; + + # Edit template + my $device = "qeth-bus-ccw-$readChannel"; + my $chanIds = "$readChannel $writeChannel $dataChannel"; + $out = +`sed --in-place -e "s,replace_host_address,$hostIP,g" \ -e "s,replace_long_name,$hostname,g" \ -e "s,replace_short_name,$node,g" \ -e "s,replace_domain,$domain,g" \ -e "s,replace_hostname,$node,g" \ -e "s,replace_nameserver,$node,g" \ -e "s,replace_broadcast,$broadcast,g" \ -e "s,replace_device,$device,g" \ -e "s,replace_ipaddr,$hostIP,g" \ -e "s,replace_netmask,$mask,g" \ -e "s,replace_network,$network,g" \ -e "s,replace_ccw_chan_ids,$chanIds,g" \ -e "s,replace_ccw_chan_mode,FOOBAR,g" \ -e "s,replace_gateway,$gateway,g" \ -e "s,replace_root_password,rootpw,g" $template`; + + # Read sample parmfile in /install/sles10.2/s390x/1/boot/s390x/ + $sampleParm = "/install/$distr/s390x/1/boot/s390x/parmfile"; + open( SAMPLEPARM, "<$sampleParm" ); + + # Search parmfile for -- ramdisk_size=65536 root=/dev/ram1 ro init=/linuxrc TERM=dumb + while () { + + # If the line contains 'ramdisk_size' + if ( $_ =~ m/ramdisk_size/i ) { + $parmHeader = xCAT::zvmUtils->trimStr($_); + } + } + + # Close sample parmfile + close(SAMPLEPARM); + + # Create parmfile + # Limited to 10 lines + # End result should be -- + # ramdisk_size=65536 root=/dev/ram1 ro init=/linuxrc TERM=dumb + # HostIP=10.0.0.5 Hostname=gpok5.endicott.ibm.com + # Gateway=10.0.0.1 Netmask=255.255.255.0 + # Broadcast=10.0.0.0 Layer2=0 + # ReadChannel=0.0.0800 WriteChannel=0.0.0801 DataChannel=0.0.0802 + # Nameserver=9.0.2.11 Portname=OSAPORT + # Install=ftp://10.0.0.1/sles10.2/s390x/1/ + # UseVNC=1 VNCPassword=123456 + # InstNetDev=osa OsaInterface=qdio OsaMedium=eth Manual=0 + my $ay = "ftp://$ftp/custom/install/sles/$profile"; + + $parms = $parmHeader . "\n"; + $parms = $parms . "AutoYaST=$ay\n"; + $parms = $parms . "HostIP=$hostIP Hostname=$hostname\n"; + $parms = $parms . "Gateway=$gateway Netmask=$mask\n"; + $parms = $parms . "Broadcast=$network Layer2=$layer\n"; + $parms = $parms . "ReadChannel=$readChannel WriteChannel=$writeChannel DataChannel=$dataChannel\n"; + $parms = $parms . "Nameserver=$nameserver Portname=$portName\n"; + $parms = $parms . "Install=ftp://$ftp/$distr/s390x/1/\n"; + $parms = $parms . "UseVNC=1 VNCPassword=123456\n"; + $parms = $parms . "InstNetDev=$instNetDev OsaInterface=$osaInterface OsaMedium=$osaMedium Manual=0\n"; + + # Write to parmfile + $parmFile = "/tmp/parm"; + open( PARMFILE, ">$parmFile" ); + print PARMFILE "$parms"; + close(PARMFILE); + + # Send kernel, parmfile, and initrd to reader to HCP + $out = `cp /install/$distr/s390x/1/boot/s390x/vmrdr.ikr /tmp/kernel`; + $out = `cp /install/$distr/s390x/1/boot/s390x/initrd /tmp/initrd`; + $out = xCAT::zvmUtils->sendFile( $hcp, "/tmp/kernel" ); + $out = xCAT::zvmUtils->sendFile( $hcp, "/tmp/parm" ); + $out = xCAT::zvmUtils->sendFile( $hcp, "/tmp/initrd" ); + + # Set the virtual unit record devices online on HCP + $out = xCAT::zvmUtils->disableEnableDisk( $callback, $hcp, "-e", "c" ); + $out = xCAT::zvmUtils->disableEnableDisk( $callback, $hcp, "-e", "d" ); + + # Purge reader + $out = xCAT::zvmCPUtils->purgeReader( $hcp, $userId ); + xCAT::zvmUtils->printLn( $callback, "$node: Purging reader... Done" ); + + # Punch kernel to reader on HCP + $out = xCAT::zvmCPUtils->punch2Reader( $hcp, $userId, "/tmp/kernel", "sles.kernel", "" ); + if ( !( $out =~ m/$searchStr/i ) ) { + xCAT::zvmUtils->printLn( $callback, "$node: Punching kernel to reader... Failed" ); + return; + } + else { + xCAT::zvmUtils->printLn( $callback, "$node: Punching kernel to reader... Done" ); + } + + # Punch parm to reader on HCP + $out = xCAT::zvmCPUtils->punch2Reader( $hcp, $userId, "/tmp/parm", "sles.parm", "-t" ); + if ( !( $out =~ m/$searchStr/i ) ) { + xCAT::zvmUtils->printLn( $callback, "$node: Punching parm to reader... Failed" ); + return; + } + else { + xCAT::zvmUtils->printLn( $callback, "$node: Punching parm to reader... Done" ); + } + + # Punch initrd to reader on HCP + $out = xCAT::zvmCPUtils->punch2Reader( $hcp, $userId, "/tmp/initrd", "sles.initrd", "" ); + if ( !( $out =~ m/$searchStr/i ) ) { + xCAT::zvmUtils->printLn( $callback, "$node: Punching initrd to reader... Failed" ); + return; + } + else { + xCAT::zvmUtils->printLn( $callback, "$node: Punching initrd to reader... Done" ); + } + } + + # RHEL installation + elsif ( $distr =~ m/rhel/i ) { + + # Create directory in FTP root (/install) to hold template + $out = `mkdir -p /install/custom/install/rh`; + + # Copy kickstart template + $template = "/install/custom/install/rh/$profile"; + $out = `cp /opt/xcat/share/xcat/install/rh/$profile $template`; + + # Edit template + my $url = "ftp://$ftp/$distr/s390x/"; + $out = +`sed --in-place -e "s,replace_url,$url,g" \ -e "s,replace_ip,$hostIP,g" \ -e "s,replace_netmask,$mask,g" \ -e "s,replace_gateway,$gateway,g" \ -e "s,replace_nameserver,$nameserver,g" \ -e "s,replace_hostname,$hostname,g" \ -e "s,replace_rootpw,rootpw,g" $template`; + + # Read sample parmfile in /install/rhel5.3/s390x/images + $sampleParm = "/install/$distr/s390x/images/generic.prm"; + open( SAMPLEPARM, "<$sampleParm" ); + + # Search parmfile for -- root=/dev/ram0 ro ip=off ramdisk_size=40000 + while () { + + # If the line contains 'ramdisk_size' + if ( $_ =~ m/ramdisk_size/i ) { + $parmHeader = xCAT::zvmUtils->trimStr($_); + } + } + + # Close sample parmfile + close(SAMPLEPARM); + + # Get mdisk address + my @mdisks = xCAT::zvmUtils->getMdisks( $callback, $node ); + my $dasd = ""; + my $i = 0; + foreach (@mdisks) { + $i = $i + 1; + @parms = split( ' ', $_ ); + + # Do not put a comma at the end of the last disk address + if ( $i == @mdisks ) { + $dasd = $dasd . "0.0.$parms[1]"; + } + else { + $dasd = $dasd . "0.0.$parms[1],"; + } + } + + # Create parmfile LINUX5 PARM-R53 + # Limit to 80 characters/line -- maximum of 11 lines + # End result should be -- + # ramdisk_size=40000 root=/dev/ram0 ro ip=off + # ks=ftp://10.0.0.1/rhel5.3/s390x/compute.rhel5.s390x.tmpl + # RUNKS=1 cmdline + # DASD=0.0.0100 HOSTNAME=gpok4.endicott.ibm.com + # NETTYPE=qeth IPADDR=10.0.0.4 + # SUBCHANNELS=0.0.0800,0.0.0801,0.0.0800 + # NETWORK=10.0.0.0 NETMASK=255.255.255.0 + # SEARCHDNS=endicott.ibm.com BROADCAST=10.0.0.255 + # GATEWAY=10.0.0.1 DNS=9.0.2.11 MTU=1500 + # PORTNAME=UNASSIGNED PORTNO=0 LAYER2=0 + # vnc vncpassword=123456 + my $ks = "ftp://$ftp/custom/install/rh/$profile"; + + $parms = $parmHeader . "\n"; + $parms = $parms . "ks=$ks\n"; + $parms = $parms . "RUNKS=1 cmdline\n"; + $parms = $parms . "DASD=$dasd HOSTNAME=$hostname\n"; + $parms = $parms . "NETTYPE=$netType IPADDR=$hostIP\n"; + $parms = $parms . "SUBCHANNELS=$readChannel,$writeChannel,$dataChannel\n"; + $parms = $parms . "NETWORK=$network NETMASK=$mask\n"; + $parms = $parms . "SEARCHDNS=$domain BROADCAST=$broadcast\n"; + $parms = $parms . "GATEWAY=$gateway DNS=$nameserver MTU=1500\n"; + $parms = $parms . "PORTNAME=$portName PORTNO=$portNo LAYER2=$layer\n"; + $parms = $parms . "vnc vncpassword=123456\n"; + + # Write to parmfile + $parmFile = "/tmp/parm"; + open( PARMFILE, ">$parmFile" ); + print PARMFILE "$parms"; + close(PARMFILE); + + # Send kernel, parmfile, conf, and initrd to reader to HCP + $out = `cp /install/$distr/s390x/images/kernel.img /tmp/kernel`; + $out = `cp /install/$distr/s390x/images/initrd.img /tmp/initrd`; + $out = xCAT::zvmUtils->sendFile( $hcp, "/tmp/kernel" ); + $out = xCAT::zvmUtils->sendFile( $hcp, "/tmp/parm" ); + $out = xCAT::zvmUtils->sendFile( $hcp, "/tmp/initrd" ); + + # Set the virtual unit record devices online + $out = xCAT::zvmUtils->disableEnableDisk( $callback, $hcp, "-e", "c" ); + $out = xCAT::zvmUtils->disableEnableDisk( $callback, $hcp, "-e", "d" ); + + # Purge reader + $out = xCAT::zvmCPUtils->purgeReader( $hcp, $userId ); + xCAT::zvmUtils->printLn( $callback, "$node: Purging reader... Done" ); + + # Punch kernel to reader on HCP + $out = xCAT::zvmCPUtils->punch2Reader( $hcp, $userId, "/tmp/kernel", "rhel.kernel", "" ); + if ( !( $out =~ m/$searchStr/i ) ) { + xCAT::zvmUtils->printLn( $callback, "$node: Punching kernel to reader... Failed" ); + return; + } + else { + xCAT::zvmUtils->printLn( $callback, "$node: Punching kernel to reader... Done" ); + } + + # Punch parm to reader on HCP + $out = xCAT::zvmCPUtils->punch2Reader( $hcp, $userId, "/tmp/parm", "rhel.parm", "-t" ); + if ( !( $out =~ m/$searchStr/i ) ) { + xCAT::zvmUtils->printLn( $callback, "$node: Punching parm to reader... Failed" ); + return; + } + else { + xCAT::zvmUtils->printLn( $callback, "$node: Punching parm to reader... Done" ); + } + + # Punch initrd to reader on HCP + $out = xCAT::zvmCPUtils->punch2Reader( $hcp, $userId, "/tmp/initrd", "rhel.initrd", "" ); + if ( !( $out =~ m/$searchStr/i ) ) { + xCAT::zvmUtils->printLn( $callback, "$node: Punching initrd to reader... Failed" ); + return; + } + else { + xCAT::zvmUtils->printLn( $callback, "$node: Punching initrd to reader... Done" ); + } + } + + # Boot node + $out = `ssh $hcp "$::DIR/startvs $userId"`; + my $rc = xCAT::zvmUtils->isOutputGood( $callback, $out ); + if ( $rc == -1 ) { + xCAT::zvmUtils->printLn( $callback, "Installation failed" ); + return; + } + else { + xCAT::zvmUtils->printLn( $callback, "$node: $out" ); + } + + # IPL 000C (reader) on node when virtual server is online + sleep(5); + $out = xCAT::zvmCPUtils->sendCPCmd( $hcp, $userId, "IPL 000C" ); + xCAT::zvmUtils->printLn( $callback, +"$node: Starting VNC server. This may take a couple of minutes.\nYou may try and open a VNC client at any time." + ); + + return; +} + +#------------------------------------------------------- + +=head3 getMacs + + Description : Collects node MAC address + Arguments : Node + Returns : Nothing + Example : getMacs($callback, $node, $args); + +=cut + +#------------------------------------------------------- +sub getMacs { + + # Get inputs + my ( $callback, $node, $args ) = @_; + + # Get node properties from 'zvm' table + my @propNames = ( 'hcp', 'userid' ); + my $propVals = xCAT::zvmUtils->getNodeProps( 'zvm', $node, @propNames ); + + # Get HCP + my $hcp = $propVals->{'hcp'}; + if ( !$hcp ) { + xCAT::zvmUtils->printLn( $callback, "Error: Missing node HCP" ); + return; + } + + # Get node userID + my $userId = $propVals->{'userid'}; + if ( !$userId ) { + xCAT::zvmUtils->printLn( $callback, "Error: Missing node ID" ); + return; + } + + # Get the last 3 letters of userID + my $hexStr = xCAT::zvmUtils->ascii2hex("123"); + xCAT::zvmUtils->printLn( $callback, "Hex string -- $hexStr" ); + + return; +}