Back before the 'packages:' action had an install option (~2 years ago), when it could only define classes, I wrote a simple[-minded?] perl wrapper that would parse the list of defined classes and hand off to yum. I'm still using it because it's been stable, avoids limitations like this argument length limit, and offers us some additional features, like the ability to use team-private rpm repos, and to [forcibly] remove rpms. FWIW, it's attached, and obviously YMMV, and, it could be much simplified if you have no need to refer to different repos (use at your own risk, disclaimer, disclaimer...) Here's how it might be used:

packages:
# Define classes to be interpreted by called function, yw5.
# Prefix these rpm-related classes with 'needs_'
# Use 'needs_<rpmname>' to install from common yum repository
# Use 'needs_NOT_<rpmname>' to remove an rpm (always handled first)
# Use 'needs_<teamname>_<rpmname>' to specify a team specific yum repository # Because cfengine class names can't contain some characters, use these substitutions:
#   hyphen in rpmname should be '__' in class name
#   period in rpmname should be '___' in classname
#   '++' in rpmname should be '____' in classname

 any::
   krb5-libs           elsedefine=needs_krb5__libs
   netdiag             elsedefine=needs_netdiag
   ntp                 elsedefine=needs_ntp

shellcommands:
  rpm::   #(shellcommands.rpm is early in actionsequence)
"/var/cfengine/modules/yw5 $(AllClasses) $(rpmserver)" inform=false ifelapsed=0


-Ed


[EMAIL PROTECTED] wrote:
Dear Mark,

It's not a question of how big - someone will always exceed the limit :)
It's the technique employed.  I appreciate you are trying to reuse
secure code by enforcing an arbitrary limit on popen calls but the list itself is
internally constructed and therefore should be considered secure,
_possibly_ bypassing this restriction.  I know that buffer overruns are
a serious problem in secure
software and hence I understand why this limit is in place.

I'll probably get around it by dumping an iterated list to a temporary
file that is constructed on the fly and parsing that to a yum/RPM
command.  Convoluted but
it's questionable whether I should be using cfengine for this task
anyway.
Another option is to use package groups instead but that requires
changes in
my yum/yam repository.

I could easily get around it by recompiling with a 'large enough'
CF_MAXARGUMENTS
but that would likely have other implications (memory and stack usage
primarily).
So I would prefer not to do that unless absolutely necessary.

I was hoping that someone had come across this before but obviously not.
I'll keep you posted.

Thanks for your help.

Best Regards,

Brett

-----Original Message-----
From: Mark Burgess [mailto:[EMAIL PROTECTED] Sent: 14 July 2006 11:58
To: Brett Delle Grazie
Cc: help-cfengine@cfengine.org
Subject: Re: Package installation of RPMs - Too many arguments in
embedded script

[EMAIL PROTECTED] wrote:
Dear Steve,

Thanks for that.  It does appear that it's cfengine imposing the limit

way before it gets anywhere near yum. Looking at the source the issue is in popen.c where it imposes the limit of CF_MAXSHELLARGS (which is set to 30). I can see why this is done (to limit memory/stack usage) but it does break the package

mechanism rather thoroughly.

Best Regards,

Brett

-----Original Message-----
From: Steve Kemp [mailto:[EMAIL PROTECTED]
Sent: 14 July 2006 11:18
To: Brett Delle Grazie
Cc: help-cfengine@cfengine.org
Subject: Re: Package installation of RPMs - Too many arguments in embedded script

On Fri, Jul 14, 2006 at 10:56:40AM +0100, [EMAIL PROTECTED] wrote:

   I'm using Yum so my rpm install command is:
RPMInstallCommand = ( "/usr/bin/yum -y install %s" ) However I'm getting the messages (in verbose mode):
   ... long list of packages ...
   package install: cfengine:build-test: Too many arguments in
embedded
   script
   Does anyone have a work around for this already (i.e. probably
using
   shellcommands)?
  Perhaps something like:

    /bin/echo %s | xargs --max-args 20 /usr/bin/yum -y install \{\} \;

That would split up the package installation to only attempt 20 at a time. Of course then you might have dependency problems if the first 20 packages depend on something to be installed in the next 20
..
Steve


How big do you think this arg list should be to help you out?

--
Mark Burgess

Professor of Network and System Administration Oslo University College

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Work: +47 22453272            Email:  [EMAIL PROTECTED]
Fax : +47 22453205            WWW  :  http://www.iu.hio.no/~mark
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

______________________________________________________________________
This email has been scanned by the MessageLabs Email Security System.
For more information please visit http://www.messagelabs.com/email
______________________________________________________________________

______________________________________________________________________
This email has been scanned by the MessageLabs Email Security System.
For more information please visit http://www.messagelabs.com/email
______________________________________________________________________

_______________________________________________
Help-cfengine mailing list
Help-cfengine@cfengine.org
http://cfengine.org/mailman/listinfo/help-cfengine
#!/usr/bin/perl

##########################################################################
#
# yw5 (yum-wrapper5) - helps integrates package management with cfengine-2
#
#  Run by cfengine from cf.rpm
#
#  Argument: colon-separated list of all defined cfengine classes.
#            Use 'packages:' sections to define rpm-related classes.
#            Classes that start with "needs_" represent rpms needing 
#            some action (install, remove).
#  Example Classes:
#            needs_foo       - install 'foo', from default rpm repository
#            needs_NOT_foo   - uninstall 'foo'
#            needs_ccn5ist_foo - install 'foo' from ccn5ist's repository
#
# Note that:
#  Double underscore in class names = hyphens in rpm names.
#  Dot in rpm name is represented as triple underscore. 
#  '++' in rpm name is represented as four underscores.
#
#  For rpms given in 'packages:' sections w/o a 'team' prefix,
#   use default yum.conf (which uses /var/rpms/<distro> repository) 
#  For rpms given in 'packages:' section WITH a 'team' prefix,
#   use team-specific yum.conf (which gives priority to /var/rpms/<team>/ 
repository)
#
##########################################################################

use strict;
use warnings;
use Getopt::Std;  

#############   Important Global Variables  ###############

my @teams = ();

# key: team name, or "common"
# value: hashref -> key: rpmname; value: not significant (used to eliminate 
dups) 
my %to_install = ();     

my %to_remove = (); # rpms to remove; key: rpmname, value: (again, not 
important) 

our ( $opt_v, $opt_h );  # Boolean options (verbose, and help)

sub usage();

my $debug = 0;

#################    Main    ################

getopts("hv");
if ( @ARGV ne 2 or $opt_h ) { usage() }

@teams = ( "teamA", "teamB", "teamC", "common" );
if ($debug) {print "debug: [EMAIL PROTECTED]: '@teams' \n"}

my $rpmserver = $ARGV[1];  # Correct server passed as arg 2 from cfengine
if ($debug) {print "debug: rpmserver: '$rpmserver'\n"}

# Process the colon separated list of all defined cfengine classes
my $rpmname = "";
CLASS: foreach (split(/:/,$ARGV[0])) {  
        if (/^needs_(.+)/) {    # Select only classes starting with 'needs_'
                $rpmname = $1;  # Strip off 'needs_' prefix
                $rpmname =~ s/____/\+\+/g;  # substitute ++ for ____ 
                $rpmname =~ s/___/\./g;     # substitute . for ___ 
                $rpmname =~ s/__/-/g;       # substitute - for __
                if ($rpmname =~ /^NOT_(.+)/) {  # Select rpms to be removed
                        $rpmname = $1;
                        $to_remove{$rpmname} = 1;  # use hash: eliminate dups
                        next CLASS;
                }
                for my $team (@teams) {   # Look for 'teamname_' prefixes
                        if ( $rpmname =~ /^($team)_(.+)/ ) {
                                $rpmname = $2;
                                $to_install{$team}{$rpmname} = 1;
                                next CLASS;
                        }
                }
                # If no match on team name, assume "common"
                $to_install{"common"}{$rpmname} = 1;
        }
}

my $remove_string = "";
for (keys(%to_remove)) { $remove_string .= " $_" }
if ($remove_string) {
        system "/bin/rpm -e --nodeps  $remove_string";
}
if ($debug) {print"debug: \$remove_string is: '$remove_string'\n"}

my $install_string;
for my $teamname (keys %to_install) {
        if ($debug) {print "debug: teamname: '$teamname'\n"}
        $install_string = "";
        if (defined $to_install{$teamname})  { 
                for (keys %{$to_install{$teamname}})  { 
                        $install_string .= " $_";
                }
                # Use default yum.conf(/etc/yum.conf), installed by cfengine 
                if ($teamname =~ /common/ and $install_string) { 
                        system "/usr/bin/yum -d1 -y  install $install_string";
                }
                # Use team-specific yum.conf (installed by cfengine)
                elsif ( $install_string ) { 
                        system "/usr/bin/yum -d1 -y -c /etc/yum.conf.team 
install $install_string";
                }
        if ($debug) {print "debug: \$teamname: '$teamname'; \$install_string: 
'$install_string'\n"}
        }
}

###################      End Main       ###################


###################     Subroutines     ###################

sub usage ()  {
        print "
NAME 
        yw5  -  yum wrapper, parses cfengine classes to determine 
                rpms to install or remove. 
SYNOPSIS
        yw5 \$(AllClasses)  \$(rpmserver)
                                
DESCRIPTION
        Allows rpm package management (installing and removing rpms) 
        from within cfengine. Classes are defined in cfengine's 'packages:'
        sections, based on cfengine's ability to determine whether 
        rpms are installed or not, and also whether particular versions 
        are installed or not. The yum wrapper script is called once 
        (from 'shellcommands:' in cf.rpm) and passed a string with all 
        defined cfengine classes.

EXAMPLES
        packages:
           !(yellow.MailReceiver)::
                sendmail        elsedefine=needs_sendmail 
                #(install most recent sendmail from default rpm repository)

           yellow.MailReceiver::
                sendmail        elsedefine=needs_teamA_sendmail
                #(install most recent sendmail from teamA's repository)

SEE ALSO
        rpm.cf, yum.conf files, and man pages for yum and yum.conf

BUGS
        Cfengine imposes limitations on classnames.  It is necessary to 
        make certain substitutions in the classnames defined:
         double underscore, '__' for hyphens in rpmnames
         triple underscore, '___' for periods in rpmnames
         four underscores, '____' for '++' in rpmnames
        e.g.:
        packages:
                libstdc++       elsedefine=needs_libstdc____
\n\n";
        exit;
        }   # end of usage() subroutine

_______________________________________________
Help-cfengine mailing list
Help-cfengine@cfengine.org
http://cfengine.org/mailman/listinfo/help-cfengine

Reply via email to