Re: [Puppet-dev] Facter OS support
Luke Kanies <luke <at> madstop.com>
2005-12-30 17:04:36 GMT
On Wed, 28 Dec 2005, Daniel Clark wrote:
> Hi, I'm starting to look into doing a test puppet deployment at my site. We
> support pretty much all of the major commercial Unix operating systems going
> back several versions (except for HP-UX), plus Debian GNU/Linux and several
> one-offs (my least favorite being Data ONTAP -- no normal command line,
> can't install code on it, grrrr...). Of these AIX is the most widely used
> (esp. for important commercial apps), which leads me to my first problem: no
> AIX support in facter yet.
Yeah, I don't have any AIX machines, so no AIX support yet.
Before I get too much further in this, I should mention that I think
Facter's long-term future is to be written in C, so that other languages can
use it. In fact, based on looking at libmetrics (which is part of ganglia)
I could see a 'fact' library capable of collecting configuration facts (like
Facter does) and metrics (which are just a different kind of fact).
If you look at metrics collection in most tools, you have the same level of
code duplication that I am trying to avoid in developing Facter, and metrics
are just a name ("load", "user cpu") and a value, so it's not much
At the very least, it would probably make sense to have a single framework
capable of organizing facts and fact resolution mechanisms, and then have
two libraries of such resolution mechanisms, one for facts and one for
metrics. Again, this should all be in a compiled form, probably C
unfortunately, so that other languages can use it.
> It looks like adding it using the current framework would be pretty easy,
> but putting what amounts to a bunch of shell commands in a separate ruby
> file seems suboptimal, and a sort of arbitrary distinction between operating
> systems. Also seeing as Luke is unlikely to ever have access to every
> platform that people want to use puppet on, it would seem to make sense to
> break out facter so that different people can be responsible for the "facts"
> of different operating systems -- and also so there can be some code
> separation, so someone messing up the way one OS works can't damage other OS
I don't think there will be a clean association between facts and OSes in
the long term, and I'm especially hesitant to hard-code such a distinction
based on responsibilities.
It's also worth noting that many facts will have multiple resolution
mechanisms, some of which will be os-specific and others not. For instance,
retrieving the domain name on a given system might start with looking in
specific files like /etc/domainname but end in doing DNS lookups of the host
name and IP address. The earlier resolution mechanisms are OS-specific but
not the later ones, so how would that work in your plan?
> What would people would think of an alternative structure along these lines?
> (1) A canonical list of facts that should be available and the format they
> should be in is created (i.e. a standards/how-to-port document). Ideally
> this would eventually be auto-generated from the below code, and include
> sample output from all operating system/version tuples ported thus far.
While I think there _should_ be a minimum list of facts, I want Facter to
always be able to be expanded. I'd like individual organizations to be able
to add their own facts (things like service level -- production,
development, etc. -- and data center are facts most companies care about but
will never be standardized), and some platforms will just have more
information available than others.
I do think that the Facter library could be written to be much more
generated than hand-coded, though, so I like that idea.
> (2) facter.rb contains only enough logic to figure out the first level of
> the machine (i.e. the output of `uname`) and call "os/`uname`.rb" (and also
> serve as the communications interface to puppet et al)
I began Facter with per-os restrictions on Facts, but I've moved to just
tagging facts with restrictions. Right now, I don't think there are any
facts that are tagged in any way other than OS and OS rev, but in the long
term, I know there will be. I'm pretty uncomfortable with having that hard
line requiring that all facts be global or per-OS, as I don't think it will
scale in the long term. It also means that for facts that are duplicated
across groups of platforms, like all BSDs or all SysV OSes, they either have
to be global or per-os, which isn't OK.
> (3) "os/`uname`.rb" contains only enough logic to figure out the second
> level of the machines (i.e. OS version, depending on the OS some uname
> command, oslevel, or perhaps other things...) e.g. "os/aix-4.3.3.rb". I
> think we can assume that a single person can handle a single OS version,
> although it might make sense to make it general enough if there really is
> some case where a OS patch dramatically changed the output format of some
> command (has anyone seen this happen in real life?).
> (4) Facts can then be determined either via a ruby file, or perhaps via a
> YAML .yml file that just lists the right shell commands to run to get the
> facts outlined in (1), along with a ruby file used only for getting facts
> via native ruby commands and reading/including the .yml file (simplest case
> this would just be a template file that calls some function that parses the
> .yml file). If the YAML file was used it would make it easy for people with
> zero Ruby knowledge to do "ports" to new operating system/version tuples --
> and it also might increase the usefulness of facter to other projects not
> coded in Ruby.
I'm not sure what yaml gets us here; can you explain that in more detail?
The main role Ruby has here is in munging the output of shell commands or in
munging files, since those are basically the only ways I'm retrieving facts
right now. I could certainly see using shell commands to do that same
munging, so I could see a Facter library written in C with each fact defined
in an easily parsed file containing all of the different fact resolution
mechanisms along with the appropriate tags. That would, at least,
completely separate the library and its interface from the resolution
mechanisms (which is kind of done in the current implementation, but it's
all in one file), but it would limit resolution mechanisms to being in shell
code, which won't work for all facts; particularly, metrics will often
require C library calls.
> This would also solve one of my quibbles with cfengine, that being that the
> complete list of classes that are available are not (at least the last time
> I checked) available anywhere except for the source code. Using YAML or some
> doc tool it would be possible to make the code autogenerate the doc
> regarding what facts are available.
This documentation should be available, but I'm not sure this is a
sufficient reason to push everything into yaml or whatever.
It wouldn't be difficult to add more introspective capabilities into either
the Facter library or the 'facter' executable. You can currently easily get
a list of all facts for the current system, but it wouldn't be hard to make
it easy to get a list of all defined facts for any platform along with maybe
a list of those facts that don't have values for the current platform.
> FYI below is a listing of the output of the shell commands I saw in
> facter.rb for the various operating systems I care most about, plus the
> output of oslevel for AIX (I don't know the history but for some reason AIX
> doesn't display it's version number via uname in the way you would expect,
> or in a way that gets you all the information you need, at least for
> versions like 4.3.x where the .x matters)
Yeah, I noticed this when I was using AIX. For AIX, you'd have to define
another fact retrieval mechanism for OperatingSystemRelease and tag it with
'aix', so that it had precedence over the normal one.
> dcca2302 <at> rook:~/svn-work/reductivelabs-svn/facter/trunk/lib$ dsh -g puppet
> -- "(echo \-s = ; uname -s ; echo \-r = ; uname -r ; echo \-m = ; uname -m ;
> echo hostid = ; hostid ; echo \-p = ; uname -p ; echo oslevel = ; if [ -x
> /bin/oslevel ]; then /bin/oslevel; fi) | xargs echo" 2>&1 | sort
> aix433: -s = AIX -r = 3 -m = 0001838F4C00 hostid = 0x9218c87 -p = oslevel =
> aix433: Usage: uname [-snlrvmaxuMS:T:]
> aix433: uname: Not a recognized flag: p
> aix52: -s = AIX -r = 2 -m = 0001830F4C00 hostid = 0x9218c1a -p = powerpc
> oslevel = 22.214.171.124
> aix53: -s = AIX -r = 3 -m = 00CE3D3E4C00 hostid = 0x9218a57 -p = powerpc
> oslevel = 126.96.36.199
Are you willing to modify Facter to have these resolution mechanisms and
send me a diff, just to get AIX support right away? I do think something
needs to be done in the long term, but until we figure out what that is, I'd
like to continue adding support for other OSes.
What is the sound of Perl? Is it not the sound of a wall that
people have stopped banging their heads against?
--Larry Wall in <1992Aug26.184221.29627 <at> netlabs.com>
Luke Kanies | http://reductivelabs.com | http://madstop.com