summaryrefslogtreecommitdiffstats
path: root/lib/puppet/statechange.rb
blob: 71995b8648695ebea0c60a5e42867b58280999f3 (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
#!/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(
                    "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?
                return Puppet::Event.new(
                    :event => event,
                    :state => @state.name,
                    :object => @state.parent,
                    :transaction => @transaction,
                    :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
                return Puppet::Event.new(
                    :event => pname + "_failed",
                    :state => @state.name,
                    :object => @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 => %s" % [@state,@is,@should]
        end
		#---------------------------------------------------------------
	end
end