~ubuntu-branches/ubuntu/precise/boinc/precise

« back to all changes in this revision

Viewing changes to sched/pymw_assimilator.py

Tags: 6.12.8+dfsg-1
* New upstream release.
* Simplified debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
 
 
3
import boinc_path_config
 
4
from assimilator import *
 
5
import os, sys, shutil
 
6
 
 
7
class PymwAssimilator(Assimilator):
 
8
    """
 
9
    PyMW Assimilator. Copies workunit results to a predefined output directory. 
 
10
    """
 
11
    
 
12
    def __init__(self):
 
13
        Assimilator.__init__(self)
 
14
        self.pymwDir = None
 
15
 
 
16
    def _copy_to_output(self, result, error_mask=0):
 
17
        # validate that the destination path still exists
 
18
        if not os.path.exists(self.pymwDir):
 
19
            self.logCritical("PyMW path does not exist or is inaccessible: %s\n", \
 
20
                            self.pymwDir)
 
21
            return
 
22
        
 
23
        resultFullPath = self.get_file_path(result)
 
24
        resultName = re.search('<open_name>(.*)</open_name>',result.xml_doc_in).group(1)
 
25
 
 
26
        # validate that the source path is accessible
 
27
        if not error_mask and not os.path.exists(resultFullPath):
 
28
            self.logCritical("Result path does not exist or is inaccessible: %s\n", \
 
29
                            resultFullPath)
 
30
            return
 
31
        
 
32
        # copy the file to the output directory where it
 
33
        # will be processed by PyMW
 
34
        try:
 
35
            dest = os.path.join(self.pymwDir, resultName)
 
36
            if error_mask:
 
37
                dest += ".error"
 
38
                f = open(dest, "w")
 
39
                try:
 
40
                    f.writelines("BOINC error: " + str(error_mask) + "\n")
 
41
                    if result.stderr_out:
 
42
                        f.writelines("STD ERR: " + result.stderr_out + "\n")
 
43
                    f.writelines("For additional information, check: " +
 
44
                                 "$project/log_$machine/pymw_assimilator.py.log\n")
 
45
                finally: f.close()
 
46
                self.logNormal("Error flag created [%s]\n", resultName)
 
47
            else:
 
48
                shutil.copy2(resultFullPath, dest)
 
49
                self.logNormal("Result copied [%s]\n", resultName)
 
50
        except Exception,msg:
 
51
            self.logCritical("Error copying output\n" + \
 
52
                             "  - Source: %s\n" + \
 
53
                             "  - Dest: %s\n" + 
 
54
                             "  - Error: %s",
 
55
                             resultFullPath, dest, msg)
 
56
    
 
57
    def assimilate_handler(self, wu, results, canonical_result):
 
58
        """
 
59
        Assimilates a canonical result by copying the result file
 
60
        to the PyMW pickup directory, self.pymwDir
 
61
        """
 
62
        
 
63
        # check for valid wu.canonical_result
 
64
        if wu.canonical_result:
 
65
            self.logNormal("[%s] Found canonical result\n", wu.name)
 
66
            self._copy_to_output(canonical_result, wu.error_mask)
 
67
        elif wu.error_mask != 0:
 
68
            # this is an error
 
69
            self.logNormal("[%s] Workunit failed, sending arbitrary result\n", wu.name)
 
70
            self._copy_to_output(results[0], wu.error_mask)
 
71
            self.logNormal("[%s] No canonical result\n", wu.name)
 
72
        else:
 
73
            self.logNormal("[%s] No canonical result\n", wu.name)
 
74
 
 
75
        # report errors with the workunit
 
76
        if self.report_errors(wu):
 
77
            pass
 
78
 
 
79
 
 
80
    def parse_args(self, args):
 
81
        """
 
82
        This overridden version adds support for a PyMW destination directory.
 
83
        """
 
84
 
 
85
        # scan the args for the -pymw_dir switch
 
86
        # remove it when found so the base class doesn't complain
 
87
        # then call the base parse_args method
 
88
 
 
89
        newArgs = []
 
90
        args.reverse()
 
91
        found = False
 
92
 
 
93
        while len(args):
 
94
            arg = args.pop()
 
95
            if arg.strip() == '-pymw_dir':
 
96
                if len(args) == 0:
 
97
                    self.logCritical("Error, path switch found, but no path specified\n")
 
98
                    sys.exit(1)
 
99
 
 
100
                self.pymwDir = args.pop()
 
101
                if not os.path.exists(self.pymwDir):
 
102
                    self.logNormal("Warning, path does not exist or is inaccessible: %s\n", \
 
103
                                    self.pymwDir)
 
104
                    found = True
 
105
                else:
 
106
                    found = True
 
107
            else:
 
108
                newArgs.append(arg)
 
109
        
 
110
        if not found:
 
111
            self.logCritical("Error, path argument expected: -pymw_dir <PATH>\n")
 
112
            sys.exit(1)
 
113
        
 
114
        Assimilator.parse_args(self, newArgs)
 
115
        
 
116
# allow the module to be executed as an application
 
117
if __name__ == '__main__':
 
118
    asm = PymwAssimilator()
 
119
    asm.run()