mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-23 20:22:05 +00:00
* Check in init version of cumulus support * Add cumulus installation doc * modify victor's comments.
412 lines
11 KiB
Perl
Executable File
412 lines
11 KiB
Perl
Executable File
#!/usr/bin/env perl
|
|
|
|
#---------------------------------------------------------
|
|
# Configure Ethnet BNT switches
|
|
#---------------------------------------------------------
|
|
|
|
BEGIN
|
|
{
|
|
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
|
$::XCATDIR = $ENV{'XCATDIR'} ? $ENV{'XCATDIR'} : '/etc/xcat';
|
|
}
|
|
use lib "$::XCATROOT/lib/perl";
|
|
|
|
|
|
use strict;
|
|
use Socket;
|
|
use Getopt::Long;
|
|
use Expect;
|
|
use Net::Ping;
|
|
use xCAT::Usage;
|
|
use xCAT::NodeRange;
|
|
use xCAT::NetworkUtils;
|
|
use xCAT::Utils;
|
|
use xCAT::Table;
|
|
use xCAT::MsgUtils;
|
|
|
|
Getopt::Long::Configure("bundling");
|
|
$Getopt::Long::ignorecase = 0;
|
|
|
|
#global variables
|
|
my @nodes;
|
|
my @filternodes;
|
|
|
|
|
|
#---------------------------------------------------------
|
|
#Main
|
|
|
|
# parse the options
|
|
if (
|
|
!GetOptions(
|
|
'h|help' => \$::HELP,
|
|
'switches=s' => \$::SWITCH,
|
|
'port=s' => \$::PORT,
|
|
'vlan=s' => \$::VLAN,
|
|
'user=s' => \$::USER,
|
|
'password=s' => \$::PASSWORD,
|
|
'snmp' => \$::SNMP,
|
|
'ssh' => \$::SSH,
|
|
'license=s' => \$::LICENSE,
|
|
'ntp' => \$::NTP,
|
|
'all' => \$::ALL,
|
|
)
|
|
)
|
|
{
|
|
&usage;
|
|
exit(1);
|
|
}
|
|
|
|
# display the usage if -h or --help is specified
|
|
if ($::HELP)
|
|
{
|
|
&usage;
|
|
exit(0);
|
|
}
|
|
|
|
if ($::SWITCH) {
|
|
my @filternodes = xCAT::NodeRange::noderange( $::SWITCH );
|
|
if (nodesmissed) {
|
|
my $nodenotdefined = join(',', nodesmissed);
|
|
xCAT::MsgUtils->message("I","The following nodes are not defined in xCAT DB: $nodenotdefined");
|
|
}
|
|
# check switch type
|
|
my $switchestab = xCAT::Table->new('switches');
|
|
my $switches_hash = $switchestab->getNodesAttribs(\@filternodes,['switchtype']);
|
|
foreach my $fsw (@filternodes) {
|
|
if (($switches_hash->{$fsw}->[0]->{switchtype}) =~ /cumulus/) {
|
|
push @nodes, $fsw;
|
|
} else {
|
|
xCAT::MsgUtils->message("E","The $fsw is not cumulus switch, will not config");
|
|
}
|
|
}
|
|
unless (@nodes) {
|
|
xCAT::MsgUtils->message("E","No Valid Switch to process");
|
|
exit(1);
|
|
}
|
|
} else {
|
|
xCAT::MsgUtils->message("E","Invalid flag, please provide switches with --switches");
|
|
&usage;
|
|
exit(1);
|
|
}
|
|
|
|
my $switches = join(",",@nodes);
|
|
my $cmd;
|
|
my $vlan;
|
|
my $port;
|
|
my $sub_req;
|
|
my $rc;
|
|
|
|
if (($::SSH) || ($::ALL))
|
|
{
|
|
config_ssh();
|
|
}
|
|
|
|
if (($::LICENSE) || ($::ALL))
|
|
{
|
|
install_license();
|
|
}
|
|
|
|
if (($::SNMP) || ($::ALL))
|
|
{
|
|
config_snmp();
|
|
}
|
|
if (($::NTP) || ($::ALL))
|
|
{
|
|
config_ntp();
|
|
}
|
|
if ($::VLAN)
|
|
{
|
|
#config_vlan();
|
|
}
|
|
sub config_ssh {
|
|
my $password = "CumulusLinux!";
|
|
my $userid = "cumulus";
|
|
my $timeout = 10;
|
|
my $keyfile = "/root/.ssh/id_rsa.pub";
|
|
my $rootkey = `cat /root/.ssh/id_rsa.pub`;
|
|
my $cmd;
|
|
my @config_switches;
|
|
|
|
foreach my $switch (@nodes) {
|
|
#remove old host key from /root/.ssh/known_hosts
|
|
$cmd = `ssh-keygen -R $switch`;
|
|
|
|
my ($exp, $errstr) = cumulus_connect($switch, $userid, $password, $timeout);
|
|
if (!defined $exp) {
|
|
print ("connect failed $errstr\n");
|
|
next;
|
|
}
|
|
|
|
my $ret;
|
|
my $err;
|
|
|
|
($ret, $err) = cumulus_exec($exp, "mkdir -p /root/.ssh");
|
|
($ret, $err) = cumulus_exec($exp, "chmod 700 /root/.ssh");
|
|
($ret, $err) = cumulus_exec($exp, "echo \"$rootkey\" >/root/.ssh/authorized_keys");
|
|
($ret, $err) = cumulus_exec($exp, "chmod 644 /root/.ssh/authorized_keys");
|
|
|
|
$exp->hard_close();
|
|
push (@config_switches, $switch);
|
|
}
|
|
|
|
if (@config_switches) {
|
|
#update switch status
|
|
my $csw = join(",",@config_switches);
|
|
$cmd = "chdef $csw status=ssh_configed ";
|
|
$rc= xCAT::Utils->runcmd($cmd, 0);
|
|
print "ssh configured for $csw\n";
|
|
}
|
|
}
|
|
|
|
sub cumulus_connect {
|
|
my $server = shift;
|
|
my $userid = shift;
|
|
my $password = shift;
|
|
my $timeout = shift;
|
|
|
|
my $ssh = Expect->new;
|
|
my $command = 'ssh';
|
|
my @parameters = ($userid . "@" . $server);
|
|
|
|
$ssh->debug(0);
|
|
$ssh->log_stdout(0); # suppress stdout output..
|
|
$ssh->slave->stty(qw(sane -echo));
|
|
|
|
unless ($ssh->spawn($command, @parameters))
|
|
{
|
|
my $err = $!;
|
|
$ssh->soft_close();
|
|
my $rsp;
|
|
return(undef, "unable to run command $command $err\n");
|
|
}
|
|
|
|
$ssh->expect($timeout,
|
|
[ "-re", qr/WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED/, sub {die "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!\n"; } ],
|
|
[ "-re", qr/\(yes\/no\)\?\s*$/, sub { $ssh->send("yes\n"); exp_continue; } ],
|
|
[ "-re", qr/ password:/, sub {$ssh->send("$password\n"); exp_continue; } ],
|
|
[ "-re", qr/:~\$/, sub { $ssh->send("sudo su\n"); exp_continue; } ],
|
|
[ "-re", qr/ password for cumulus:/, sub { $ssh->send("$password\n"); exp_continue; } ],
|
|
[ "-re", qr/.*\/home\/cumulus#/, sub { $ssh->clear_accum(); } ],
|
|
[ timeout => sub { die "No login.\n"; } ]
|
|
);
|
|
$ssh->clear_accum();
|
|
return ($ssh);
|
|
}
|
|
|
|
sub cumulus_exec {
|
|
my $exp = shift;
|
|
my $cmd = shift;
|
|
my $timeout = shift;
|
|
my $prompt = shift;
|
|
|
|
$timeout = 10 unless defined $timeout;
|
|
$prompt = qr/.*\/home\/cumulus#/ unless defined $prompt;
|
|
|
|
|
|
$exp->clear_accum();
|
|
$exp->send("$cmd\n");
|
|
my ($mpos, $merr, $mstr, $mbmatch, $mamatch) = $exp->expect(6, "-re", $prompt);
|
|
|
|
if (defined $merr) {
|
|
return(undef,$merr);
|
|
}
|
|
return($mbmatch);
|
|
}
|
|
|
|
# for cumulus switch, need to set the license file
|
|
sub install_license {
|
|
my @config_switches;
|
|
print "install_license\n";
|
|
my $license_file;
|
|
my $file_name = "/root/license.txt";
|
|
|
|
if ($::LICENSE) {
|
|
$license_file = $::LICENSE;
|
|
}
|
|
|
|
print "file = $license_file\n";
|
|
if (!(-e $license_file) ) {
|
|
print "$license_file is not exist\n";
|
|
}
|
|
|
|
foreach my $switch (@nodes) {
|
|
my $cmd = "xdcp $switch $license_file $file_name";
|
|
$rc= xCAT::Utils->runcmd($cmd, 0);
|
|
if ($::RUNCMD_RC != 0) {
|
|
xCAT::MsgUtils->message("E","Failed to xscp $license_file to $switch");
|
|
next;
|
|
}
|
|
|
|
$cmd = "xdsh $switch '/usr/cumulus/bin/cl-license -i $file_name' ";
|
|
$rc= xCAT::Utils->runcmd($cmd, 0);
|
|
if ($::RUNCMD_RC != 0) {
|
|
xCAT::MsgUtils->message("E","Failed to $cmd to $switch");
|
|
next;
|
|
}
|
|
push (@config_switches, $switch);
|
|
}
|
|
if (@config_switches) {
|
|
my $csw = join(",",@config_switches);
|
|
print "license is installed on $csw\n";
|
|
}
|
|
|
|
}
|
|
|
|
|
|
#setup secure SNMP v3
|
|
sub config_snmp {
|
|
my $snmp_user;
|
|
my $snmp_passwd;
|
|
my @config_switches;
|
|
my $cmd;
|
|
|
|
print "start to config_snmp\n";
|
|
if ($::USER) {
|
|
$snmp_user = $::USER;
|
|
} else {
|
|
$snmp_user = "xcatadmin";
|
|
}
|
|
if ($::PASSWORD) {
|
|
$snmp_passwd = $::PASSWORD;
|
|
} else {
|
|
$snmp_passwd = "xcatpassw0rd";
|
|
}
|
|
|
|
my $file = "temp.txt";
|
|
open(FILE , ">$file")
|
|
or die "cannot open file $file\n";
|
|
print FILE "#xCAT modify following line\n";
|
|
print FILE "agentAddress udp:161,udp6:[::1]:161\n";
|
|
print FILE "rocommunity public default\n";
|
|
print FILE "rocommunity public default -V systemonly\n";
|
|
print FILE "createUser $snmp_user SHA $snmp_passwd\n";
|
|
print FILE "rwuser $snmp_user\n";
|
|
|
|
foreach my $switch (@nodes) {
|
|
#check if xdsh works
|
|
$cmd = "xdsh $switch date";
|
|
$rc= xCAT::Utils->runcmd($cmd, 0);
|
|
if ($::RUNCMD_RC != 0) {
|
|
xCAT::MsgUtils->message("E","xdsh command to $switch failed");
|
|
next;
|
|
}
|
|
my $cmd_line = "sed -i 's/^agentAddress/#agentAddress/g' /etc/snmp/snmpd.conf";
|
|
$cmd = "xdsh $switch $cmd_line";
|
|
$rc= xCAT::Utils->runcmd($cmd, 0);
|
|
|
|
$cmd = "xdcp $switch $file";
|
|
$rc= xCAT::Utils->runcmd($cmd, 0);
|
|
$cmd = "xdsh $switch 'cat $file >> /etc/snmp/snmpd.conf;rm -fr $file;systemctl restart snmpd;systemctl enable snmpd' ";
|
|
$rc= xCAT::Utils->runcmd($cmd, 0);
|
|
if ($::RUNCMD_RC != 0) {
|
|
xCAT::MsgUtils->message("E","Failed to update snmpd.conf for $switch");
|
|
next;
|
|
}
|
|
push (@config_switches, $switch);
|
|
}
|
|
close FILE;
|
|
$cmd = `rm -rf $file`;
|
|
if (@config_switches) {
|
|
#update switch status
|
|
my $csw = join(",",@config_switches);
|
|
$cmd = "chdef $csw status=snmp_configed snmpversion=3 snmpauth=sha snmpusername=$snmp_user snmppassword=$snmp_passwd";
|
|
$rc= xCAT::Utils->runcmd($cmd, 0);
|
|
}
|
|
|
|
}
|
|
|
|
sub config_ntp {
|
|
my @config_switches;
|
|
my $cmd;
|
|
|
|
my $master = `hostname -i`;
|
|
|
|
my $file = "temp.txt";
|
|
open(FILE , ">$file")
|
|
or die "cannot open file $file\n";
|
|
print FILE "#This file is created by xCAT \n";
|
|
print FILE "driftfile /var/lib/ntp/drift\n";
|
|
print FILE "disable auth\n";
|
|
print FILE "restrict 127.0.0.1\n";
|
|
print FILE "server $master iburst\n";
|
|
print FILE "interface listen eth0\n";
|
|
|
|
foreach my $switch (@nodes) {
|
|
#check if xdsh works
|
|
$cmd = "xdsh $switch date";
|
|
$rc= xCAT::Utils->runcmd($cmd, 0);
|
|
if ($::RUNCMD_RC != 0) {
|
|
xCAT::MsgUtils->message("E","xdsh command to $switch failed");
|
|
next;
|
|
}
|
|
my $cmd_line = "echo 'US/Eastern'>/etc/timezone;dpkg-reconfigure --frontend noninteractive tzdata";
|
|
print "$cmd_line\n";
|
|
$cmd = "xdsh $switch $cmd_line";
|
|
if ($::RUNCMD_RC != 0) {
|
|
print "Failed to update ntp timezone\n";
|
|
xCAT::MsgUtils->message("E","Failed to update ntp timezone for $switch");
|
|
next;
|
|
}
|
|
print "$cmd\n";
|
|
$cmd = "xdcp $switch $file";
|
|
$rc= xCAT::Utils->runcmd($cmd, 0);
|
|
$cmd = "xdsh $switch 'cp /etc/ntp.conf /etc/ntp.conf.orig;cp $file /etc/ntp.conf;rm -fr $file;systemctl restart ntp;systemctl enable ntp' ";
|
|
$rc= xCAT::Utils->runcmd($cmd, 0);
|
|
if ($::RUNCMD_RC != 0) {
|
|
xCAT::MsgUtils->message("E","Failed to update ntp for $switch");
|
|
next;
|
|
}
|
|
push (@config_switches, $switch);
|
|
}
|
|
close FILE;
|
|
$cmd = `rm -rf $file`;
|
|
|
|
if (@config_switches) {
|
|
#update switch status
|
|
my $csw = join(",",@config_switches);
|
|
$cmd = "chdef $csw status=ntp_configed";
|
|
$rc= xCAT::Utils->runcmd($cmd, 0);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
sub config_vlan {
|
|
if ($::PORT) {
|
|
$port = $::PORT;
|
|
} else {
|
|
&usage;
|
|
exit(1);
|
|
}
|
|
$vlan = $::VLAN;
|
|
print "Tagging VLAN=$vlan for $switches port $port\n";
|
|
#create vlan, tagged vlan
|
|
#$cmd = `xdsh $switches --devicetype EthSwitch::BNT "enable;configure terminal;vlan $vlan;exit;interface port $port;switchport mode trunk;switchport trunk allowed vlan $vlan;write memory;exit;exit"`;
|
|
|
|
}
|
|
|
|
|
|
#---------------------------------------------------------
|
|
|
|
=head3 usage
|
|
|
|
Displays message for -h option
|
|
|
|
=cut
|
|
|
|
#---------------------------------------------------------
|
|
sub usage
|
|
{
|
|
print "Usage:
|
|
configBNT [-?│-h│--help]
|
|
configBNT [--switches switchnames] [--all]
|
|
configBNT [--switches switchnames] [--ssh]
|
|
configBNT [--switches switchnames] [--license filename ]
|
|
configBNT [--switches switchnames] [--snmp] [--user snmp_user] [--password snmp_password] [--group snmp_group]
|
|
configBNT [--switches switchnames] [--ntp]
|
|
configBNT [--switches switchnames] [--port port] [--vlan vlan]
|
|
\n";
|
|
}
|
|
|
|
|