Hi all,
I'm struggling with the 'right' design for #1232[1]. The solution is
relatively straightforward -- the client needs a different directory
than the server.
The bug is symptomatic of larger problems, though. I'm going to try
to explain this, but I didn't do so hot in my attempt to do so on the
phone with Andrew, so bear with me. If anyone thinks I'm being
unnecessarily complex, then please say so; I'd love this to get
easier. My goal here is to figure out the right long-term direction;
for this bug, I'm likely to just do the easy, short-term fix, since I
think the long-term solution will require multiple iterations to get
right.
I'm considering adding a new concept to the settings, or possibly
something that sits above the settings. This would be something like
an execution context, which would allow selection from among a set of
defaults, and would also make it easy for code to make decisions based
on the context.
At its simplest, the problem is this: Different executables don't
just behave differently, they operate on different assumptions. For
instance, puppetd runs as root but puppetmasterd runs as puppet, and
puppetd sends reports, but puppet does not. In addition, the
different executables might need different settings: E.g., the master
uses --masterport for the mongrel non-ssl port, but puppetd uses it
for the pound port running ssl (i.e., the master might use 8000 but
the client still uses 8140).
Even more complicated, you might want the same executable to behave
differently in different contexts, such as puppet running as root vs.
as a normal user (using /etc/puppet or ~/.puppet, respectively).
The way Puppet has traditionally "solved" this problem is by selecting
based on executable name. If you look around the code, you'll see
about 8 places that use the executable name (as stored in
Puppet[:name]) to make some decision.
The main problem with this is that's it's poor semantics: The name of
the executable isn't inherently the bit-flip to change behaviour, in
that we might have multiple executables that all have the same
assumptions and need the same context. Anyone who's tried to write a
simple ruby script that needed settings from the 'puppetmasterd'
section of puppet.conf have probably wondered why on earth they needed
to set 'Puppet[:name] = puppetmasterd'.
Here's a snippet from the webrick server class:
if Puppet[:name] == "puppetmasterd"
file = Puppet[:masterhttplog]
else
file = Puppet[:httplog]
end
This demonstrates the crappy current state: We've got two unrelated
defaults defined, and then some low-level plumbing code chooses the
right one based on the executable name. This is the "simple" solution
that I'm probably going to use for the bug fix, but it's clearly a
worrying long-term trend.
This seems related to the need to choose different defaults for
different platforms. Linux boxes generally want to follow the LSB,
but Solaris and OS X definitely don't. The current solution is to
ship around custom config files, but that gets really messy if someone
replaces this custom config with one that doesn't have these
overrides; a *lot* of the ssl problems people have are exactly because
of this problem.
I expect the right solution is to continue with the settings the way
they are now, but then allow the definition of contexts. These would
override the defaults. For instance, here's what a simplistic version
might look like:
Puppet.settings.newdefaults(:main,
:vardir => ["/var/puppet", "Some docs"],
:confdir => ["/etc/puppet", "Good docs"],
:user => "root"
)
Puppet.settings.newcontext(:lsb,
:vardir => "/var/lib/puppet"
)
Puppet.settings.newcontext(:server,
:user => "puppet"
)
You'd obviously need to be able to set multiple contexts at once, but
at least for now we could just fail if they conflict in any way,
rather than worrying about ordering them.
The contexts would also need to be supported by the config file, so
you could have a 'server' section in addition to your 'puppetmasterd'
section -- the executable name would be more specific than the context.
You'd still need some way to set which contexts should run. The
executables themselves would probably all need to specify a context
manually -- that's the simplest -- but we'd probably need some kind of
core context selector that set OS-dependent contexts.
On a related note, I've recently realized that the settings class
exposes too much information -- 9/10s of the settings are just a means
of not hard-coding information, and they shouldn't actually be exposed
to the user. I think it's time to go through the settings and mark
them specially, so that people aren't forced to look at this huge list
of settings, when they really only ever need to tune a few of them.
Any comments? Any easier ways of looking at the world?
1 - http://reductivelabs.com/redmine/issues/show/1232
--
If you're not part of the solution, you're part of the precipitate.
-- Henry J. Tillman
---------------------------------------------------------------------
Luke Kanies | http://reductivelabs.com | http://madstop.com
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Puppet Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/puppet-dev?hl=en
-~----------~----~----~----~------~----~------~--~---