help-cfengine
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Patch to add install action to packages:


From: Phil D'Amore
Subject: Re: Patch to add install action to packages:
Date: Thu, 03 Mar 2005 09:36:11 -0500

On Thu, 2005-03-03 at 06:14, David Douthitt wrote:
> Phil D'Amore wrote:
> > On Tue, 2005-03-01 at 14:10, David Douthitt wrote:
> > 
> >>Phil D'Amore wrote:
> >>
> >>>On Mon, 2005-02-28 at 13:27, David Douthitt wrote:
> 
> >>That's where the wrapper comes in.  Use "PkgInstalled" as a function and 
> >>use "PkgInstalledCmd" as an abstraction.  Then you could have this:
> 
> > What do you mean use PkgInstalled as a function.  Where?
> 
> Such as:
> 
>      gccInst = PkgInstalled( gcc )
> 

Ahhh, an evaluated class.  Actually, I tried this originally.  At the
time, the current implementation was more flexible because it allowed
conditional checking for packages.  That is, when originally written,
cfengine would not allow this:

classes:
    checkforgccc::
        fooInst = PkgInstalled( foo )

You could not use class predicates inside classes:.  IIRC that is not an
issue anymore, but it was a limitation at the time.

Additionally, given the situation where you have a number of args to
each item like pkgmgr/action/version/whatever, I find the action syntax
more pleasing to the eye, but that is just my opinion there :).

Plus, like it or not, if the overall interface changed now, it'd
probably break a lot of people.  We can change the guts if that's what
people want, but I'd really like to see the main part of the interface
stay the same, even if a few variables have to change/die in the name of
science or progress or something noble like that.

> >>linux::
> >>   PkgInstalledCmd = ( ReturnsZero("rpm -q %s") )
> >>
> >>solaris::
> >>   PkgInstalledCmd = ( ReturnsZero("pkginfo -x %s") )
> 
> > That would get you a yes or no answer on whether or not *any* version of
> > the package was installed.
> 
> True.
> 
> > What packages: can do, as it exists in cfengine today, is check for a
> > package at a specified version.  That requires parsing of each commands
> > specific output to determine the version, plus do version comparison
> > based on the logic used by that particular package manager.
> 
> Not necessarily.  The RPM command, as given, will work with version 
> numbers as well.  I would also argue against "parsing output" as the 
> output is not guaranteed to remain the same.  For rpm, this command will 
> return the proper value as an exit value:
> 
> rpm -q gcc-3.2.3

Indeed it will.  But, I cannot ask rpm directly to tell me if gcc is
installed, say, at a version equal to *or* greater than a specified
version.  That'd be a really nice feature, though.  When I'm using
version comparison, which honestly isn't very often, I tend to want
that.  I'm willing to bet there are other package managers out there
with the same limitation.

So, yeah you can probably get pretty darn close with such a generic
interface, depending on the package manager, but it'd never be the
same.  I admit for my purposes, I could probably live with it, but
that's just me.  You'd still be limited by a given package manager's
command line query interface, but it is no longer a cfengine detail at
that point.

> 
> > No matter how much it is abstracted once you sit down to write a
> > cfengine config file, somewhere deep in the bowels of cfengine,
> > something has to understand the output of these various commands, in
> > order to detect and deal with differences in version information.
> 
> Not necessarily.  All cfengine really has to understand is how to check 
> for an installed package.  The output should not even be seen; only an 
> exit value.
> 
> The user (or a developer) should be the one who configures cfengine to 
> do what they want.  My idea of abstraction would neither be outside 
> cfengine (as was suggested) nor "deep in the bowels" inside cfengine.
> 
> I'm merely suggesting the use of a set of configuration variables to be 
> set by the user and utilized by cfengine internally.
> 
> >>However.... putting that aside.... There is no reason that your 
> >>scriptlet above could not be done using abstraction contained within 
> >>cfengine.  Something like:
> >>
> >>control:
> >>   rpm.PkgInstall = ...
> >>   rpm.PkgRemove = ...
> >>   sun.PkgInstall = ...
> >>   sun.PkgRemove = ...
> > 
> > 
> > How is that different from the variables which with you originally took
> > issue?  The way I see it, that is the same thing as I originally
> > proposed, sans the .'s of course.
> 
> The difference is that the way you suggested it, it was a "name"; here I 
> am suggesting "rpm" and "sun" would be class names arbitrarily chosen by 
> the user, and later utilized in a command to determine which "class" of 
> packaging to use.
> 
> This, then, allows the user to extend cfengine to handle packaging types 
> not accounted for by the standard installation - and without having to 
> code or recompile cfengine to do it.

OK, I see what you are trying to do there now, but what you propose is
syntactically invalid.  Also, having worked with modifying the parser on
a few occasions, I'd be afraid of what changing the varobj (I think)
token in the lexer to accept dots would do there, and if it would even
be useful.  Perhaps an associative array could do the same thing,
though, without a parser change.  That could more easily allow the
example of multiple package managers on the same machine.

> 
> > It was generic for a reason:  I was trying to illustrate that it won't
> > work.  That example used yum to install the packages, yet I had one
> > check for a RPM package and one check for a native Sun package.  You
> > can't use yum to install a native Sun package (AFAICT from the website -
> > someone correct me if I'm wrong).  So, specifying one install command
> > and querying for the two different types of packages won't work.
> 
> So define multiple versions using classes.
> > DefaultPkgMgr does that already.  My point is that if we go to an
> > environment where we only allow one install command, then we can only
> > install one type of package on a given run of the agent.  If that is
> > abstracted into a wrapper program/library external to cfengine as has
> > been proposed elsewhere in this thread, then cfengine looses control
> > over what to query to that external facility, and any options inside
> > cfengine to specify it are useless at that point.
> 
> I'm not refering to an external library, or to a wrapper program.  I'm 
> refering to telling cfengine how to query packages, etc.  The current 
> method requires a modification of the code to support unknown package 
> managers, to support changes in output, and to support differences even 
> between two implementations of the same package manager (such as with RPM!).

You are referring to Mark's comments about his experience with RPM?  I
don't think it is certain that the implementations of RPM are different
there.  The output he was posting to the list leads me to think they are
the same.  Two bugs were recently found in RPMCheckPackage() which may
have caused this, and I submitted a patch to fix it to the bug list. 
Once Mark has time to test again we will know for sure.

> 
> The evidence of such trouble is evident already in a much simpler area: 
> recognizing operating system versions and releases.  HP-UX 11 had this 
> problem, and the numerous various Linux distributions render this almost 
> impossible to keep up with.  Does cfengine recognize White Box Linux? 
> TinySofa? Enguarde? Vine? Miracle? Red Flag?  And most importantly, can 
> it be made to recognize these variants without recompiling?

Agreed, 100% with you on that one.  The magic string file method would
probably be a workable solution there, then folks would only have to
download the latest magic string file to be updated.  They could even
distribute that through cfengine as well via update.conf.  I still think
there'd have to be some level of detection in code to at least determine
the OS type (Linux, HP-UX, Solaris), since those are reliably obtainable
with uname(), but once that was known, a magic string check could
probably be applied to find specifically what you are dealing with.

> Same for package managers - such as FreeBSD packages, HP-UX software 
> depots, and Slackware archives...
> 
> Granted, recognizing a Linux variant could be (should be?) easier - a 
> "magic string" file like /usr/bin/file uses.
> 
> Perhaps this would be a good place for dynamic code modules?  Or is that 
> branching into too much complexity?

I've had this thought on several occasions.  It might make the code
easier to maintain, but good golly that'd be a lot of runtime linking. 
I'm still not sure how I feel about cfengine doing something like that. 
If it were done in a way that I wasn't having to recompile any 3rd party
modules all the time, it might be kinda cool.  Perhaps people are
already looking at this issue for cfengine 3?

Later,

-- 
Phil D'Amore                             "Sometimes there is a fine line
Senior System Administrator               between criminally abusive
Red Hat, Inc                              behavior and fun."
Office: 919.754.3700 x44395                 -- Ted the Generic Guy
Pager: 877.383.8795                            (Dilbert 4/19/2003)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]