84c182a1baabd7a315a84af7f01c02e2ad646a6a
[packages/precise/mcollective.git] / ext / action_helpers / python / kwilczynski / mcollective_action.py
1 #!/usr/bin/env python
2
3 import os
4 import sys
5
6 class Error(Exception):
7     pass
8
9 class MissingModule(Error):
10     pass
11
12 class MissingFiles(Error):
13     pass
14
15 class MissingEnvironemntVariable(Error):
16     pass
17
18 class FileReadError(Error):
19     pass
20
21 class JSONParsingError(Error):
22     pass
23
24 try:
25     import simplejson as json
26 except ImportError:
27     raise MissingModule('Unable to load JSON module. Missing module?')
28
29 class MCollectiveAction(object):
30
31     _environment_variables = [ 'MCOLLECTIVE_REQUEST_FILE',
32                                'MCOLLECTIVE_REPLY_FILE' ]
33
34     def __init__(self):
35         self._info  = sys.__stdout__
36         self._error = sys.__stderr__ 
37
38         for entry in '_reply', '_request':
39             self.__dict__[entry] = {}
40
41         self._arguments = sys.argv[1:]
42
43         if len(self._arguments) < 2:
44             try:
45                 for variable in self._environment_variables:
46                     self._arguments.append(os.environ[variable])
47             except KeyError:
48                 raise MissingEnvironemntVariable("Environment variable `%s' "
49                                                  "is not set." % variable)
50
51         self._request_file, self._reply_file = self._arguments
52
53         if len(self._request_file) == 0 or len(self._reply_file) == 0:
54             raise MissingFiles("Both request and reply files have to be set.")
55
56     def __setattr__(self, name, value):
57         if name.startswith('_'):
58             object.__setattr__(self, name, value)
59         else:
60             self.__dict__['_reply'][name] = value
61
62     def __getattr__(self, name):
63         if name.startswith('_'):
64             return self.__dict__.get(name, None)
65         else:
66             return self.__dict__['_reply'].get(name, None)
67
68     def __del__(self):
69         if self._reply:
70             try:
71                 file = open(self._reply_file, 'w')
72                 json.dump(self._reply, file)
73                 file.close()
74             except IOError, error:
75                 raise FileReadError("Unable to open reply file `%s': %s" %
76                                     (self._reply_file, error))
77
78     def info(self, message):
79         print >> self._info, message
80         self._info.flush()
81
82     def error(self, message):
83         print >> self._error, message
84         self._error.flush()
85
86     def fail(self, message, exit_code=1):
87         self.error(message)
88         sys.exit(exit_code)
89
90     def reply(self):
91         return self._reply
92
93     def request(self):
94         if self._request:
95             return self._request
96         else:
97             try:
98                 file = open(self._request_file, 'r')
99                 self._request = json.load(file)
100                 file.close()
101             except IOError, error:
102                 raise FileReadError("Unable to open request file `%s': %s" %
103                                     (self._request_file, error))
104             except json.JSONDecodeError, error:
105                 raise JSONParsingError("An error occurred during parsing of "
106                                        "the JSON data in the file `%s': %s" %
107                                        (self._request_file, error))
108                 file.close()
109
110             return self._request
111
112 # vim: set ts=4 sw=4 et :