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
158
159
160
161
162
163
|
# The virtual base class for states, which are the self-contained building
# blocks for actually doing work on the system.
require 'puppet'
require 'puppet/element'
require 'puppet/statechange'
module Puppet
class State < Puppet::Element
attr_accessor :is, :parent
# Because 'should' uses an array, we have a special method for handling
# it. We also want to keep copies of the original values, so that
# they can be retrieved and compared later when merging.
attr_reader :shouldorig
@virtual = true
class << self
attr_accessor :unmanaged
attr_reader :name
end
# initialize our state
def initialize(hash)
@is = nil
unless hash.include?(:parent)
raise Puppet::DevError, "State %s was not passed a parent" % self
end
@parent = hash[:parent]
if hash.include?(:should)
self.should = hash[:should]
end
if hash.include?(:is)
self.is = hash[:is]
end
end
# Determine whether the state is in-sync or not. If @should is
# not defined or is set to a non-true value, then we do not have
# a valid value for it and thus consider the state to be in-sync
# since we cannot fix it. Otherwise, we expect our should value
# to be an array, and if @is matches any of those values, then
# we consider it to be in-sync.
def insync?
#debug "%s value is '%s', should be '%s'" %
# [self,self.is.inspect,self.should.inspect]
unless defined? @should and @should
return true
end
unless @should.is_a?(Array)
raise Puppet::DevError, "%s's should is not array" % self.class.name
end
# an empty array is analogous to no should values
if @should.empty?
return true
end
# Look for a matching value
@should.each { |val|
if @is == val
return true
end
}
# otherwise, return false
return false
end
# each state class must define the name() method, and state instances
# do not change that name
# this implicitly means that a given object can only have one state
# instance of a given state class
def name
return self.class.name
end
# for testing whether we should actually do anything
def noop
unless defined? @noop
@noop = false
end
tmp = @noop || self.parent.noop || Puppet[:noop] || false
#debug "noop is %s" % tmp
return tmp
end
# return the full path to us, for logging and rollback; not currently
# used
def path
return [@parent.path, self.name].flatten
end
# Only return the first value
def should
if defined? @should
unless @should.is_a?(Array)
self.warning @should.inspect
raise Puppet::DevError, "should for %s on %s is not an array" %
[self.class.name, @parent.name]
end
return @should[0]
else
return nil
end
end
# Set the should value.
def should=(values)
unless values.is_a?(Array)
values = [values]
end
@shouldorig = values
if self.respond_to?(:shouldprocess)
@should = values.collect { |val|
self.shouldprocess(val)
}
else
@should = values
end
end
# How should a state change be printed as a string?
def change_to_s
if @is == :notfound
return "%s: defined '%s' as '%s'" %
[@parent, self.name, self.should_to_s]
elsif self.should == :notfound
return "%s: undefined %s from '%s'" %
[self.parent, self.name, self.is_to_s]
else
return "%s changed '%s' to '%s'" %
[self.name, self.is_to_s, self.should_to_s]
end
end
# because the @should and @is vars might be in weird formats,
# we need to set up a mechanism for pretty printing of the values
# default to just the values, but this way individual states can
# override these methods
def is_to_s
@is
end
def should_to_s
@should
end
def to_s
return "%s(%s)" % [@parent.name,self.name]
end
end
end
# $Id$
|