1
require 'puppet/indirector/terminus'
4
# The base class for MessagePack indirection terminus implementations.
6
# This should generally be preferred to the PSON base for any future
7
# implementations, since it is ~ 30 times faster
8
class Puppet::Indirector::Msgpack < Puppet::Indirector::Terminus
10
if ! Puppet.features.msgpack?
11
raise "MessagePack terminus not supported without msgpack library"
17
load_msgpack_from_file(path(request.key), request.key)
21
filename = path(request.key)
22
FileUtils.mkdir_p(File.dirname(filename))
24
Puppet::Util.replace_file(filename, 0660) {|f| f.print to_msgpack(request.instance) }
25
rescue TypeError => detail
26
Puppet.log_exception "Could not save #{self.name} #{request.key}: #{detail}"
30
Puppet::FileSystem.unlink(path(request.key))
32
unless detail.is_a? Errno::ENOENT
33
raise Puppet::Error, "Could not destroy #{self.name} #{request.key}: #{detail}", detail.backtrace
35
1 # emulate success...
39
Dir.glob(path(request.key)).collect do |file|
40
load_msgpack_from_file(file, request.key)
44
# Return the path to a given node's file.
45
def path(name, ext = '.msgpack')
46
if name =~ Puppet::Indirector::BadNameRegexp then
47
Puppet.crit("directory traversal detected in #{self.class}: #{name.inspect}")
48
raise ArgumentError, "invalid key"
51
base = Puppet.run_mode.master? ? Puppet[:server_datadir] : Puppet[:client_datadir]
52
File.join(base, self.class.indirection_name.to_s, name.to_s + ext)
57
def load_msgpack_from_file(file, key)
61
msgpack = File.read(file)
65
raise Puppet::Error, "Could not read MessagePack data for #{indirection.name} #{key}: #{detail}", detail.backtrace
69
return from_msgpack(msgpack)
71
raise Puppet::Error, "Could not parse MessagePack data for #{indirection.name} #{key}: #{detail}", detail.backtrace
75
def from_msgpack(text)
76
model.convert_from('msgpack', text)
79
def to_msgpack(object)
80
object.render('msgpack')