source: people/peter.buschman/backup_monitoring/parsing/parsers/bpimagelist/_bpimagelist.py

Last change on this file was 976, checked in by peter, on Dec 6, 2011 at 10:19:33 AM

Raw checkin of current NetBackup / TSM parsing code.

File size: 7.9 KB
Line 
1import re
2
3import time
4import datetime
5import pytz
6
7from ....builtins import *
8
9from ...exceptions import *
10from ...expressions import *
11from ...autotype import *
12from ...streams import *
13
14##
15## bpimagelist has records separated by blank lines
16##
17def stream(stream, format='bpimagelist -L'):
18
19 if format in ['bpimagelist -L']:
20 return BlankLineStream(stream, header=1)
21 else:
22 raise ParseError, 'Unknown format %s' % (format)
23
24
25##
26## Parse a bpimagelist record
27##
28## bpimagelist -L
29##
30def parse(record, format='bpimagelist -L', version=None, tz=None):
31
32 re_pair = re.compile('^\s*([^:]+):\s*(.*)\s*$')
33 re_type_id = re.compile('^([0-9a-zA-Z\-_ ]+)\s+\((\d+)\)$')
34 re_id_type = re.compile('^(\d+)\s+\(([0-9a-zA-Z\-_ ]+)\)$')
35 re_in_parens = re.compile('^\((.*)\)$')
36 re_starts_with_time = re.compile('^time_.*$')
37 re_ends_with_time = re.compile('^.*_time$')
38 re_time_plus_epoch_seconds_in_parens = re.compile('^.*\d:\d\d:\d\d.*\((\d+)\)$')
39 re_epoch_seconds_plus_time_in_parens = re.compile('^(\d+)\s+\(.*\d:\d\d:\d\d.*\)$')
40 re_nbu_infinity = re.compile('^.*INFINITY\s+\((\d+)\)$')
41 re_unix_time_hack = re.compile('^.*\((\d+)\)$')
42
43 image = ExtendedDict()
44
45 if format == 'bpimagelist -L':
46
47 header = True
48
49 try:
50
51 i = 0
52
53 #
54 # process image header
55 #
56 while header and i < len(record):
57
58 line = record[i]
59
60 i += 1
61
62 match = re_pair.match(line)
63
64 key = match.group(1)
65 value = match.group(2)
66 value = value.rstrip()
67 key = key.lower()
68 key = key.rstrip()
69 key = key.replace('-', '_')
70 key = key.replace(' ', '_')
71
72 if key == 'copy_number':
73 header = False
74 else:
75
76 #
77 # convert text values to python datatypes
78 #
79 while True:
80
81 #
82 # match timestamp with Unix time in parentheses
83 #
84 match = re_time_plus_epoch_seconds_in_parens.match(line)
85 if match:
86 value = datetime.datetime.fromtimestamp(float(match.group(1)), tz)
87 break
88
89 #
90 # match infinity
91 #
92 match = re_nbu_infinity.match(value)
93 if match:
94 value = datetime.datetime.fromtimestamp(float(match.group(1)), tz)
95 break
96
97 #
98 # separate type and id
99 #
100 match = re_type_id.match(value)
101 if match:
102 idkey = '%s_id' % (key)
103 value = match.group(1)
104 image[idkey] = int(match.group(2))
105 break
106
107 #
108 # separate id and type
109 #
110 match = re_id_type.match(value)
111 if match:
112 idkey = '%s_id' % (key)
113 value = match.group(2)
114 image[idkey] = int(match.group(1))
115 break
116
117 #
118 # strip enclosing parens
119 #
120 match = re_in_parens.match(value)
121 if match:
122 value = match.group(1)
123 break
124
125 #
126 # ..otherwise autodetect
127 #
128 value = autotype(value)
129 break
130
131 #
132 # store value
133 #
134 image[key] = value
135
136 #
137 # parse image copies
138 #
139 copies = ExtendedDict()
140 image['copies'] = copies
141
142 #
143 # return the image if there are no copies and we have reached the end of the record
144 #
145 if i == len(record):
146 return image
147
148 i = i - 1
149
150 while i < len(record):
151
152 line = record[i]
153
154 match = re_pair.match(line)
155
156 key = match.group(1)
157 value = match.group(2)
158 value = value.rstrip()
159 key = key.lower()
160 key = key.rstrip()
161 key = key.replace('-', '_')
162 key = key.replace(' ', '_')
163
164 #
165 # identify current copy
166 #
167 if key == 'copy_number':
168
169 copy_number = int(value)
170
171 if copy_number not in copies:
172 copies[copy_number] = ExtendedDict()
173 copies[copy_number]['copy_number'] = copy_number
174 copies[copy_number]['fragments'] = ExtendedDict()
175
176 #
177 # identify current fragment
178 #
179 elif key == 'fragment':
180
181 if value == 'TIR (-1)':
182 fragment = -1
183 tir = True
184 elif value == 'TIR (-2)':
185 fragment = -2
186 tir = True
187 else:
188 fragment = int(value)
189 tir = False
190
191 if fragment not in copies[copy_number].fragments:
192 copies[copy_number].fragments[fragment] = ExtendedDict()
193 copies[copy_number].fragments[fragment]['fragment'] = fragment
194 copies[copy_number].fragments[fragment]['tir'] = tir
195
196 #
197 # save the key and value using the copy and fragment
198 #
199 else:
200
201 while True:
202
203 #
204 # match timestamp with Unix time in parentheses
205 #
206 match = re_time_plus_epoch_seconds_in_parens.match(line)
207 if match:
208 value = datetime.datetime.fromtimestamp(float(match.group(1)), tz)
209 break
210
211 #
212 # match infinity
213 #
214 match = re_nbu_infinity.match(value)
215 if match:
216 value = datetime.datetime.fromtimestamp(float(match.group(1)), tz)
217 break
218
219 #
220 # separate type and id
221 #
222 match = re_type_id.match(value)
223 if match:
224 idkey = '%s_id' % (key)
225 value = match.group(1)
226 copies[copy_number].fragments[fragment][idkey] = int(match.group(2))
227 break
228
229 #
230 # ..otherwise autodetect
231 #
232 value = autotype(value, tz=tz)
233 break
234
235 copies[copy_number].fragments[fragment][key] = value
236
237 i += 1
238
239 image['copies'] = copies
240
241 return image
242
243 except Exception, e:
244
245 for line in record:
246 print line
247
248 raise ParseError, e
249
250 else:
251
252 raise ParseError, 'Unknown format %s' % (format)
253
Note: See TracBrowser for help on using the repository browser.