Hi,
Last year I used puppet for my master thesis. I added quite some
features to puppet for this. It has been too long but I finally got
one feature documented and ported to the latest master. The
explanation and some examples are in this email. The code for this is
in github: http://github.com/bartv/puppet/tree/master
Conflict handling
-----------------
Because of Puppet's declarative nature it is impossible to define resources of
the same name if they have the same resource type. Conflict handling introduces
a new metaparameter called 'conflicthandler'. When this parameter is set,
resources with conflicting names do not generate an exception but are handed
off to the conflicthandler referenced in the metaparameter. Because the
conflict handling only happens at the end of the compilation process it only
makes sense to use these conflicthandlers on native resources.
The patch allows new conflicthandlers to be defined like custom functions in
puppet/parser/conflicthandlers Puppet contains one conflicthandler for file
resources. The 'concat' handlers handles the conflict by collecting the content
parameters of all conflicting resources, sorts them and concatenates them. The
sorting is required so only real content changes will case a reconfiguration
instead of different ordering. The 'concat' handler can be used like that file
fragment pattern.
Using the concat conflict manager and file resources a lot of existing native
types can be replaced. The only downside is you can only manage a full file
instead of specific lines or groups of lines. But the only sane way to use
these native resources such as hosts, nagios_*, sshkey, etc is by setting Type
{ purge => true } any way.
example usage
+++++++++++++
# A host entry in /etc/hosts. It replaces the native resource and is functional
# equivalent to the native host type if Host { purge => true } is set.
define host($ip, $alias = "", $ensure = "present", $target = "/etc/hosts") {
case $ensure {
present: {
file {$target:
conflicthandler => "concat",
owner => root,
group => root,
mode => 0644,
content => "$ip $name $alias\n",
}
}
default: {}
}
}
host {"localhost":
ip => "127.0.0.1",
alias => "localhost.localdomain",
}
host {"localhost6":
ip => "::1",
alias => "localhost6.localdomain6",
}
example handler (define in puppet/parser/conflicthandlers/ignore.pp)
+++++++++++++++
This handler just keeps the first one found and ignores the other conflicting
rules.
# ignore conflicting users if they have the same parameters
def are_equal?(one, two)
# TODO
end
class Puppet::Parser::ConflictHandler
self.newconflicthandler("user", "ignore")
conflicts.each do |conflict|
# resource variable contains the resource that was added
to the catalog
raise ArgumentError.new("Conflict!") unless
are_equal?(resource, conflict)
end
end
end
Todo
++++
- add a better api for writing conflicthandlers, especially to work with the
resources
- only allow conflicthandlers on native resources or make them work on
non-native resources. But this can only work IF the conflicting define does
NOT generate any new conflicting defines for the same resource.
gr,
Bart
--
Bart Vanbrabant <[email protected]>
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---