code for OpenStack-Chef-Cookbook/xCAT integration

This commit is contained in:
jjhua 2013-10-22 10:07:08 -04:00
parent 66d62f7e65
commit 42bc6cef07
2 changed files with 353 additions and 2 deletions

View File

@ -0,0 +1,194 @@
# IBM(c) 2010 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT_plugin::cloud;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use strict;
use xCAT::Table;
use Getopt::Long;
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("pass_through");
#use xCAT::Utils;
#use xCAT::TableUtils;
use xCAT::Template;
sub handled_commands
{
return {makeclouddata => "cloud",};
}
############################################################
# check_options will process the options for makeclouddata and
# give a usage error for any invalid options
############################################################
sub check_options
{
my $req = shift;
my $callback = shift;
my $rc = 0;
Getopt::Long::Configure("bundling");
$Getopt::Long::ignorecase = 0;
Getopt::Long::Configure("no_pass_through");
# Exit if the packet has been preprocessed
if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; }
# Save the arguements in ARGV for GetOptions
if ($req && $req->{arg}) { @ARGV = @{$req->{arg}}; }
else { @ARGV = (); }
# Parse the options for makedhcp
if (!GetOptions(
'h|help' => \$::opt_h,
))
{
# If the arguements do not pass GetOptions then issue error message and return
return -1;
}
# display the usage if -h
if ($::opt_h)
{
return 1;
}
my $cloudlist =shift( @ARGV );
if( defined($cloudlist) ) {
my @clouds = split(",", $cloudlist);
$req->{clouds} = \@clouds;
}
return 0;
}
sub cloudvars {
my $inf = shift;
my $outf = shift;
my $cloud = shift;
my $callback = shift;
my $outh;
my $inh;
open($inh,"<",$inf);
unless ($inh) {
my $rsp;
$rsp->{errorcode}->[0]=1;
$rsp->{error}->[0]="Unable to open $inf, aborting\n";
$callback->($rsp);
return;
}
my $inc;
#First load input into memory..
while (<$inh>) {
$inc.=$_;
}
close($inh);
$inc =~ s/\$CLOUD/$cloud/eg;
$inc =~ s/#TABLE:([^:]+):([^:]+):([^#]+)#/xCAT::Template::tabdb($1,$2,$3)/eg;
open($outh,">",$outf);
unless($outh) {
my $rsp;
$rsp->{errorcode}->[0]=1;
$rsp->{error}->[0]="Unable to open $inf, aborting\n";
$callback->($rsp);
return;
}
print $outh $inc;
close($outh);
return 0;
}
sub process_request
{
my $req = shift;
my $callback = shift;
my $rc = 0;
# define usage statement
my $usage="Usage: \n\tmkcloudata\n\tmakeclouddata <cloudname>\n\tmakeclouddata [-h|--help]";
$rc = check_options($req,$callback);
if ($rc == -1) {
my $rsp = {};
$rsp->{data}->[0] = $usage;
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
return;
} elsif ($rc == 1) {
my $rsp = {};
$rsp->{data}->[0] = $usage;
xCAT::MsgUtils->message("I", $rsp, $callback, 0);
return;
}
my $tab = "clouds";
my $ptab = xCAT::Table->new("$tab");
unless ($ptab) {
my $rsp;
$rsp->{errorcode}->[0]=1;
$rsp->{error}->[0]="Unable to open $tab table";
$callback->($rsp);
return;
}
my $t = $req->{clouds};
my %h;
if( defined(@$t) ) {
%h = map { $_ => 1} @$t;
}
my @cloudentries = $ptab->getAllAttribs('name', 'template', 'repository');
foreach my $cloudentry (@cloudentries) {
my $cloud = $cloudentry->{name};
if( %h ) {
# if makeclouddata <cloudA>, and
if( $h{$cloud} != 1) {
next;
}
}
my $tmplfile = $cloudentry->{template};
my $repos = $cloudentry->{repository};
unless ( -r "$tmplfile") {
my $rsp;
$rsp->{errorcode}->[0]=1;
$rsp->{error}->[0]="The $cloud environment template $tmplfile doesn't exist.";
$callback->($rsp);
next;
}
unless ( -r "$repos") {
my $rsp;
$rsp->{errorcode}->[0]=1;
$rsp->{error}->[0]="The $cloud repository $repos doesn't exist.";
$callback->($rsp);
next;
}
my $tmperr = cloudvars(
$tmplfile,
"$repos/environments/$cloud.rb",
$cloud,
$callback
);
}
return;
}
1;

View File

@ -213,6 +213,8 @@ sub makescript {
$mn = xCAT::Utils->noderangecontainsMn(@$nodes);
my $cfgflag=0;
my $cloudflag=0;
my $inc;
my $t_inc;
my %table;
@ -239,6 +241,14 @@ sub makescript {
}
}
if( $line =~ /#CFGMGTINFO_EXPORT#/ ) {
$cfgflag = 1;
}
if ($cfgflag == 1) {
if( $line =~ /#CLOUDINFO_EXPORT#/ ) {
$cloudflag = 1;
}
}
}
close($inh);
@ -334,7 +344,23 @@ sub makescript {
# get all the nodes' setstate
my $nodes_setstate_hash = getNodesSetState($nodes);
my $cfginfo_hash;
my $cloudinfo_hash;
#
# if #CFGCLIENTLIST_EXPORT# exists, ...
if( $cfgflag == 1 ) {
$cfginfo_hash = getcfginfo();
#
# if #CLOUDINFO_EXPORT# exists, ...
if( $cloudflag == 1) {
$cloudinfo_hash = getcloudinfo();
}
}
foreach my $n (@$nodes ) {
$node = $n;
$inc = $t_inc;
@ -447,7 +473,15 @@ sub makescript {
my $enablesshbetweennodes = enableSSHbetweennodes($node, \%::GLOBAL_SN_HASH, $groups_hash);
my @clients;
my $cfgres;
my $cloudres;
if ( $cfgflag == 1 ) {
$cfgres = getcfgres($cfginfo_hash, $node, \@clients);
if ( $cloudflag == 1 ) {
$cloudres = getcloudres($cloudinfo_hash, \@clients);
}
}
#ok, now do everything else..
#$inc =~ s/#XCATVAR:([^#]+)#/envvar($1)/eg;
#$inc =~ s/#ENV:([^#]+)#/envvar($1)/eg;
@ -462,6 +496,9 @@ sub makescript {
$inc =~ s/#NETWORK_FOR_DISKLESS_EXPORT#/$diskless_net_vars/eg;
$inc =~ s/#INCLUDE_POSTSCRIPTS_LIST#/$postscripts/eg;
$inc =~ s/#INCLUDE_POSTBOOTSCRIPTS_LIST#/$postbootscripts/eg;
$inc =~ s/#CFGMGTINFO_EXPORT#/$cfgres/eg;
$inc =~ s/#CLOUDINFO_EXPORT#/$cloudres/eg;
$inc =~ s/\$ENABLESSHBETWEENNODES/$enablesshbetweennodes/eg;
$inc =~ s/\$NSETSTATE/$nodesetstate/eg;
@ -1699,7 +1736,127 @@ sub getPostbootScripts
return $result;
}
sub getcfginfo
{
my %info = ();
my $tab = "cfgmgt";
my $ptab = xCAT::Table->new($tab);
unless ($ptab) {
xCAT::MsgUtils->message("E", "Unable to open $tab table");
return undef
}
my @rs = $ptab->getAllAttribs('node','cfgserver','roles');
foreach my $r ( @rs ) {
my $node = $r->{'node'};
my $server = $r->{'cfgserver'};
my $roles = $r->{'roles'};
$info{ $server }{clientlist} .= "$node,";
$info{ $node }{roles} = $roles;
}
return \%info;
}
sub getcfgres
{
my $cfginfo_hash = shift;
my $server = shift;
my $clients = shift;
my $cfgclient_list;
my $cfgres;
if( ! ( exists($cfginfo_hash->{$server}) && exists( $cfginfo_hash->{$server}->{clientlist} ) ) ) {
return $cfgres;
}
$cfgclient_list = $cfginfo_hash->{$server}->{clientlist};
chop $cfgclient_list;
$cfgres = "CFGCLIENTLIST='$cfgclient_list'\n";
$cfgres .= "export CFGCLIENTLIST\n";
@$clients = split(',', $cfgclient_list);
foreach my $client (@$clients) {
my $roles = $cfginfo_hash->{$client}->{roles};
#$cfgres .= "hput $client roles $roles\n";
$cfgres .= "HASH".$client."roles='$roles'\nexport HASH".$client."roles\n";
}
return $cfgres;
}
sub getcloudinfo
{
my %info = ();
my $tab = "clouds";
my $ptab = xCAT::Table->new($tab);
unless ($ptab) {
xCAT::MsgUtils->message("E", "Unable to open $tab table");
return undef;
}
my @rs = $ptab->getAllAttribs('name','repository');
foreach my $r ( @rs ) {
my $cloud = $r->{'name'};
my $repos = $r->{'repository'};
$info{ $cloud }{repository} = $repos;
}
$tab = "cloud";
$ptab = xCAT::Table->new($tab);
unless ($ptab) {
xCAT::MsgUtils->message("E", "Unable to open $tab table");
return undef;
}
@rs = $ptab->getAllAttribs('node','cloudname');
my $pre;
my $curr;
foreach my $r ( @rs ) {
my $node = $r->{'node'};
my $cloud = $r->{'cloudname'};
$info{ $node }{cloud} = $cloud;
}
return \%info;
}
sub getcloudres
{
my $cloudinfo_hash = shift;
my $clients = shift;
my $cloudres;
my $cloudlist;
my $repos;
if( @$clients == 0 ) {
return $cloudres;
}
foreach my $client (@$clients) {
my $cloud;
if( defined($cloudinfo_hash) && defined($cloudinfo_hash->{$client}) ) {
$cloud = $cloudinfo_hash->{$client}->{cloud};
}
#$cloudres .= "hput $client cloud $cloud\n";
$cloudres .= "HASH".$client."cloud='$cloud'\nexport HASH".$client."cloud\n";
$cloudlist .="$cloud,";
my $t = $cloudinfo_hash->{$cloud}->{repository};
if( !defined($repos) ) {
$repos = $t;
}
if( defined($repos) && ( $repos != $t && "$repos/" != $t && $repos != "$t/" ) ) {
xCAT::MsgUtils->message("E", "Two cloud repositories: $repos and $t.\n There should be only one cloud repository one ont chef-server.");
return undef;
}
}
chop $cloudlist;
$cloudres = "REPOSITORY='$repos'\nexport REPOSITORY\nCLOUDLIST='$cloudlist'\nexport CLOUDLIST\n$cloudres";
return $cloudres;
}
1;