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) _______________________________________________ Help-cfengine mailing list Help-cfengine@gnu.org http://lists.gnu.org/mailman/listinfo/help-cfengine