From 4e59b13e0f5c9b28427d2db536d99d4c2ef026c2 Mon Sep 17 00:00:00 2001 From: jjhua Date: Wed, 23 Oct 2013 22:41:15 -0400 Subject: [PATCH] move out the code to read cloud/clouds table from Postage.pm to Cloud.pm in xCAT-OpenStack. Move out the loadchefdata script. --- xCAT-OpenStack/lib/perl/xCAT/Cloud.pm | 158 +++++++++++++++++++ xCAT-server/lib/perl/xCAT/Postage.pm | 174 +++++++++++---------- xCAT/postscripts/hashlib.sh | 16 -- xCAT/postscripts/loadchefdata | 212 -------------------------- xCAT/postscripts/mountinstall | 2 +- 5 files changed, 249 insertions(+), 313 deletions(-) create mode 100644 xCAT-OpenStack/lib/perl/xCAT/Cloud.pm delete mode 100755 xCAT/postscripts/hashlib.sh delete mode 100755 xCAT/postscripts/loadchefdata 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-server/lib/perl/xCAT/Postage.pm b/xCAT-server/lib/perl/xCAT/Postage.pm index 2d96b9498..0ff0066df 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" -} - - diff --git a/xCAT/postscripts/loadchefdata b/xCAT/postscripts/loadchefdata deleted file mode 100755 index 41e525314..000000000 --- a/xCAT/postscripts/loadchefdata +++ /dev/null @@ -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 - - - diff --git a/xCAT/postscripts/mountinstall b/xCAT/postscripts/mountinstall index bf8a0fe86..62097e469 100755 --- a/xCAT/postscripts/mountinstall +++ b/xCAT/postscripts/mountinstall @@ -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" #