diff --git a/xCAT-OpenStack/lib/perl/xCAT/Cloud.pm b/xCAT-OpenStack/lib/perl/xCAT/Cloud.pm new file mode 100644 index 000000000..171b7ad4b --- /dev/null +++ b/xCAT-OpenStack/lib/perl/xCAT/Cloud.pm @@ -0,0 +1,158 @@ +# IBM(c) 2013 EPL license http://www.eclipse.org/legal/epl-v10.html +package xCAT::Cloud; + +BEGIN +{ + $::XCATROOT = + $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} + : -d '/opt/xcat' ? '/opt/xcat' + : '/usr'; +} +use lib "$::XCATROOT/lib/perl"; +use xCAT::Table; +use xCAT::MsgUtils; +use xCAT::NodeRange; +use xCAT::Utils; +use xCAT::TableUtils; +#use Data::Dumper; +use strict; + + + +#----------------------------------------------------------------------------- + +=head3 getcloudinfo + + This function will be invoked by Postage.pm. + get the chef cookbook repository for each cloud from the clouds table, and + then get all the node --> cloud from the cloud table. The two type information + will be stored in the %info + + If success, return the \%info. + + + Arguments: + none + Returns: + \%info + + Error: + none + Example: + + Comments: + none + +=cut + +#----------------------------------------------------------------------------- + + +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; + + + +} + + +#----------------------------------------------------------------------------- + +=head3 getcloudres + + This function will be invoked by Postage.pm. And it's only for one chef-server. + 1. get the chef cookbook repository for the clouds on one chef-server. + All the clouds's repositoryies on one chef-server should be the same one. + 2. get the cloud list for one chef-server + 3. get the cloud name for each node on the same chef-server + + + Arguments: + $cloudinfo_hash -- This is from the getcloudinfo function. + $clients -- an array which stores different cloud nodes(chef-client) + Returns: + $cloudres -- a string including cloud information + + Error: + none + Example: + + Comments: + none + +=cut + +#----------------------------------------------------------------------------- + + + +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"; + if ( $cloudlist !~ $cloud ) { + $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; diff --git a/xCAT/postscripts/loadchefdata b/xCAT-OpenStack/postscripts/loadclouddata similarity index 95% rename from xCAT/postscripts/loadchefdata rename to xCAT-OpenStack/postscripts/loadclouddata index 41e525314..5e27bd25d 100755 --- a/xCAT/postscripts/loadchefdata +++ b/xCAT-OpenStack/postscripts/loadclouddata @@ -1,7 +1,7 @@ #!/bin/sh # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html -# This script, ("loadchefdata"), is a sample xCAT post script for +# This script, ("loadclouddata"), is a sample xCAT post script for # upload the openstack-cookbooks, roles, enviornment to the # xCAT chef-server node, and then create the chef-client # nodes, and then assign the role and environment name to the @@ -21,12 +21,24 @@ # could set the "postbootscripts" attribute of the chef-server node # definitions as follows: # -# chdef -t node -o chef-server postbootscripts="mountinstall,loadchefdata" +# chdef -t node -o chef-server postbootscripts="mountinstall,loadclouddata" # -# load shell hash lib -source ./hashlib.sh +## defined HASH functions here +hput() { + eval "HASH""$1""$2"='$3' +} + +hget() { + eval echo '${'"HASH$1$2"'}' +} + +hkeys() { + set | grep -o "^HASH${1}[[:alnum:]]*=" | sed -re "s/^HASH${1}(.*)=/\\1/g" +} + + #flags no_args=0 diff --git a/xCAT-OpenStack/templates/mypostscript/mypostscript_cloud.tmpl b/xCAT-OpenStack/templates/mypostscript/mypostscript_cloud.tmpl new file mode 100644 index 000000000..1a1554069 --- /dev/null +++ b/xCAT-OpenStack/templates/mypostscript/mypostscript_cloud.tmpl @@ -0,0 +1 @@ +#CLOUDINFO_EXPORT# diff --git a/xCAT-OpenStack/xCAT-OpenStack.spec b/xCAT-OpenStack/xCAT-OpenStack.spec index 363a5935a..51b064f06 100644 --- a/xCAT-OpenStack/xCAT-OpenStack.spec +++ b/xCAT-OpenStack/xCAT-OpenStack.spec @@ -29,20 +29,36 @@ management. %install mkdir -p $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_schema mkdir -p $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_plugin +mkdir -p $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT +mkdir -p $RPM_BUILD_ROOT/install/postscripts +mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/xcat/templates cp -a lib/perl/xCAT_schema/* $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_schema find $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_schema -type d -exec chmod 755 {} \; find $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_schema -type f -exec chmod 644 {} \; cp -a lib/perl/xCAT_plugin/* $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_plugin +chmod 644 $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_plugin/* -ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/sbin/makeclouddata +cp -a lib/perl/xCAT/* $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT +chmod 644 $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT/* + + +#ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/sbin/makeclouddata + +#cd - +cp -a postscripts/* $RPM_BUILD_ROOT/install/postscripts +chmod 755 $RPM_BUILD_ROOT/install/postscripts/* + +cp -a templates/mypostscript/* $RPM_BUILD_ROOT/%{prefix}/share/xcat/templates +chmod 644 $RPM_BUILD_ROOT/%{prefix}/share/xcat/templates/* %clean rm -rf $RPM_BUILD_ROOT %files %{prefix} +/install/postscripts %defattr(-,root,root) diff --git a/xCAT-server/lib/perl/xCAT/Postage.pm b/xCAT-server/lib/perl/xCAT/Postage.pm index 4970f81c1..96c4699c3 100644 --- a/xCAT-server/lib/perl/xCAT/Postage.pm +++ b/xCAT-server/lib/perl/xCAT/Postage.pm @@ -223,6 +223,11 @@ sub makescript { #First load input into memory.. while (<$inh>) { my $line = $_; + + if( $line =~ /#INCLUDE:[^#^\n]+#/ ) { + $line =~ s/#INCLUDE:([^#^\n]+)#/includetmpl($1)/eg; + } + if ($line !~/^##/ ) { $t_inc.=$line; } @@ -241,14 +246,11 @@ sub makescript { } } + if( $line =~ /#CFGMGTINFO_EXPORT#/ ) { $cfgflag = 1; } - if ($cfgflag == 1) { - if( $line =~ /#CLOUDINFO_EXPORT#/ ) { - $cloudflag = 1; - } - } + } close($inh); @@ -347,20 +349,25 @@ sub makescript { my $cfginfo_hash; my $cloudinfo_hash; + $cfginfo_hash = getcfginfo(); # - # if #CFGCLIENTLIST_EXPORT# exists, ... - if( $cfgflag == 1 ) { - $cfginfo_hash = getcfginfo(); - # - # if #CLOUDINFO_EXPORT# exists, ... - if( $cloudflag == 1) { - $cloudinfo_hash = getcloudinfo(); - - } + #check it the cloud module exists or not + #the default doesn't exist. + my $cloud_exists = 0; + my $cloud_module_name="xCAT::Cloud"; + eval("use $cloud_module_name;"); + if (!$@) { + $cloud_exists = 1; + if( $cfgflag == 0) { + my $rsp; + $rsp->{errorcode}->[0]=1; + $rsp->{error}->[0]="xCAT-OpenStack needs the tag #CFGMGTINFO_EXPORT# in $tmpl.\n"; + $callback->($rsp); + return; + } + $cloudinfo_hash = getcloudinfo($cloud_module_name, $cloud_exists); } - - - + foreach my $n (@$nodes ) { $node = $n; $inc = $t_inc; @@ -476,12 +483,11 @@ sub makescript { my @clients; my $cfgres; my $cloudres; - if ( $cfgflag == 1 ) { - $cfgres = getcfgres($cfginfo_hash, $node, \@clients); - if ( $cloudflag == 1 ) { - $cloudres = getcloudres($cloudinfo_hash, \@clients); - } + $cfgres = getcfgres($cfginfo_hash, $node, \@clients); + if ( $cloud_exists == 1 ) { + $cloudres = getcloudres($cloud_module_name, $cloud_exists, $cloudinfo_hash, \@clients); } + #ok, now do everything else.. #$inc =~ s/#XCATVAR:([^#]+)#/envvar($1)/eg; #$inc =~ s/#ENV:([^#]+)#/envvar($1)/eg; @@ -1788,75 +1794,75 @@ sub getcfgres 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 $module_name = shift; + my $cloud_exists = shift; + my $result; + + #get cloud info + if ( $cloud_exists ) { + no strict "refs"; + if (defined(${$module_name."::"}{getcloudinfo})) { + $result=${$module_name."::"}{getcloudinfo}(); + } } - my @rs = $ptab->getAllAttribs('name','repository'); + return $result; +} - 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 $module_name = shift; + my $cloud_exists = shift; 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; + my $clients = shift; + my $result; + + #get cloud res + if ( $cloud_exists ) { + no strict "refs"; + if (defined(${$module_name."::"}{getcloudres})) { + $result=${$module_name."::"}{getcloudres}($cloudinfo_hash, $clients); + } + } + return $result; } +## +# +#This function only can be used for #INCLUDE:filepath# in mypostscript.tmpl . +#It doesn't support the #INCLUDE:filepath# in the new $file. So it doesn't +#support the repeated include. +#It will put all the content of the file into @text excetp the empty line +sub includetmpl +{ + my $file = shift; + my @text = (); + + if ( ! -r $file ) { + return ""; + } + + open(INCLUDE, $file) || \return ""; + + while () + { + chomp($_); #remove newline + s/\s+$//; #remove trailing spaces + next if /^\s*$/; #-- skip empty lines + if (/^@(.*)/) + { #for groups that has space in name + my $save = $1; + if ($1 =~ / /) { $_ = "\@" . $save; } + } + push(@text, $_); + } + + close(INCLUDE); + + return join(',', @text); +} + + + 1; diff --git a/xCAT/postscripts/hashlib.sh b/xCAT/postscripts/hashlib.sh deleted file mode 100755 index 78fb47c9e..000000000 --- a/xCAT/postscripts/hashlib.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -## defined HASH functions here -hput() { - eval "HASH""$1""$2"='$3' -} - -hget() { - eval echo '${'"HASH$1$2"'}' -} - -hkeys() { - set | grep -o "^HASH${1}[[:alnum:]]*=" | sed -re "s/^HASH${1}(.*)=/\\1/g" -} - -