1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
require 'puppet/rails/resource'
require 'puppet/rails/fact_name'
require 'puppet/rails/source_file'
require 'puppet/util/rails/collection_merger'
# Puppet::TIME_DEBUG = true
class Puppet::Rails::Host < ActiveRecord::Base
include Puppet::Util
include Puppet::Util::CollectionMerger
has_many :fact_values, :dependent => :destroy
has_many :fact_names, :through => :fact_values
belongs_to :puppet_classes
has_many :source_files
has_many :resources,
:include => :param_values,
:dependent => :destroy
# If the host already exists, get rid of its objects
def self.clean(host)
if obj = self.find_by_name(host)
obj.rails_objects.clear
return obj
else
return nil
end
end
# Store our host in the database.
def self.store(node, resources)
unless name = hash[:name]
raise ArgumentError, "You must specify the hostname for storage"
end
args = {}
host = nil
transaction do
#unless host = find_by_name(name)
seconds = Benchmark.realtime {
unless host = find_by_name(name)
host = new(:name => node.name)
end
}
Puppet.notice("Searched for host in %0.2f seconds" % seconds) if defined?(Puppet::TIME_DEBUG)
if ip = node.parameters["ipaddress"]
host.ip = ip
end
# Store the facts into the database.
host.setfacts node.parameters
seconds = Benchmark.realtime {
host.setresources(resources)
}
Puppet.notice("Handled resources in %0.2f seconds" % seconds) if defined?(Puppet::TIME_DEBUG)
host.last_compile = Time.now
host.save
end
return host
end
# Return the value of a fact.
def fact(name)
if fv = self.fact_values.find(:all, :include => :fact_name,
:conditions => "fact_names.name = '#{name}'")
return fv
else
return nil
end
end
# returns a hash of fact_names.name => [ fact_values ] for this host.
def get_facts_hash
fact_values = self.fact_values.find(:all, :include => :fact_name)
return fact_values.inject({}) do | hash, value |
hash[value.fact_name.name] ||= []
hash[value.fact_name.name] << value
hash
end
end
def setfacts(facts)
facts = facts.dup
ar_hash_merge(get_facts_hash(), facts,
:create => Proc.new { |name, values|
fact_name = Puppet::Rails::FactName.find_or_create_by_name(name)
values = [values] unless values.is_a?(Array)
values.each do |value|
fact_values.build(:value => value,
:fact_name => fact_name)
end
}, :delete => Proc.new { |values|
values.each { |value| self.fact_values.delete(value) }
}, :modify => Proc.new { |db, mem|
mem = [mem].flatten
fact_name = db[0].fact_name
db_values = db.collect { |fact_value| fact_value.value }
(db_values - (db_values & mem)).each do |value|
db.find_all { |fact_value|
fact_value.value == value
}.each { |fact_value|
fact_values.delete(fact_value)
}
end
(mem - (db_values & mem)).each do |value|
fact_values.build(:value => value,
:fact_name => fact_name)
end
})
end
# Set our resources.
def setresources(list)
existing = nil
seconds = Benchmark.realtime {
# Preload the parameters with the resource query, but not the tags, since doing so makes the query take about 10x longer.
# I've left the other queries in so that it's straightforward to switch between them for testing, if we so desire.
#existing = resources.find(:all, :include => [{:param_values => :param_name, :resource_tags => :puppet_tag}, :source_file]).inject({}) do | hash, resource |
#existing = resources.find(:all, :include => [{:resource_tags => :puppet_tag}, :source_file]).inject({}) do | hash, resource |
existing = resources.find(:all, :include => [{:param_values => :param_name}, :source_file]).inject({}) do | hash, resource |
hash[resource.ref] = resource
hash
end
}
Puppet.notice("Searched for resources in %0.2f seconds" % seconds) if defined?(Puppet::TIME_DEBUG)
compiled = list.inject({}) do |hash, resource|
hash[resource.ref] = resource
hash
end
ar_hash_merge(existing, compiled,
:create => Proc.new { |ref, resource|
resource.to_rails(self)
}, :delete => Proc.new { |resource|
self.resources.delete(resource)
}, :modify => Proc.new { |db, mem|
mem.modify_rails(db)
})
end
def update_connect_time
self.last_connect = Time.now
save
end
end
# $Id$
|