mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-03 21:02:34 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			256 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			256 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | 
						|
#TODO: delete entries not being refreshed if no noderange
 | 
						|
package xCAT_plugin::goconserver;
 | 
						|
BEGIN {
 | 
						|
        $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
 | 
						|
}
 | 
						|
use lib "$::XCATROOT/lib/perl";
 | 
						|
use strict;
 | 
						|
use File::Copy;
 | 
						|
use xCAT::Table;
 | 
						|
use xCAT::Utils;
 | 
						|
use xCAT::TableUtils;
 | 
						|
use Getopt::Long;
 | 
						|
use Sys::Hostname;
 | 
						|
use xCAT::SvrUtils;
 | 
						|
use xCAT::Goconserver;
 | 
						|
use Data::Dumper;
 | 
						|
 | 
						|
my $isSN;
 | 
						|
my $host;
 | 
						|
my $usage_string ="   makegocons [-V|--verbose] [-d|--delete] noderange
 | 
						|
    -h|--help                   Display this usage statement.
 | 
						|
    -v|--version                Display the version number.
 | 
						|
    -C|--cleanup                Remove the entries for the nodes whose definitions have been removed from xCAT db.
 | 
						|
    -q|--query  [noderange]     Display the console connection status.";
 | 
						|
 | 
						|
my $version_string = xCAT::Utils->Version();
 | 
						|
 | 
						|
sub handled_commands {
 | 
						|
    return {
 | 
						|
        makegocons => "goconserver"
 | 
						|
      }
 | 
						|
}
 | 
						|
 | 
						|
sub preprocess_request {
 | 
						|
    my $request = shift;
 | 
						|
    if ($request->{_xcatpreprocessed}->[0] == 1) { return [$request]; }
 | 
						|
    $::callback = shift;
 | 
						|
    my @requests;
 | 
						|
    my $noderange = $request->{node};    #Should be arrayref
 | 
						|
 | 
						|
    #display usage statement if -h
 | 
						|
    my $extrargs = $request->{arg};
 | 
						|
    my @exargs   = ($request->{arg});
 | 
						|
    if (ref($extrargs)) {
 | 
						|
        @exargs = @$extrargs;
 | 
						|
    }
 | 
						|
    @ARGV = @exargs;
 | 
						|
 | 
						|
    $isSN     = xCAT::Utils->isServiceNode();
 | 
						|
    my @hostinfo = xCAT::NetworkUtils->determinehostname();
 | 
						|
    my %iphash   = ();
 | 
						|
    foreach (@hostinfo) { $iphash{$_} = 1; }
 | 
						|
 | 
						|
    $Getopt::Long::ignorecase = 0;
 | 
						|
 | 
						|
    #$Getopt::Long::pass_through=1;
 | 
						|
    if (!GetOptions(
 | 
						|
        'h|help'      => \$::HELP,
 | 
						|
        'D|debug'     => \$::DEBUG,
 | 
						|
        'v|version'   => \$::VERSION,
 | 
						|
        'V|verbose'   => \$::VERBOSE)) {
 | 
						|
        $request = {};
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    if ($::HELP) {
 | 
						|
        $::callback->({ data => $usage_string });
 | 
						|
        $request = {};
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    if ($::VERSION) {
 | 
						|
        $::callback->({ data => $version_string });
 | 
						|
        $request = {};
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    # get site master
 | 
						|
    my $master = xCAT::TableUtils->get_site_Master();
 | 
						|
    if (!$master) { $master = hostname(); }
 | 
						|
 | 
						|
    # get conserver for each node
 | 
						|
    my %cons_hash = ();
 | 
						|
    my $hmtab     = xCAT::Table->new('nodehm');
 | 
						|
    my @items;
 | 
						|
    my $allnodes = 1;
 | 
						|
    if ($noderange && @$noderange > 0) {
 | 
						|
        $allnodes = 0;
 | 
						|
        my $hmcache = $hmtab->getNodesAttribs($noderange, [ 'node', 'serialport', 'cons', 'conserver' ]);
 | 
						|
        foreach my $node (@$noderange) {
 | 
						|
            my $ent = $hmcache->{$node}->[0]; #$hmtab->getNodeAttribs($node,['node', 'serialport','cons', 'conserver']);
 | 
						|
            if ($ent) {
 | 
						|
                push (@items, $ent);
 | 
						|
            } else {
 | 
						|
                my $rsp->{data}->[0] = $node .": ignore, cons attribute or serialport attribute is not specified.";
 | 
						|
                xCAT::MsgUtils->message("I", $rsp, $::callback);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        $allnodes = 1;
 | 
						|
        @items = $hmtab->getAllNodeAttribs([ 'node', 'serialport', 'cons', 'conserver' ]);
 | 
						|
    }
 | 
						|
    my @nodes = ();
 | 
						|
    foreach (@items) {
 | 
						|
        if (((!defined($_->{cons})) || ($_->{cons} eq "")) and !defined($_->{serialport})) {
 | 
						|
            my $rsp->{data}->[0] = $_->{node} .": ignore, cons attribute or serialport attribute is not specified.";
 | 
						|
            xCAT::MsgUtils->message("I", $rsp, $::callback);
 | 
						|
            next;
 | 
						|
        }
 | 
						|
        if (defined($_->{conserver})) { push @{ $cons_hash{ $_->{conserver} }{nodes} }, $_->{node}; }
 | 
						|
        else { push @{ $cons_hash{$master}{nodes} }, $_->{node}; }
 | 
						|
        push @nodes, $_->{node};
 | 
						|
    }
 | 
						|
 | 
						|
    # send to conserver hosts
 | 
						|
    foreach my $host (keys %cons_hash) {
 | 
						|
        my $reqcopy = {%$request};
 | 
						|
        $reqcopy->{'_xcatdest'} = $host;
 | 
						|
        $reqcopy->{_xcatpreprocessed}->[0] = 1;
 | 
						|
        $reqcopy->{'_allnodes'} = [$allnodes]; # the original command comes with nodes or not
 | 
						|
        $reqcopy->{node} = $cons_hash{$host}{nodes};
 | 
						|
        push @requests, $reqcopy;
 | 
						|
    }    #end foreach
 | 
						|
 | 
						|
    if ($::DEBUG) {
 | 
						|
        my $rsp;
 | 
						|
        $rsp->{data}->[0] = "In preprocess_request, request is " . Dumper(@requests);
 | 
						|
        xCAT::MsgUtils->message("I", $rsp, $::callback);
 | 
						|
    }
 | 
						|
    return \@requests;
 | 
						|
}
 | 
						|
 | 
						|
sub process_request {
 | 
						|
    my $req = shift;
 | 
						|
    $::callback  = shift;
 | 
						|
    my @hostinfo = xCAT::NetworkUtils->determinehostname();
 | 
						|
    $host = $hostinfo[-1];
 | 
						|
    $isSN = xCAT::Utils->isServiceNode();
 | 
						|
    if ($req->{command}->[0] eq "makegocons") {
 | 
						|
        makegocons($req, \@hostinfo);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
sub start_goconserver {
 | 
						|
    my ($rsp, $running, $ready, $ret);
 | 
						|
    unless (-x "/usr/bin/goconserver") {
 | 
						|
        xCAT::MsgUtils->error_message("goconserver is not installed.", $::callback);
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
    # if goconserver is installed, check the status of conserver service.
 | 
						|
    if (xCAT::Goconserver::is_conserver_running()) {
 | 
						|
        xCAT::MsgUtils->error_message("conserver is started, please stop it at first.", $::callback);
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
    xCAT::Goconserver::switch_goconserver($::callback);
 | 
						|
    $running = xCAT::Goconserver::is_goconserver_running();
 | 
						|
    $ready = xCAT::Goconserver::is_xcat_conf_ready();
 | 
						|
    if ( $running && $ready ) {
 | 
						|
        # Already started by xcat
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
    # user could customize the configuration, do not rewrite the configuration if this file has been
 | 
						|
    # generated by xcat
 | 
						|
    if (!$ready) {
 | 
						|
        $ret = xCAT::Goconserver::build_conf();
 | 
						|
        if ($ret) {
 | 
						|
            xCAT::MsgUtils->error_message("Failed to create configuration file for goconserver.", $::callback);
 | 
						|
            return 1;
 | 
						|
        }
 | 
						|
        if (!copy($::XCATROOT."/share/xcat/conf/goconslogrotate", "/etc/logrotate.d/goconserver")) {
 | 
						|
            xCAT::MsgUtils->warn_message("Failed to create logrotate configuration for goconserver.", $::callback);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    $ret = xCAT::Goconserver::restart_service();
 | 
						|
    if ($ret) {
 | 
						|
        xCAT::MsgUtils->error_message("Failed to start goconserver service.", $::callback);
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
    xCAT::MsgUtils->info_message("Starting goconserver service ...", $::callback);
 | 
						|
    sleep(3);
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
sub makegocons {
 | 
						|
    my $req = shift;
 | 
						|
    my $hostinfo = shift;
 | 
						|
    my $extrargs = $req->{arg};
 | 
						|
    my @exargs   = ($req->{arg});
 | 
						|
    if (ref($extrargs)) {
 | 
						|
        @exargs = @$extrargs;
 | 
						|
    }
 | 
						|
    @ARGV = @exargs;
 | 
						|
    $Getopt::Long::ignorecase = 0;
 | 
						|
    my ($delmode, $querymode, $cleanupmode);
 | 
						|
    GetOptions('d|delete' => \$delmode,
 | 
						|
        'q|query' => \$querymode,
 | 
						|
        'C|cleanup' => \$cleanupmode,
 | 
						|
    );
 | 
						|
 | 
						|
    my $svboot = 0;
 | 
						|
    my $rsp;
 | 
						|
    if (exists($req->{svboot})) {
 | 
						|
        $svboot = 1;
 | 
						|
    }
 | 
						|
    if ($cleanupmode) {
 | 
						|
        if (exists($req->{_allnodes}) && $req->{_allnodes}->[0] != 1) {
 | 
						|
            xCAT::MsgUtils->error_message("Can not specify noderange together with -C|--cleanup.", $::callback);
 | 
						|
            return 1;
 | 
						|
        }
 | 
						|
        return xCAT::Goconserver::cleanup_nodes($::callback);
 | 
						|
    }
 | 
						|
    my %cons_map = xCAT::Goconserver::get_cons_map($req);
 | 
						|
    if (! %cons_map) {
 | 
						|
        xCAT::MsgUtils->error_message("Could not get any console request entry.", $::callback);
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
    my $api_url = "https://$host:". xCAT::Goconserver::get_api_port();
 | 
						|
    if ($querymode) {
 | 
						|
        return xCAT::Goconserver::list_nodes($api_url, \%cons_map, $::callback)
 | 
						|
    }
 | 
						|
 | 
						|
    my $ret = start_goconserver();
 | 
						|
    if ($ret != 0) {
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
    my @entries    = xCAT::TableUtils->get_site_attribute("consoleondemand");
 | 
						|
    my $site_entry = $entries[0];
 | 
						|
    my $siteondemand = 0;
 | 
						|
    if (defined($site_entry)) {
 | 
						|
        if (lc($site_entry) eq "yes") {
 | 
						|
            $siteondemand = 1;
 | 
						|
        }
 | 
						|
        elsif (lc($site_entry) ne "no") {
 | 
						|
            # consoleondemand attribute is set, but it is not "yes" or "no"
 | 
						|
            xCAT::MsgUtils->error_message("Unexpected value $site_entry for consoleondemand attribute in site table.", $::callback);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    my (@nodes);
 | 
						|
    my $data = xCAT::Goconserver::gen_request_data(\%cons_map, $siteondemand, $::callback);
 | 
						|
    if (! $data) {
 | 
						|
        xCAT::MsgUtils->error_message("Could not generate the request data.", $::callback);
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
    $ret = xCAT::Goconserver::delete_nodes($api_url, $data, $delmode, $::callback);
 | 
						|
    if ($delmode) {
 | 
						|
        return $ret;
 | 
						|
    }
 | 
						|
    $ret = xCAT::Goconserver::create_nodes($api_url, $data, $::callback);
 | 
						|
    if ($ret != 0) {
 | 
						|
        xCAT::MsgUtils->error_message("Failed to create console entry in goconserver.", $::callback);
 | 
						|
        return $ret;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
1;
 |