forked from SeattleTestbed/nodemanager
-
Notifications
You must be signed in to change notification settings - Fork 0
/
nmrestrictionsprocessor.py
214 lines (163 loc) · 5.7 KB
/
nmrestrictionsprocessor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
"""
Author: Armon Dadgar
Start Date: March 31st, 2009
Description:
Provides a tool-chain for altering resource files.
"""
# Finds all resource files
import glob
# Used for moving files
import os
def read_restrictions_file(file):
"""
<Purpose>
Reads in the contents of a restrictions file.
<Arguments>
file: name/path of the file to open
<Returns>
A list, where each element is a line in the file
"""
# Get the file object, read mode with universal newlines
fileo = open(file,"rU")
# Read in all the contents
contents = fileo.readlines()
# Close the file object
fileo.close()
return contents
def write_restrictions_file(file, buffer):
"""
<Purpose>
Writes in the contents of a restrictions file. Tries to do this safely,
by writing to a new file, backing-up the original, renaming the new file, and finally deleting the backup.
<Arguments>
file: name/path of the file to open
buffer: A list, where each element is a line in the file
<Returns>
Nothing
"""
# Get the file object, write mode
# Use a .new suffix, so as not to corrupt the current file
fileo = open(file+".new", "w")
# Write in all the buffer
for line in buffer:
fileo.write(line)
# Close the file object
fileo.close()
# Move the original to *.bak if it exists
if os.path.exists(file):
os.rename(file, file+".bak")
# Move the new one to the original
os.rename(file+".new", file)
# Cleanup, remove the backup
if os.path.exists(file+".bak"):
os.remove(file+".bak")
def update_restriction(lines, restriction, restype, val, func=False):
"""
<Purpose>
Updates a resource in a restrictions file
<Arguments>
lines: The contents of the restrictions file, list each element is a line
restriction: The name of the restriction e.g. resource, call
restype: The type of restriction, e.g. events
val: Either a new absolute value, or a callback function
func: If true, this indicates that val is a function. That function will be given a list of the elements on the current line, and is expected
to return the appropriate val to use.
<Side Effects>
The restrictions file will be modified
<Returns>
The contents of the new restrictions file, list each element is a line
"""
# Empty buffer for new contents
newContents = []
# Store the length of the restriction
restrictionLength = len(restriction)
# Check each line if it contains the resource
for line in lines:
# Check if the line starts with a comment or the restriction as an optimization
# This prevents us from processing every single line needlessly
if not line[0] == "#" and restriction == line[0:restrictionLength]:
# Explode on space
lineContents = line.split(" ")
# Make sure this is the correct resource
# This is okay if there are comments, because either the index will be offset
# Or the value of the index will be changed, and will not match
if not lineContents[0] == restriction or not lineContents[1] == restype:
# Wrong line, continue after appending this line
newContents.append(line)
continue
# Check if we are using a callback function
if func:
userVal = val(lineContents)
else:
# Otherwise, this is just the real value
userVal = val
# Change the value to the string val
lineContents[2] = str(userVal)
# Re-create the line string, with the modifications
lineString = ""
for elem in lineContents:
lineString += elem + " "
lineString = lineString.strip()
lineString += "\n"
# Append the new line to the buffer
newContents.append(lineString)
else:
# Just append this line to the buffer
newContents.append(line)
# Return the modified buffer
return newContents
def get_all_resource_files():
"""
<Purpose>
Returns a list with all the resource files.
<Returns>
A list object with file names.
"""
return glob.glob("resource.v*")
def process_restriction_file(file, tasks):
"""
<Purpose>
Serves as a useful macro for processing a resource file.
<Argument>
file: The name of a resource file.
tasks: A list of tuple objects. Each tuple should contain the following:
(restriction, restype, val, func). See update_restriction for the meaning of these values.
<Returns>
Nothing
"""
# Get the content
content = read_restrictions_file(file)
# Create a new buffer to store the changes
newContent = content
# Run each task against the restrictions file
for task in tasks:
(restriction, restype, val, func) = task
newContent = update_restriction(newContent, restriction, restype, val, func)
# Check if there were any changes
if content != newContent:
# Write out the changes
write_restrictions_file(file, newContent)
def process_all_files(tasks):
"""
<Purpose>
Serves as a useful macro for processing all resource files.
<Arguments>
tasks: A list of tuple objects. Each tuple should contain the following:
(restriction, restype, val, func). See update_restriction for the meaning of these values.
<Returns>
A list of all the failures. They are in the form of tuples: (file, exception)
"""
# Get all the resource files
allFiles = get_all_resource_files()
# Stores the name of all files that failed
failedFiles = []
# Process each one
for rFile in allFiles:
try:
# Process this file
process_restriction_file(rFile, tasks)
# Log if any files fail
except Exception, exp:
failedFiles.append((rFile, exp))
# Return the list of failed files
return failedFiles