Re: General questions and problems with exec...

Luke Kanies
Mon, 09 Oct 2006 20:45:55 -0000

> Hi,
>
> I''m in the process of evaluating puppet and cfengine for a rollout
on
> a mix of in-house servers and managed customer servers. I''ve
always
> been a pro-cfengine man, and it''s already running on a small setup
of
> 5 machines. But even though I have pretty clear idea of how I should
> proceed building the system, I''m intimidated by the vast amount of
> redundant lines of code I need to write to get the system to the
> state where I want it.
>
> In enters puppet. I noticed it''s existence when Luke announced it
and
> immediately thought: "Oh no, not another tool to solve the same
> problem!" Sorry Luke! After looking more thouroughly on it, and
> trying it out, I''m convinced that you have done a really good job
of
> addressing the shortcomings of cfengine. Right now I''m trying it
out
> on a single host, moving to multihost testing soon.

Great, glad to hear it.

> But before I take that step, I want to see that puppet can accomplish
> some more of the tasks that I need this tool to do:
>
> 1. Security updates on a specific time of the day. I think I can do
> this with:
>
> schedule { maintenance:
>      range => "6:30 - 8:30"
> }
>
> and set this schedule on every package definition I make:
>
> package { foo:
> 	ensure => latest,
> 	schedule => maintenance
> }

Yes, that is correct.

> But I also want to be able to do initial host installs any time of
> the day, and have puppet install all the packages required for the
> host to fulfill it''s purpose. Can I do this with tagging, or...?

During installs, just start puppetd with --ignoreschedules.  This will
cause it to, well, ignore schedules.  In other words, all objects will
run, whether they match their schedule or not.

> 2. Do puppet have any feature that resembles cfengines SplayTime
> function?

It does not, although it could be added relatively easily.  I decided
against implementing it because it has such a negative impact on
usability -- e.g., every time you need to run cfagent, you have to
disable splaytime, and it affects even smaller sites that won''t have
performance problems.

Instead, Puppet relies on the fact that puppetd is a long-running
daemon, and each of your daemons will tend to start at slightly
different times, and they will thus tend to spread their load over the
run interval.

I''ve thought about other mechanisms for providing something load
balancing, such as a simple method to check the load on the server and
have clients automatically throttle back on high load, but until I start
hearing performance complaints I''m not going to bother.

> 3. I''m using shorewall on my servers, and want to be able to make
a
> rules file out of several files. For that I''m using puppet to
> distribute the files, and make to assemble them into a rules file.
> After copying the separate files with puppet, I''m using exec to
run
> the make part - but I can''t get it to work. Here''s the
.pp file:
>
> <snip>
> class shorewall {
>      package { shorewall:
> 	ensure 		=> latest
>      }
>      file { "/etc/shorewall/rulefiles":
> 	ensure		=> directory,
> 	mode		=> 750
>      }
>      configfile { "/etc/shorewall/shorewall.conf":
> 	mode		=> 0640,
> 	source		=> "config/apps/shorewall/shorewall.conf",
> 	require		=> package["shorewall"]
>      }
>      configfile { "/etc/shorewall/Makefile":
> 	source		=> "config/apps/shorewall/Makefile",
> 	require		=> package["shorewall"]
>      }
>      configfile { "/etc/shorewall/rulefiles/":
> 	mode		=> 0640,
> 	source		=> "config/apps/shorewall/rulefiles/",
> 	recurse		=> inf,
> 	require		=> package["shorewall"]
>      }
>      configfile { "/etc/shorewall/infaces":
> 	mode		=> 0640,
> 	source		=> [
> 	    "config/apps/shorewall/infaces.$host",
> 	    "config/apps/shorewall/infaces"
> 	],
> 	require		=> package["shorewall"]
>      }

I recommend creating a definition for this, since it''s a repeating
pattern:

     define swconfig {
         configfile { "/etc/shorewall/$name":
             mode        => 0640,
             source      => [
                 "config/apps/shorewall/$name.$host",
                 "config/apps/shorewall/$name"
             ]
         }
     }

Note I got rid of the require; you''ll need that before you install the
rules, but not to copy the files down.

Then you can just use that:

     # Call the swconfig with no attributes
     swconfig { [infaces, zones, policy]: }

Instead of all the different calls to ''configfile'' you
have.
>      exec { make:
>          path		=> "/usr/bin",
> 	cwd		=> "/etc/shorewall/",
> 	subscribe	=> file["/etc/shorewall/rulefiles/"],
> 	require		=> file["/etc/shorewall/Makefile"],
> 	refreshonly	=> true
>      }
> }
>
> <snap>
>
> And the Makefile:
>
> <snip>
> RULEFILES       := $(shell ls /etc/shorewall/rulefiles/*.rules)
>
> all: rules
>
> rules: $(RULEFILES)
>          @echo "Updating rules file..."
>          @cat $(CONFDIR)/rulefiles/*.rules > rules
>
> <snap>

Where is CONFDIR set?

> Apparently the exec part runs as it should, but it results in an
> empty rules file. And I can''t see why. If I run make manually in
/etc/
> shorewall, the rules file is created correctly. I hope someone can
> shed some light on where I''ve done wrong.

Is it possible that CONFDIR is set in your shell environment, but make
doesn''t know what that directory is when it is run out of Puppet?

> And once again, Luke, you''ve done a great job with puppet!

Thanks. :)

--
I do not feel obliged to believe that the same God who has endowed us
with sense, reason, and intellect has intended us to forgo their use.
                 -- Galileo Galilei