move out the code to read cloud/clouds table from Postage.pm to Cloud.pm in xCAT-OpenStack. Move out the loadchefdata script.

This commit is contained in:
jjhua 2013-10-23 22:41:15 -04:00
parent 50a853c96e
commit 4e59b13e0f
5 changed files with 249 additions and 313 deletions

View File

@ -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;

View File

@ -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 (<INCLUDE>)
{
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;

View File

@ -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"
}

View File

@ -1,212 +0,0 @@
#!/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
# 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
# chef-client nodes
#
# Make sure your script is executable and that is is in the
# /install/postscripts directory on the xCAT management node.
#
# You must add the script name to the list of scripts that
# must be run at install time, or use it with updatenode.
#
# To use this script you should make sure it gets run after the
# "mountinstall" script or any other scipts that may need to use
# scripts in the /install directory.
#
# For example, to get it to run after the "mountinstall" script you
# could set the "postbootscripts" attribute of the chef-server node
# definitions as follows:
#
# chdef -t node -o chef-server postbootscripts="mountinstall,loadchefdata"
#
# load shell hash lib
source ./hashlib.sh
#flags
no_args=0
only_load_cookbook=0
only_load_role=0
only_load_clouddata=0
if [ $# -eq 0 ]
then
no_args=1
else
for arg in "$@"
do
if [ "$arg" = "--cookbook" ]
then
only_load_cookbook=1
elif [ "$arg" = "--role" ]
then
only_load_role=1
elif [ "$arg" = "--clouddata" ]
then
only_load_clouddata=1
else
errmsg="no argument $arg in the loadchefdata script"
logger -t xcat -p local4.err $errmsg
echo $errmsg
exit 1
fi
done
fi
# enter the repository director
# for example: cd /install/chef-cookbooks/grizzy-xcat/
if [ ! -d "$REPOSITORY" ]
then
errmsg="$REPOSITORY is not a OpenStack Chef cookbooks directory."
logger -t xcat -p local4.err $errmsg
echo $errmsg
exit 1
fi
cd $REPOSITORY
if [ $no_args -eq 1 -o $only_load_cookbook -eq 1 ]
then
# upload coobooks
knife cookbook bulk delete '.*' -y > /dev/null 2>&1
knife cookbook upload -o cookbooks --all
if [ $? != 0 ]
then
errmsg="Failed to run knife cookbook upload -o cookbooks --all on the chefserver $NODE."
logger -t xcat -p local4.err $errmsg
echo $errmsg
exit 1
fi
fi
if [ $no_args -eq 1 -o $only_load_role -eq 1 ]
then
# upload roles
knife role bulk delete '.*' -y > /dev/null 2>&1
knife role from file roles/*.rb
if [ $? != 0 ]
then
errmsg="Failed to run knife role from file roles/*.rb on the chefserver $NODE."
logger -t xcat -p local4.err $errmsg
echo $errmsg
exit 1
fi
fi
if [ $no_args -eq 1 -o $only_load_clouddata -eq 1 ]
then
if [ -z $CFGCLIENTLIST ]
then
msg="No cfgclient on the cfgserver $NODE?"
logger -t xcat -p local3.info $msg
echo $errmsg
exit 0
fi
#CLOUDLIST='cloud1,cloud1,cloud3'
OIFS=$IFS
IFS=','
for cloud in $CLOUDLIST
do
echo "loading the enviornment file $cloud.rb for $cloud"
# knife environment delete xcat_per-tenant_routers_with_private_networks -y
# knife environment delete xcat_per-tenant_routers_with_private_networks -y
# load the environment file
# knife environment from file environments/xcat_per-tenant_routers_with_private_networks.rb
if [ ! -e "$REPOSITORY/environments/$cloud.rb" ]
then
errmsg="$REPOSITORY/environments/$cloud.rb doesn't exsit. run mkclouddata at first."
logger -t xcat -p local4.err $errmsg
echo $errmsg
exit 1
fi
knife environment from file environments/$cloud.rb
if [ $? != 0 ]
then
errmsg="Failed to run knife environment from file environments/$cloud.rb on the chef-server $NODE."
logger -t xcat -p local4.err $errmsg
echo $errmsg
exit 1
fi
done
#IFS=$OIFS
#CFGCLIENTLIST='node1,node1,node3'
#OIFS=$IFS
#IFS=','
for client in $CFGCLIENTLIST
do
echo "Configuring the chef-client node $client on the chef-server $NODE."
c_fullname="$client.$DOMAIN"
knife client delete -y $c_fullname > /dev/null 2>&1
knife node delete -y $c_fullname > /dev/null 2>&1
#create nodes on this chef-server
# knife node create test3 -d
knife node create $c_fullname -d
if [ $? != 0 ]
then
errmsg="Failed to run knife node create $client -d on the chef-server $NODE."
logger -t xcat -p local4.err $errmsg
echo $errmsg
exit 1
fi
roles=`hget $client roles`
if [ -z $roles ]
then
errmsg="No roles for $client. Please check the cfgmgt table."
logger -t xcat -p local4.err $errmsg
echo $errmsg
exit 1
fi
# assign the role for the chef node
knife node run_list add $c_fullname "role[$roles]"
if [ $? != 0 ]
then
errmsg="Failed to run knife node run_list add $client 'role[$roles]' on the chef-server $NODE."
logger -t xcat -p local4.err $errmsg
echo $errmsg
exit 1
fi
# assign the new environment to the chef client node
newenv=`hget $client cloud`
if [ -z $newenv ]
then
errmsg="No cloud for $client. Please check the cloud table."
logger -t xcat -p local4.err $errmsg
echo $errmsg
exit 1
fi
origenv=`knife node show $c_fullname -E | sed -e 's/[ ]*//g'| awk -F: '{print $2}'`
EDITOR="sed -e s/$origenv/$newenv/ -i" knife node edit $c_fullname
if [ $? != 0 ]
then
errmsg="Failed to run knife node edit $client on the chef-server $NODE."
logger -t xcat -p local4.err $errmsg
echo $errmsg
exit 1
fi
done
fi
IFS=$OIFS
exit 0

View File

@ -19,7 +19,7 @@
# 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"
#