source: trunk/examples/JobParser.py @ 329

Last change on this file since 329 was 323, checked in by bas, 10 years ago

Added some documentation and improve some error handeling

File size: 7.2 KB
Line 
1#!/usr/bin/env python
2#
3# Author:       Dennis Stam
4# Date:         30 September 2014
5# Description:  This is a very simple jobscript parser to fetch all #PBS arguments
6#               and convert them to a attropl list which can be used for submission
7#
8
9import re
10import sys
11import argparse
12import time
13import pbs
14
15class JobParser(object):
16    '''A simple simple jobscript parser to fetch all #PBS arguments from the header'''
17
18    job_script = None
19    matcher = re.compile(r'\#PBS\s(?P<args>.+)')
20
21    ## These are the arguments that exist in Torque
22    pbs_attrs = {
23        'a' : {
24            'func': 'pbs_datetime',
25            'args_opts': {
26                'type': str,
27            },
28        },
29        'A' : {
30            'args_opts': {
31                'type': str,
32            },
33        },
34        # Checkpoint is not yet implemented
35        #'c' : {
36        #    'args_opts': {
37        #        'type': str,
38        #        'action': 'append',
39        #    },
40        #},
41        'e' : {
42            'args_opts': {
43                'type': str,
44            },
45        },
46        'F' : {
47            'args_opts': {
48                'type': str,
49            },
50        },
51        'f' : {
52            'args_opts': {
53                'action' : 'store_true',
54            },
55        },
56        'h' : {
57            'args_opts': {
58                'action' : 'store_true',
59            },
60        },
61        'I' : {
62            'args_opts': {
63                'action' : 'store_true',
64            },
65        },
66        'j' : {
67            'args_opts': {
68                'type': str,
69                'choices': ['eo','oe','n'],
70            },
71        },
72        'k' : {
73            'args_opts': {
74                'type': str,
75                'choices' : ['e','o','eo','oe','n'],
76            },
77        },
78        'l' : {
79            'args_opts': {
80                'type': str,
81                'action': 'append',
82            },
83        },
84        'm' : {
85            'args_opts': {
86                'type': str,
87                'choices': ['a','b','e','n'],
88            },
89        },
90        'M' : {
91            'args_opts': {
92                'type': str,
93                'action': 'append',
94            },
95        },
96        'N' : {
97            'args_opts': {
98                'type': str,
99            },
100        },
101        'o' : {
102            'args_opts': {
103                'type': str,
104            },
105        },
106        'p' : {
107            'args_opts': {
108                'type': int,
109            },
110        },
111        'P' : {
112            'args_opts': {
113                'type': str,
114            },
115        },
116        'q' : {
117            'args_opts': {
118                'type': str,
119            },
120        },
121        'r' : {
122            'args_opts': {
123                'action' : 'store_true',
124            },
125        },
126        'S' : {
127            'args_opts': {
128                'type': str,
129                'action' : 'append',
130            },
131        },
132        't' : {
133            'args_opts': {
134                'type': str,
135            },
136        },
137        'u' : {
138            'args_opts': {
139                'type': str,
140                'action' : 'append',
141            },
142        },
143        'W' : {
144            'args_opts': {
145                'type': str,
146                'action' : 'append',
147            },
148        },
149    }
150
151    def __init__(self, job_script=None):
152        if hasattr(job_script, 'readlines'):
153            self.job_script = job_script.readlines()
154
155    def read(self, filename):
156        try:
157            with open(filename, 'r') as fi:
158                self.job_script = fi.readlines()
159        except IOError:
160            error_str = "Jobscript filename does not exists: %s" %(filename)
161            raise Exception(error_str)
162
163    def __get_pbs_args(self):
164        if not self.job_script:
165            raise Exception("User function read to read from file")
166
167        args = list()
168        for line in self.job_script:
169            if self.matcher.search(line.strip()):
170                args.append(self.matcher.findall(line.strip())[0])
171        return args
172
173    def pbs_datetime(self, input):
174
175        current_time, current_seconds = tuple(time.strftime('%Y%m%d%H%M.%S').split('.'))
176
177        if len(input.strip()) == 12:
178            return input.strip()
179        elif len(input.strip()) == 10:
180            return current_time[0:2] + input.strip()
181        elif len(input.strip()) == 8:
182            return current_time[0:4] + input.strip()
183        elif len(input.strip()) == 6:
184            return current_time[0:6] + input.strip()
185        elif len(input.strip()) == 4:
186            return current_time[0:8] + input.strip()
187
188        return current_time
189
190    def parse_pbs(self):
191        '''Parse the arguments and check if they are using the correct format'''
192
193        ## First create an arguments parser
194        parser = argparse.ArgumentParser(add_help=False)
195        for arg, options in self.pbs_attrs.items():
196            parser.add_argument('-'+arg, **options['args_opts'])
197
198        ## Parse the arguments that have been found in the jobscript
199        args = parser.parse_args(self.__get_pbs_args())
200
201        ## Create an dict with items we wan't to set, skip evrything which is None, empty of False
202        process_args = dict()
203        for k,v in args.__dict__.items():
204            if v:
205                if self.pbs_attrs.has_key(k) and self.pbs_attrs[k].has_key('func'):
206                    try:
207                        process_args[k] = getattr(self, self.pbs_attrs[k]['func'])(v)
208                    except AttributeError as err:
209                        raise Exception('Could not locate function')
210                else:
211                    if type(v) is type(list()):
212                        value = list()
213                        for x in v:
214                            value.extend(x.strip().split(','))
215                        process_args[k] = ",".join(value)
216                    else:
217                        process_args[k] = v.strip()
218        return process_args
219
220    def get_attropl(self):
221        data = self.parse_pbs()
222
223        ### First al the keys, except for --resource-list/-l
224        ##  and perhaps more later
225        length = len([ x for x in data.keys() if x not in ['l']])
226        if data.has_key('l'):
227            length += len(data['l'].split(','))
228
229        attropl = pbs.new_attropl(length)
230        index = 0
231
232        for attr, value in data.items():
233            if attr in ['l']:
234                for v in value.split(','):
235                    parts = v.split('=')
236                    resource, value = parts[0], "=".join(parts[1:])
237                    attropl[index].name = getattr(pbs, 'ATTR_'+attr)
238                    attropl[index].resource = resource
239                    attropl[index].value = value
240                    index += 1
241            else:
242                attropl[index].name = getattr(pbs, 'ATTR_'+attr)
243                attropl[index].value = value
244                index += 1
245        return attropl
246
247if __name__ == '__main__':
248    jp = JobParser()
249
250    try:
251        jp.read(sys.argv[1])
252    except IndexError:
253        print("Usage: %s <jobscript>" %(sys.argv[0]))
254        sys.exit(1)
255       
256
257    server_name = pbs.pbs_default()
258    con = pbs.pbs_connect(server_name)
259    job_id = pbs.pbs_submit(con, jp.get_attropl(), sys.argv[1], 'batch', 'NULL')
260
261    e, e_txt = pbs.error()
262    if e:
263        print(e, e_txt)
264    else:
265        print(job_id)
Note: See TracBrowser for help on using the repository browser.