#!/usr/bin/env perl # IBM(c) 2017 EPL license http://www.eclipse.org/legal/epl-v10.html use Fcntl qw(:DEFAULT :flock); use Time::HiRes qw(sleep); use File::Path; use IO::Socket; BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; } my $sleepint = int(rand(10)); #Stagger start to avoid overwhelming conserver/xCATd my ($lockfd, $bmcip); my $username = 'root'; my $password = '0penBmc'; my $node = $ARGV[0]; use constant CONSOLE_LOCK_FILE => "/tmp/xcat/consolelock"; use constant CONSOLE_LOCK_DIR => "/tmp/xcat"; sub acquire_lock { umask 0077; mkpath(CONSOLE_LOCK_DIR); print "Acquiring startup lock..."; unless (sysopen($lockfd, CONSOLE_LOCK_FILE, O_WRONLY | O_CREAT)) { print "Unable to open file ".CONSOLE_LOCK_FILE."\n"; sleep(15); exit 1; } unless (flock($lockfd, LOCK_EX)) { print "Unable to lock file ".CONSOLE_LOCK_FILE."\n"; close($lockfd); sleep(15); exit 1; } print "done\n"; unless (syswrite($lockfd, $$, length($$))) { print "Unable to write file ".CONSOLE_LOCK_FILE."\n"; close($lockfd); sleep(15); exit 1; } } sub release_lock { flock($lockfd, LOCK_UN); close($lockfd); } use lib "$::XCATROOT/lib/perl"; require xCAT::Client; sub getans { my $rsp = shift; if ($rsp->{node}) { $bmcip = $rsp->{node}->[0]->{bmcip}->[0]; $username = $rsp->{node}->[0]->{username}->[0]; $password = $rsp->{node}->[0]->{passwd}->[0]; if (exists $rsp->{node}->[0]->{error}) { my $error = $rsp->{node}->[0]->{error}->[0]; print "$error\n"; } } } my $cmdref = { command => ["getopenbmccons"], arg => ["text"], node => [ $ARGV[0] ] }; acquire_lock(); # avoid of congestion sleep(0.1); release_lock(); xCAT::Client::submit_request($cmdref, \&getans); until (($username or $password) and $bmcip ) { #Let other clients have a go $sleepint = 10 + int(rand(20)); print "Console not ready, retrying in $sleepint seconds (Ctrl-e,c,o to skip delay) \n"; sleep ($sleepint); acquire_lock(); sleep(0.1); release_lock(); xCAT::Client::submit_request($cmdref, \&getans); } my $isintel = 0; my $sleepint; my $rc; my $sshport = 2200; if ($ENV{SSHCONSOLEPORT}) { $sshport= $ENV{SSHCONSOLEPORT}; } #check if sshport is up my $sock = IO::Socket::INET->new( PeerAddr => $bmcip, PeerPort => $sshport, Proto => "tcp", Timeout => 10 ); while (!defined($sock)) { $sleepint = 10 + int(rand(20)); print "No BMC active at IP $bmcip, retrying in $sleepint seconds (Hit Ctrl-E,c,o to skip)\n"; sleep ($sleepint); acquire_lock(); sleep(0.1); release_lock(); $sock = IO::Socket::INET->new( PeerAddr => $bmcip, PeerPort => $sshport, Proto => "tcp", Timeout => 10 ); } $sock->close(); # To automatically connect to the console without the need to send over the ssh keys, # ensure sshpass is installed on the Management and/or Service Nodes. print "Unable to open console. If BMC pings, ensure sshpass is installed or ssh keys have been configured on the BMC.\n"; if (-x '/usr/bin/sshpass') { exec "/usr/bin/sshpass -p $password ssh -p $sshport -l $username -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $bmcip"; } else { exec "ssh -p $sshport -l $username -o PasswordAuthentication=no -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $bmcip"; }