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
-~----------~----~----~----~------~----~------~--~---

Reply via email to