~bcsaller/pyjuju/relation-get-shell

« back to all changes in this revision

Viewing changes to ensemble/hooks/invoker.py

  • Committer: kapil.thangavelu at canonical
  • Date: 2011-05-05 22:04:25 UTC
  • mfrom: (174.8.38 debug-hook-scope-guard)
  • Revision ID: kapil.thangavelu@canonical.com-20110505220425-mt5f28jrvy72h6gp
merge debug-hook-scope-guard [r=niemeyer][f=776014]

Enables live hook debugging via screen/byobu, with better start/end condition handling.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
        self._log.error(data)
30
30
 
31
31
    def processExited(self, reason):
32
 
        ec = reason.value.exitCode
33
 
        if ec == 0:
34
 
            self.deferred.callback(ec)
 
32
        exit_code = reason.value.exitCode
 
33
        if exit_code in (0, None):
 
34
            self.deferred.callback(exit_code)
35
35
        else:
36
 
            exc = errors.FormulaInvocationError(self._hook_name, ec)
37
 
            self.deferred.errback(exc)
 
36
            error = errors.FormulaInvocationError(self._hook_name, exit_code)
 
37
            self.deferred.errback(error)
38
38
 
39
39
 
40
40
class Invoker(object):
64
64
        self._client_id = client_id
65
65
        self._socket_path = socket_path
66
66
        self._log = logger
 
67
        # The twisted.internet.process.Process instance.
 
68
        self._process = None
 
69
        # The hook executable path
 
70
        self._process_executable = None
67
71
 
68
72
    def get_environment(self):
69
73
        """
101
105
            raise errors.FormulaError(hook_filename,
102
106
                                      "hook is not executable")
103
107
 
 
108
    def send_signal(self, signal_id):
 
109
        """Send a signal of the given signal_id.
 
110
 
 
111
        :param signal_id: limited value interpretation, numeric
 
112
        signals ids are used as given, some values for symbolic
 
113
        string interpretation are available see
 
114
        ``twisted.internet.process._BaseProcess.signalProcess`` for
 
115
        additional details.
 
116
 
 
117
        Raises a ValueError if the process doesn't exist or
 
118
        ProcessExitedAlreaday if the process has already ended.
 
119
        """
 
120
 
 
121
        if not self._process:
 
122
            raise ValueError("No Process")
 
123
        return self._process.signalProcess(signal_id)
 
124
 
104
125
    def __call__(self, hook):
105
126
        """
106
127
        Given the complete path name to a hook execute it with a
117
138
        hook_proto = HookProtocol(hook, self._context, self._log)
118
139
        deferred = hook_proto.deferred
119
140
 
120
 
        def cleanupProcess(result):
 
141
        def cleanup_process(result):
121
142
            # Result should be the exit code of the process
122
143
            # clean up the connection and return the exit code
123
144
            # not the result of loseConnection.
130
151
 
131
152
            # Flush context changes back to zookeeper if hook was successful.
132
153
            if result == 0 and self._context:
 
154
                self._log.debug("Flushing relation settings changes ...")
133
155
                d = self._context.flush()
134
156
                d.addCallback(lambda _: result)
135
157
                return d
137
159
            return result
138
160
 
139
161
        self._process = reactor.spawnProcess(hook_proto, hook, [hook], env)
140
 
        deferred.addBoth(cleanupProcess)
 
162
        deferred.addBoth(cleanup_process)
141
163
 
142
164
        return deferred