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