summaryrefslogtreecommitdiffstats
path: root/lib/puppet/statechange.rb
blob: ac10dc3010158284aa362fc50d99edc152f15a3b (plain)
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
#!/usr/local/bin/ruby -w

# $Id$

# the class responsible for actually doing any work

# enables no-op and logging/rollback

module Puppet
	class StateChange
        attr_accessor :is, :should, :type, :path, :state, :transaction, :run

		#---------------------------------------------------------------
        def initialize(state)
            @state = state
            @path = [state.path,"change"].flatten
            @is = state.is

            if state.is == state.should
                raise Puppet::Error.new(
                    "Tried to create a change for in-sync state %s" % state.name
                )
            end
            @should = state.should

            @run = false
        end
		#---------------------------------------------------------------

		#---------------------------------------------------------------
        def go
            if @state.noop
                #Puppet.debug "%s is noop" % @state
                return nil
            end

            if @state.is == @state.should
                raise Puppet::Error.new(
                    "Tried to change in-sync state %s" % state.name
                )
            end

            begin
                event = @state.sync
                @run = true
                
                # default to a simple event type
                if event.nil?
                    #event = @state.parent.class.name.id2name + "_changed"
                    # they didn't actually change anything
                    return
                elsif ! event.is_a?(Symbol)
                    Puppet.warning "State '%s' returned invalid event '%s'; resetting to default" %
                        [@state.class,event]

                    event = @state.parent.class.name.id2name + "_changed"
                end

                # i should maybe include object type, but the event type
                # should basically point to that, right?
                    #:state => @state,
                    #:object => @state.parent,
                Puppet.notice self.to_s
                return Puppet::Event.new(
                    :event => event,
                    :change => self,
                    :transaction => @transaction,
                    :source => @state.parent,
                    :message => self.to_s
                )
            rescue => detail
                #Puppet.err "%s failed: %s" % [self.to_s,detail]
                raise
                # there should be a way to ask the state what type of event
                # it would have generated, but...
                pname = @state.parent.class.name.id2name
                #if pname.is_a?(Symbol)
                #    pname = pname.id2name
                #end
                    #:state => @state,
                Puppet.notice "Failed: " + self.to_s
                return Puppet::Event.new(
                    :event => pname + "_failed",
                    :change => self,
                    :source => @state.parent,
                    :transaction => @transaction,
                    :message => "Failed: " + self.to_s
                )
            end
        end
		#---------------------------------------------------------------

		#---------------------------------------------------------------
        def forward
            #Puppet.debug "moving change forward"

            unless defined? @transaction
                raise "StateChange '%s' tried to be executed outside of transaction" %
                    self
            end

            return self.go
        end
		#---------------------------------------------------------------

		#---------------------------------------------------------------
        def backward
            @state.should = @is
            @state.retrieve

            unless @state.insync?
                Puppet.notice "Rolling %s backward" % self
                return self.go
            end

            #raise "Moving statechanges backward is currently unsupported"
            #@type.change(@path,@should,@is)
        end
		#---------------------------------------------------------------
        
		#---------------------------------------------------------------
        def noop
            return @state.noop
        end
		#---------------------------------------------------------------

		#---------------------------------------------------------------
        def to_s
            return "%s: %s changed %s to %s" %
                [@state.parent, @state.name, @state.is_to_s, @state.should_to_s]
        end
		#---------------------------------------------------------------
	end
end