Imported Upstream version 0.0~git20110829
[debian/mudpuppy.git] / mudpuppy.py
1 #!/usr/bin/env python
2
3 '''A very, very simple mudpuppy implementation
4 '''
5
6 import os
7 import sys
8 import auto
9 import util
10 import config
11 import time
12 import traceback
13 import signal
14
15 from constants import *
16 from modules.base import CannotAutomateException
17 from magiclink import MagicLink
18
19 import logging
20 import logging.config
21 logging.config.fileConfig(os.path.join(os.path.dirname(os.path.abspath(__file__)),'logging.conf'))
22
23 exit_gracefully = False
24
25 def sighup_handler(signum, frame):
26         global exit_gracefully
27         exit_gracefully = True
28         print "got SIGHUP"
29 signal.signal(signal.SIGHUP, sighup_handler)
30
31
32 def automate_task(uuid):
33         '''find an item that we can do in a task and automate it
34
35         At the moment we return as soon as we automate a single item successfully
36
37         returns True if we managed to automate anything
38         '''     
39
40         api = MagicLink()
41
42         automated_something = False
43
44         for item in api.get_available_items(uuid):
45                 item_name = item['name']
46                 if automated_something: break
47
48                 # Needs to be at least as new as the available list
49                 task_metadata = api.get_task_metadata(uuid)
50                 for module in auto.get_modules_for_item(item, task_metadata):
51                         if automated_something: break
52                         # Lock
53                         if not api.update_item_state(uuid, item_name, INCOMPLETE, IN_PROGRESS):
54                                 break   # Couldn't lock item. Try the next
55                         logging.info('Set %s/%s to IN_PROGRESS' %(uuid,item_name))
56
57                         # Attempt to run
58                         try:
59                                 builder = module(item, task_metadata)
60                                 result = builder.do_magic()
61                                 if result != None and result.has_key('task_metadata_update'):
62                                         api.update_task_metadata(uuid, result['task_metadata_update'])
63                                         logging.debug('updating task metadata for %s with: %s' %(uuid,result['task_metadata_update']))
64                                 if result != None and result.has_key('item_metadata_update'):
65                                         api.update_item(uuid, item_name, result['item_metadata_update'])
66                                         logging.debug('updating item metadata for %s/%s with: %s' %(uuid,item_name,result['item_metadata_update']))
67                         except CannotAutomateException:
68                                 # Unlock and try the next builder
69                                 logging.debug('Module threw CANNOT_AUTOMATE. Continuing with other modules if there are there', exc_info=1)
70                                 logging.info('Setting %s/%s to INCOMPLETE' %(uuid,item_name))
71                                 worked = api.update_item_state(uuid, item_name, IN_PROGRESS, INCOMPLETE)
72                                 if not worked:
73                                         logging.error("Couldn't set item state from IN_PROGRESS to FAILED! Task may be in inconsistant state")
74                                         return False
75                                 continue
76                         except Exception, e:
77                                 logging.error('Module threw an exception. Setting the item to FAILED', exc_info=1)
78                                 worked = api.update_item_state(uuid, item_name, IN_PROGRESS, FAILED)
79                                 if not worked:
80                                         logging.error("Couldn't set item state from IN_PROGRESS TO FAILED! Task may be in inconsistant state")
81                                         return False
82                                 automated_something = True
83                                 break
84
85                         logging.info('Module finished. Setting %s/%s to COMPLETE' %(uuid,item['name']))
86                         automated_something = True
87                         worked = api.update_item_state(uuid, item_name, IN_PROGRESS, COMPLETE)
88                         if not worked:
89                                 logging.error("Couldn't set item state from IN_PROGRESS TO COMPLETE! Task may be in inconsistant state")
90                                 return False
91
92         return automated_something
93         
94 def mudpuppy_main():
95         logging.config.fileConfig(os.path.join(os.path.dirname(os.path.abspath(__file__)),'logging.conf'))
96
97         api = MagicLink()
98
99         # Load in the modules that do the real work
100         auto.load_modules()
101
102         logging.info("Started. Waiting for things to do.")
103         while not exit_gracefully:
104                 tasks = api.get_tasks()
105
106                 automated_something = False
107                 for uuid in tasks:
108                         automated = automate_task(uuid)         
109                         automated_something |= automated
110
111                 if not automated_something:
112                         # Didn't manage to change the state of anything
113                         # so wait at least a second before hammering
114                         # the server again
115                         time.sleep(1)
116                         continue
117
118                 logging.debug("Polling make-magic for serverbuilds for us to automate")
119         logging.info("Exiting gracefully after SIGHUP")
120
121
122 if __name__ == '__main__':
123         mudpuppy_main()