# RACsetup.def: Gather Setup Information for Remote Data Collection in a Cluster # $Id: RACsetup.def,v 1.29 2008/02/25 17:32:55 mschenke Exp $ # ARCS: $Header: /home/cvs/repository/RDA_4/src/scripting/lib/modules/RACsetup.def,v 1.29 2008/02/25 17:32:55 mschenke Exp $ # # Change History # 20080225 MSC Change the copyright notice. =head1 NAME RACsetup - Gathers Setup Information for Remote Data Collection in a Cluster =head1 DESCRIPTION This module supports the following setup and configuration actions: =cut # Initialisation var $ORACLE_HOME = getEnv('ORACLE_HOME') var $ORACLE_SID = getEnv('ORACLE_SID') var $FORCE = getSetting('RDA_FORCE') var $VERBOSE = getSetting('RDA_VERBOSE') var $RDA_WORK = getSetting('RDA_WORK') var $SEP = repeat('-',getSetting('RDA_COLUMNS',79)) var $OSN = getOsName() # Restrict its usage on Unix and cygwin if !or(isUnix(),match($OSN,'cygwin')) {echo 'Only UNIX platforms are currently supported' die 'Cluster data collection setup aborted' } # Define common macros macro exec_rda {var ($nod,$opt,$dsc) = @arg if getSetting(concat('REMOTE_',$nod,'_HOSTNAME')) {import $VERBOSE if rda($nod,$opt) echo ' ',$dsc,' on node ',$nod,' failed (exit code: ',last,')' elsif $VERBOSE echo ' ',$dsc,' on node ',$nod,' succeeded' } } macro list_nodes {# Treat specified nodes if getSetting('EXT_ARGS') return split('\|',last) # When no nodes are specified, treat all nodes in force mode if getSetting('RDA_FORCE') return split(',',getSetting('REMOTE_NODES')) # Otherwise, no nodes are considered return () } macro is_local {var ($nod) = @arg if !$flg {var @loc = (getSetting('MACHINE_NAME'),'localhost') if getSetting('DOMAIN_NAME') var $loc[2] = join('.',$loc[0],last) var $flg = true keep $flg,@loc } loop $loc (@loc) {if compare('eq',$nod,$loc) return 1 } return 0 } # Execute the specified action var $act = getSetting('EXT_CMD') =head2 setup Gets the list of all nodes belonging to a cluster, gathers the related setup information (such as Oracle home and SID), and generates the corresponding setup files. When you specify the B<-f> option, it also resets the default remote commands and the external collections are disabled on the collecting node. =cut if compare('eq',$act,'setup') {var @tb_hom var @tb_nod var @tb_sid var %tb_set # Define the macros to get the nodes names macro get_db {var ($usr) = @arg var $cnt = 0 import @tb_nod,@tb_sid if $usr {debug 'In RACsetup, getting nodes using gv$instance' set $sql {SELECT instance_name || '|' || host_name " FROM gv$instance " ORDER BY thread#; } if loadSql($sql) {if grepLastSql('^(ORA|SP2)-\d{4,}:') return 0 loop $lin (grepLastSql('\|')) {incr $cnt var ($tb_sid[$cnt],$tb_nod[$cnt]) = split('\|',$lin,2) } } } return $cnt } macro get_nodes {var ($cmd) = @arg var $cnt = 0 import @tb_nod if loadCommand($cmd) {debug 'In RACsetup, getting nodes using ',$cmd loop $nod (getLines()) {incr $cnt var $tb_nod[$cnt] = $nod } } return $cnt } # Define a macro to get the database login password macro get_password {var $log = uc($arg[0]) import %tb_set if compare('ne',$log,'/') {var $pwd = askPassword(concat('Enter ',$log,' user password: ')) if $pwd var $tb_set{concat('SQL_PASSWORD_',$log)} = trim(pack('u',$pwd)) } return $pwd } # Determine if the node list can be get from the database if getSetting('EXT_ARGS') {var ($usr) = split('\|',last) # Check ORACLE_HOME if !testDir('d',$ORACLE_HOME) {echo 'ORACLE_HOME not set in environment. Please set and retry' die 'Cluster data collection setup aborted' } # Determine the user to connect to the database if match($usr,'^/$') {if $ORACLE_SID {call setSqlLogin(concat('@ AS SYSDBA'),'') call setTempSetting('RAC_SQL_LOGIN','/') call setTempSetting('RAC_SQL_SYSDBA',1) } else {echo 'ORACLE_SID not set in environment. Please set and try again' die 'Cluster data collection setup aborted' } } elsif match($usr,'^/(@.*)$') {call setSqlLogin(concat(last,' AS SYSDBA'),'') call setTempSetting('RAC_SQL_LOGIN','/') call setTempSetting('RAC_SQL_SYSDBA',1) } elsif match($usr,'/') {echo 'Invalid oracle user' die 'Cluster data collection setup aborted' } elsif match($usr,'^(.*)@') {var ($str) = (last) call setSqlLogin($usr,get_password($str)) call setTempSetting('RAC_SQL_LOGIN',uc($str)) call setTempSetting('RAC_SQL_SYSDBA',0) } else {if $ORACLE_SID {call setSqlLogin($usr,get_password($usr)) call setTempSetting('RAC_SQL_LOGIN',uc($usr)) call setTempSetting('RAC_SQL_SYSDBA',0) } else {echo 'ORACLE_SID not set in environment. Please set and try again' die 'Cluster data collection setup aborted' } } } else {var $usr = undef if getSetting('NO_DIALOG') {call setTempSetting('RAC_DFT_SQL_LOGIN','/') call setTempSetting('RAC_DFT_SQL_SYSDBA',1) } loop $lin (catFile($RDA_WORK,grepFile(getRemoteSetup('NOD001',true)),\ '^SQL_(LOGIN|SYSDBA)=')) call setTempSetting(concat('RAC_DFT_',key($lin)),value($lin)) } # Get the node list if get_db($usr) var ($cnt,$typ) = (last,'db') else {# If ORA_CRS_HOME environment variable is not set, find it if possible var $ORA_CRS_HOME = getEnv('ORA_CRS_HOME') if !testDir('d',$ORA_CRS_HOME) {if match($OSN,'solaris') {if grepFile('/etc/init.d/init.cssd','^ORA_CRS_HOME=','f') var $ORA_CRS_HOME = value(last) } elsif match($OSN,'hpux') {if grepFile('/sbin/init.d/init.cssd','^ORA_CRS_HOME=','f') var $ORA_CRS_HOME = value(last) } elsif match($OSN,'aix') {if grepFile('/etc/init.cssd','^ORA_CRS_HOME=','f') var $ORA_CRS_HOME = value(last) } elsif match($OSN,'dec_osf') {if grepFile('/sbin/init.d/init.cssd','^ORA_CRS_HOME=','f') var $ORA_CRS_HOME = value(last) } elsif match($OSN,'linux') {if grepFile('/etc/init.d/init.cssd','^ORA_CRS_HOME=','f') var $ORA_CRS_HOME = value(last) } } if testDir('d',$ORA_CRS_HOME) var $cmd = concat(catCommand($ORA_CRS_HOME,'bin','olsnodes'),' 2>/dev/null') else var $cmd = '' # Get the node list using operating system commands if get_nodes($cmd) var ($cnt,$typ) = (last,'os') elsif get_nodes('lsnodes 2>/dev/null') var ($cnt,$typ) = (last,'os') else {echo 'No cluster nodes found' die 'Cluster data collection setup aborted' } } # Reset the default remote environment settings if $FORCE {call setSetting('REMOTE_SSH_AGENT') call setSetting('REMOTE_SSH_COMMAND') call setSetting('REMOTE_SSH_OPTIONS') call setSetting('REMOTE_SCP_COMMAND') call setSetting('REMOTE_SCP_OPTIONS') } # Align the remote environments on the local one var $spl = compare('ne',$RDA_WORK,'.') if $spl {call setTempSetting('RAC_SETUP_PHASE','split') if !isAbsolute($RDA_WORK) call setTempSetting('RAC_RDA_WORK',catDir(getSetting('RDA_HOME'),$RDA_WORK)) } else call setTempSetting('RAC_SETUP_PHASE','common') # Merge common settings from command line and remote node setup file var (%key,%tbl) = () loop $lin (grepFile(catFile($RDA_WORK,getRemoteSetup('NOD001',true)),'^\w+=')) var $tbl{key($lin)} = value($lin) if exists($tbl{'REMOTE_COMMON_SETTINGS'}) {var $lst = $tbl{'REMOTE_COMMON_SETTINGS'} loop $key (split(':',$lst)) {if exists($tbl{$key}) {var $key{$key} = 1 call setTempSetting(concat('RAC_COMMON_',$key),$tbl{$key}) } } } if getSetting('SET_COMMON_SETTINGS') {var $lst = last loop $key (split(':',$lst)) {var $val = getSetting(concat('SET_COMMON_',$key)) if defined($val) {var $key{$key} = 2 call setTempSetting(concat('RAC_COMMON_',$key),$val) } } } call setTempSetting('RAC_COMMON_SETTINGS',join(':',keys(%key))) # Get the common information echo $SEP echo 'Requesting common information' echo $SEP if getSetting('REMOTE_USER') {call setTempSetting('RAC_OS_LOGIN',last) call setTempSetting('RAC_ALT_LOGIN',1) } if match(getSetting('REMOTE_RDA_OPTIONS'),'-p\s+(\w+)\b') call setTempSetting('RAC_PROFILE',last) call requestSetting('RACsetup') if getSetting('RAC_OS_LOGIN') call setTempSetting('REMOTE_USER',last) else call setSetting('REMOTE_USER') var $prf = getSetting('RAC_PROFILE') var $top = getSetting('RAC_RDA_HOME') var $wrk = getSetting('RAC_RDA_WORK') var $tb_set{'SQL_LOGIN'} = getSetting('RAC_SQL_LOGIN') var $tb_set{'SQL_SYSDBA'} = getSetting('RAC_SQL_SYSDBA',0) if match($typ,'os') call get_password($tb_set{'SQL_LOGIN'}) # Add the common settings if getSetting('RAC_COMMON_SETTINGS') {var $lst = last var $tb_set{'REMOTE_COMMON_SETTINGS'} = $lst loop $key (split(':',$lst)) var $tb_set{$key} = getSetting(concat('RAC_COMMON_',$key)) } # Ping each non-local node. Any bad connect sets CLUSTER_UP to "N" var $hom = getSetting('ORACLE_HOME',getEnv('ORACLE_HOME')) var $dwn = 0 for $cur (1,$cnt) {var $nod = $tb_nod[$cur] if is_local($nod) {debug 'In RACsetup, getting local node information' if missing($tb_sid[$cur]) var $tb_sid[$cur] = getSetting('ORACLE_SID',getEnv('ORACLE_SID')) } else {debug 'In RACsetup, pinging node ',$nod call setTempSetting('REMOTE_RAC_HOSTNAME',$nod) if rexec('RAC','env',true) {var $tb_sta[$cur] = 'DOWN or INACCESSIBLE' incr $dwn } elsif missing($tb_sid[$cur]) {loop $lin (getRemoteLines()) {if compare('eq',key($lin),'ORACLE_SID') {var $tb_sid[$cur] = value($lin) break } } } } } # Get association between each node and database sid var @tbl = () call setTempSetting('RAC_SETUP_PHASE',$typ) for $cur (1,$cnt) {var $id = sprintf('NOD%03d',$cur) var $nod = $tb_nod[$cur] call setTempSetting('RAC_HOSTNAME',$nod) # Merge node settings from command line and remote node setup file var (%key,%tbl) = () loop $lin (grepFile(catFile($RDA_WORK,getRemoteSetup($id,true)),'^\w+=')) var $tbl{key($lin)} = value($lin) if exists($tbl{'ORACLE_HOME'}) call setTempSetting('RAC_ORACLE_HOME',$tbl{'ORACLE_HOME'}) else call setTempSetting('RAC_ORACLE_HOME',$hom) if exists($tbl{'ORACLE_SID'}) call setTempSetting('RAC_ORACLE_SID',$tbl{'ORACLE_SID'}) elsif $tb_sid[$cur] call setTempSetting('RAC_ORACLE_SID',last) else call setTempSetting('RAC_ORACLE_SID') if exists($tbl{'REMOTE_NODE_SETTINGS'}) {var $lst = $tbl{'REMOTE_NODE_SETTINGS'} loop $key (split(':',$lst)) {if exists($tbl{$key}) {var $key{$key} = 1 call setTempSetting(concat('RAC_NODE_',$key),$tbl{$key}) } } } var @pre = ('SET_NODE_') if is_local($nod) var @pre = (@pre,'SET_LOCAL_') else var @pre = (@pre,'SET_REMOTE_') if expr('==',$cur,1) var @pre = (@pre,'SET_FIRST_') if expr('==',$cur,$cnt) var @pre = (@pre,'SET_LAST_') loop $pre (@pre) {if getSetting(concat($pre,'SETTINGS')) {loop $key (split(':',last)) {var $val = getSetting(concat($pre,$key)) if defined($val) {var $key{$key} = 2 call setTempSetting(concat('RAC_NODE_',$key),$val) } } } } call setTempSetting('RAC_NODE_SETTINGS',join(':',keys(%key))) # Request or verify the ORACLE_HOME and ORACLE_SID of the remote node echo $SEP echo 'Requesting information for node ',$nod echo $SEP call requestSetting('RACsetup') var $hom = getSetting('RAC_ORACLE_HOME') var $tb_sid[$cur] = getSetting('RAC_ORACLE_SID') var %tb_xtr = () if getSetting('RAC_NODE_SETTINGS') {var $lst = last var $tb_xtr{'REMOTE_NODE_SETTINGS'} = $lst loop $key (split(':',$lst)) var $tb_xtr{$key} = getSetting(concat('RAC_NODE_',$key)) } # Generate the corresponding setup file call genRemoteSetup($id,'ORACLE_HOME',$hom,\ 'ORACLE_SID', $tb_sid[$cur],\ %tb_set,%tb_xtr) call setTempSetting(concat('REMOTE_',$id,'_DESCRIPTION'),\ concat('Cluster node ',$nod)) call setTempSetting(concat('REMOTE_',$id,'_HOSTNAME'),$nod) call setTempSetting(concat('REMOTE_',$id,'_HOME'),$top) call setTempSetting(concat('REMOTE_',$id,'_SPLIT'),$spl) call setTempSetting(concat('REMOTE_',$id,'_STEP'),'N') call setTempSetting(concat('REMOTE_',$id,'_WORK'),$wrk) var @tbl = (@tbl,$id) } call setTempSetting('REMOTE_NODES',join(',',@tbl)) call setTempSetting('REMOTE_RDA_OPTIONS',concat('-vSCRPy -p ',$prf)) # Limit the external collections on the collecting node if or($FORCE,not(defined(getSetting('NO_LOAD')))) call setTempSetting('NO_LOAD',1) # Print the setup summary echo $SEP echo 'RAC Setup Summary' echo $SEP echo 'Nodes:' for $cur (1,$cnt) {var $id = sprintf('NOD%03d',$cur) if $tb_sta[$cur] echo '* ',$id,' ',$tb_nod[$cur],'/',$tb_sid[$cur],\ ' (Node ',$tb_sta[$cur],')' else echo '. ',$id,' ',$tb_nod[$cur],'/',$tb_sid[$cur] } if $dwn echo $cnt,' nodes found (',$dwn,' down)' else echo $cnt,' nodes found' if !$spl {call command(concat(getSetting('RDA_SELF'),' -c')) if status() echo tput('reverse'),\ 'Note: File alterations should be allowed to perform the collection',\ tput('off') } } =head2 disable Disables the remote collection. This is only performed for nodes that are executing a step before the post treatment or the report package transfer. When no nodes are specified and the force option is specified, all nodes are considered. =cut elsif compare('eq',$act,'disable') {var %rtr = ('I','d','N','d','P','P','R','d','T','T') var %sta = ('P','waiting for post treatment','T','waiting for transfer') # Recover step information for aborted sessions if initSteps(true) call endSteps() # Adapt last step loop $nod (list_nodes()) {var $key = concat('REMOTE_',$nod,'_STEP') var $stp = getSetting($key,'N') if $rtr{$stp} {call setSetting($key,last) if $VERBOSE echo ' ',$nod,' ',nvl($sta{$stp},'remote collection disabled') } } } =head2 edit Edits one or more remote node initial settings. These modifications are provided as a comma separated list of key/value pairs and no settings are created. If no nodes are specified and the force option is specified, all nodes are considered. =cut elsif compare('eq',$act,'edit') {# Parse the modification list var %new = () loop $itm (split(',',getSetting('EXT_EDIT'))) {if key($itm) var $new{last} = hex2chr(nvl(value($itm),'')) } # Modify the nodes setup loop $nod (list_nodes()) {var ($cnt,%tbl) = (0) var $cfg = catFile($RDA_WORK,getRemoteSetup($nod,true)) loop $itm (grepFile($cfg,'^\w+=')) {var $key = key($itm) if exists($new{$key}) {var $tbl{$key} = $new{$key} incr $cnt } else var $tbl{$key} = value($itm) } if $cnt {call genRemoteSetup($nod,%tbl) if $VERBOSE echo ' Initial ',$nod,' setup modified' } } } =head2 list Lists the nodes and the related Oracle SIDs. For the remote nodes, a command is executed to check its accessibility. =cut elsif compare('eq',$act,'list') {var ($cnt,$dwn,$loc,%sta) = (0,0,getSetting('MACHINE_NAME')) var @nod = split(',',getSetting('REMOTE_NODES')) loop $nod (@nod) {incr $cnt next !isRemote($nod) debug 'Testing ',$nod,' accessibility ...' if rexec($nod,'env',true) {var $sta{$nod} = 'DOWN or INACCESSIBLE' incr $dwn } } echo 'Nodes:' loop $nod (@nod) {var $hst = getSetting(concat('REMOTE_',$nod,'_HOSTNAME')) var $sid = '' var $cfg = catFile($RDA_WORK,getRemoteSetup($nod,true)) loop $lin (grepFile($cfg,'^ORACLE_SID=')) var $sid = value($lin) if $sta{$nod} echo '* ',$nod,' ',$hst,'/',$sid,' (Node ',$sta{$nod},')' else echo '. ',$nod,' ',$hst,'/',$sid } if $dwn echo $cnt,' nodes found (',$dwn,' down)' else echo $cnt,' nodes found' } =head2 restart Restarts the remote node collection from the beginning. This action is only performed if the node step has been defined already. When no nodes are specified and the force option is specified, all nodes are restarted. =cut elsif compare('eq',$act,'restart') {# Recover step information for aborted sessions if initSteps(true) call endSteps() # Adapt last step loop $nod (list_nodes()) {var $key = concat('REMOTE_',$nod,'_STEP') if getSetting($key) {call setSetting($key,'N') if $VERBOSE echo ' ',$nod,' remote collection restarted' } } } =head2 retry Tries to execute the last step of remote data collections again and this is only performed for nodes with errors. If no nodes are specified and the force option is specified, all nodes are restarted. =cut elsif compare('eq',$act,'retry') {var %rtr = ('c','I','d','N','i','I','n','N','p','P','r','R','t','T') var %sta = ('I','Install','N','New','P','Post','R','Run','T','Transfer') # Recover step information for aborted sessions if initSteps(true) call endSteps() # Adapt last step loop $nod (list_nodes()) {var $key = concat('REMOTE_',$nod,'_STEP') if $rtr{getSetting($key)} {var $stp = last call setSetting($key,$stp) if $VERBOSE echo ' ',$nod," remote collection status reset as '",$sta{$stp},"'" } } } =head2 set_dft, set_remsh, set_rsh, set_ssh, set_ssh0 Specifies which commands to use for remote operations for the specified nodes. When no nodes are specified and the force option is specified, all nodes are considered. =cut elsif compare('eq',$act,'set_dft') {loop $nod (list_nodes()) {if getSetting(concat('REMOTE_',$nod,'_HOSTNAME')) {debug 'Resetting remote commands for ',$nod,' ...' call setSetting(concat('REMOTE_',$nod,'_SSH_COMMAND')) call setSetting(concat('REMOTE_',$nod,'_SSH_OPTIONS')) call setSetting(concat('REMOTE_',$nod,'_SCP_COMMAND')) call setSetting(concat('REMOTE_',$nod,'_SCP_OPTIONS')) } } } elsif match($act,'^set_(remsh|rsh|ssh0?)$') {var ($typ) = (last) var %ssh = ('remsh','remsh','rsh','rsh','ssh','ssh','ssh0','ssh') var %scp = ('remsh','rcp','rsh','rcp','ssh','scp','ssh0','scp') var $ssh = findCommand($ssh{$typ}) var $scp = findCommand($scp{$typ}) if !$ssh die $ssh{$typ},' not found!' elsif !$scp die $scp{$typ},' not found!' else {var %tb1 = ('remsh','','rsh','',\ 'ssh','-Cnq -o ConnectTimeout=30','ssh0','-Cnq') var %tb2 = ('remsh','-p','rsh','-p',\ 'ssh','-BCpq -o ConnectTimeout=30','ssh0','-Cpq') loop $nod (list_nodes()) {if getSetting(concat('REMOTE_',$nod,'_HOSTNAME')) {debug 'Using ',$ssh{$typ},' and ',$scp{$typ},' for ',$nod,' ...' call setSetting(concat('REMOTE_',$nod,'_SSH_COMMAND'),$ssh,\ 'F','Node specific remote command') call setSetting(concat('REMOTE_',$nod,'_SSH_OPTIONS'),$tb1{$typ},\ 'T','Node specific remote command options') call setSetting(concat('REMOTE_',$nod,'_SCP_COMMAND'),$scp,\ 'F','Node specific remote copy command') call setSetting(concat('REMOTE_',$nod,'_SCP_OPTIONS'),$tb2{$typ},\ 'T','Node specific remote copy command options') } } } } =head2 start_daemon Starts a background collection on the specified nodes. When no nodes are specified and the force option is specified, all nodes are considered. =cut elsif compare('eq',$act,'start_daemon') {loop $nod (list_nodes()) call rda($nod,'-vB','Background collection start') } =head2 stop_daemon Stops the background collection on the specified nodes. When no nodes are specified and the force option is specified, all nodes are considered. =cut elsif compare('eq',$act,'stop_daemon') {loop $nod (list_nodes()) call rda($nod,'-vH','Background collection stop') } =head2 suspend Suspends the remote collection by putting the current step in an error state. This action is only performed for nodes where the collection is not completed. When no nodes are specified and the force option is specified, all nodes are considered. You can enable the remote collection again by using a C command. =cut elsif compare('eq',$act,'suspend') {var %rtr = ('I','i','N','n','P','p','R','r','T','t') # Recover step information for aborted sessions if initSteps(true) call endSteps() # Adapt last step loop $nod (list_nodes()) {var $key = concat('REMOTE_',$nod,'_STEP') if $rtr{getSetting($key,'N')} {var $stp = last call setSetting($key,$stp) if $VERBOSE echo ' ',$nod,' remote collection suspended' } } } =begin credits =over 10 =item RDA 4.2: Roger Snowden. =item RDA 4.5: Bob Caldwell. =back =end credits =head1 COPYRIGHT NOTICE Copyright (c) 2002-2008, Oracle. All rights reserved. =head1 TRADEMARK NOTICE Oracle, JD Edwards, PeopleSoft, and Siebel are registered trademarks of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. =cut