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
|
# the class responsible for actually doing any work
# enables no-op and logging/rollback
module Puppet
# Handle all of the work around performing an actual change,
# including calling 'sync' on the properties and producing events.
class PropertyChange
attr_accessor :is, :should, :type, :path, :property, :transaction, :changed, :proxy
# The log file generated when this object was changed.
attr_reader :report
# Switch the goals of the property, thus running the change in reverse.
def backward
@property.should = @is
@is = @property.retrieve
unless defined? @transaction
raise Puppet::Error,
"PropertyChange '%s' tried to be executed outside of transaction" %
self
end
unless @property.insync?(@is)
@property.info "Backing %s" % self
return self.go
else
@property.debug "rollback is already in sync: %s vs. %s" %
[@is, @property.should.inspect]
return nil
end
end
def changed?
self.changed
end
# Create our event object.
def event(name)
# default to a simple event type
unless name.is_a?(Symbol)
@property.warning("Property '%s' returned invalid event '%s'; resetting to default" %
[@property.class, name])
event = @property.resource.class.name.id2name + "_changed"
end
Puppet::Event.new(
:event => name,
:transaction => @transaction,
:source => self.source
)
end
def initialize(property, currentvalue)
unless property.is_a?(Puppet::Property)
raise Puppet::DevError, "Got a %s instead of a property" %
property.class
end
@property = property
@path = [property.path,"change"].flatten
@is = currentvalue
@should = property.should
@changed = false
end
# Perform the actual change. This method can go either forward or
# backward, and produces an event.
def go
if skip?
if self.noop
return [event(:noop)]
else
return nil
end
end
# The transaction catches any exceptions here.
events = @property.sync
if events.nil?
return nil
end
if events.is_a?(Array)
if events.empty?
return nil
end
else
events = [events]
end
return events.collect { |name|
@report = @property.log(@property.change_to_s(@is, @should))
event(name)
}
end
def forward
#@property.debug "moving change forward"
unless defined? @transaction
raise Puppet::Error,
"PropertyChange '%s' tried to be executed outside of transaction" %
self
end
return self.go
end
def noop
return @property.noop
end
def skip?
if @property.insync?(@is)
@property.info "Already in sync"
return true
end
if @property.noop
@property.log "is %s, should be %s (noop)" %
[property.is_to_s(@is), property.should_to_s(@should)]
#@property.debug "%s is noop" % @property
return true
end
return false
end
def source
self.proxy || @property.resource
end
def to_s
return "change %s.%s(%s)" %
[@transaction.object_id, self.object_id, @property.change_to_s(@is, @should)]
#return "change %s.%s" % [@transaction.object_id, self.object_id]
end
end
end
|