OLD | NEW |
---|---|
(Empty) | |
1 #!/usr/bin/python | |
2 # -*- coding: utf-8 -*- | |
3 | |
4 """ | |
5 This script is to generate a zip file of delta-generator and it's dependencies | |
6 """ | |
7 import logging.handlers | |
8 import optparse | |
9 import os | |
10 import re | |
11 import string | |
12 import subprocess | |
13 import sys | |
14 import time | |
15 import tempfile | |
16 import shutil | |
17 # GLOBALS | |
18 | |
19 logging_format = '%(asctime)s - %(filename)s - %(levelname)-8s: %(message)s' | |
20 date_format = '%Y/%m/%d %H:%M:%S' | |
21 logging.basicConfig(level=logging.INFO, format=logging_format, | |
22 datefmt=date_format) | |
23 | |
24 | |
25 def BuildOptions(): | |
26 """ | |
27 Builds all required options using optparse | |
28 args: None | |
scottz-goog
2010/11/05 01:22:46
If there are no arguments there is no need for thi
Raja Aluri
2010/11/05 18:58:01
Done.
| |
29 return parser object | |
30 """ | |
31 | |
32 parser = optparse.OptionParser() | |
scottz-goog
2010/11/05 01:22:46
Move these into main and drop this whole function
| |
33 | |
34 parser.add_option('-d', '--debug', dest='debug', action='store_true', | |
35 default=False, help='Verbose Default: "False"') | |
36 parser.add_option('-o','--output-dir', dest='output_dir', default=None, | |
37 help='Specify the output location for copying the zipfile') | |
38 parser.add_option('-z','--zip-name', dest='zip_name', | |
39 default='au-generator.zip', help='Name of the zip file') | |
40 parser.add_option('-k','--keep-temp', dest='keep_temp', default=False, | |
41 action='store_true', help='Keep the temp files...') | |
42 return parser | |
43 | |
44 | |
45 | |
46 def ValidateOptions(options, args): | |
scottz-goog
2010/11/05 01:22:46
This should be in main as well.
Raja Aluri
2010/11/05 18:58:01
Done.
| |
47 """ | |
48 Validates the set of given options on the command line before executing the | |
49 rest of the script. This is to make sure that all the required options and | |
50 option logic is validated before the execution. | |
51 Args: | |
52 options: options from parser object as input | |
53 args: args from parser objects | |
54 return: False or True | |
55 """ | |
56 | |
57 if not options: | |
58 return False | |
59 if options.debug: | |
scottz-goog
2010/11/05 01:22:46
Validating options should not be modifying things.
Raja Aluri
2010/11/05 18:58:01
Done.
| |
60 logging.setLevel(logging.DEBUG) | |
61 logging.debug('Options are %s ', options) | |
62 if not options.output_dir: | |
63 options.output_dir='/tmp/au-generator' | |
scottz-goog
2010/11/05 01:22:46
This should be the default set in the parser setup
Raja Aluri
2010/11/05 18:58:01
Done.
| |
64 return True | |
65 | |
66 | |
67 def CreateTempDir(): | |
68 """ | |
69 Generates a tempdir | |
70 args: None | |
71 return: name of tempdir | |
72 """ | |
73 temp_dir = tempfile.mkdtemp(suffix='au', prefix='tmp') | |
74 logging.info("Using tempdir = %s",temp_dir) | |
75 return temp_dir | |
76 | |
77 def CopyRequiredFiles(dest_files_root = None ): | |
78 if not dest_files_root: | |
79 logging.error("Invalid option passed for dest_files_root") | |
scottz-goog
2010/11/05 01:22:46
shouldn't we be dying here?
Raja Aluri
2010/11/05 18:58:01
Done.
| |
80 | |
81 ldd_files = ['/usr/bin/delta_generator', | |
scottz-goog
2010/11/05 01:22:46
ldd files? Is there a better name for this? they
Raja Aluri
2010/11/05 18:58:01
Added the explanation in the comments
| |
82 '/usr/bin/bsdiff', | |
83 '/usr/bin/bspatch', | |
84 '/usr/bin/cgpt', | |
85 ] | |
86 static_files = ['~/trunk/src/scripts/common.sh', | |
scottz-goog
2010/11/05 01:22:46
same deal. Static files in what regard? They never
Raja Aluri
2010/11/05 18:58:01
Added the explanation in the comments
| |
87 '~/trunk/src/scripts/cros_generate_update_payload', | |
88 '~/trunk/src/scripts/chromeos-common.sh' | |
89 ] | |
90 recurse_dirs = {'~/trunk/src/scripts/lib/shflags': 'lib/shflags'} | |
91 | |
92 black_list = ['linux-vdso.so', | |
93 'libgcc_s.so', | |
94 'librt.so', | |
95 'libstdc', | |
96 'libgcc_s.so', | |
97 'libc.so', | |
98 'ld-linux-x86-64', | |
99 'libm.so', | |
100 'libdl.so', | |
101 'libresolv.so' | |
102 ] | |
103 | |
104 all_files =ldd_files + static_files | |
scottz-goog
2010/11/05 01:22:46
allfiles = ldd_files...
Raja Aluri
2010/11/05 18:58:01
Done.
| |
105 all_files = map(os.path.expanduser,all_files) | |
scottz-goog
2010/11/05 01:22:46
os.path.expanduser, all_files
Raja Aluri
2010/11/05 18:58:01
Done.
| |
106 logging.debug("all files that need to be copied = %s",all_files) | |
scottz-goog
2010/11/05 01:22:46
comma, SPACE please apply this to all areas.
| |
107 | |
108 for file_name in all_files: | |
109 if not os.path.isfile(file_name): | |
110 logging.error("file = %s does not exist",file_name) | |
111 sys.exit(1) | |
112 | |
113 for file_name in ldd_files: | |
scottz-goog
2010/11/05 01:22:46
this whole for loop should be broken out into a fu
Raja Aluri
2010/11/05 18:58:01
Done.
| |
114 logging.info("Running ldd on %s",file_name) | |
115 cmd = ['/usr/bin/ldd',file_name] | |
116 stdout_data ='' | |
scottz-goog
2010/11/05 01:22:46
the format is
"variable = value"
Note the spaces
Raja Aluri
2010/11/05 18:58:01
Done.
| |
117 stderr_data ='' | |
118 | |
119 try: | |
120 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, | |
121 stderr=subprocess.PIPE ) | |
scottz-goog
2010/11/05 01:22:46
align cmd and stderr= no space after PIPE)
Raja Aluri
2010/11/05 18:58:01
Done.
| |
122 (stdout_data, stderr_data) = proc.communicate(input=None) | |
123 except subprocess.CalledProcessError as e: | |
124 logging.error("Command %s failed", cmd) | |
125 logging.error("error code %s", e.returncode) | |
126 logging.error("ouput %s", e.output) | |
127 raise | |
128 | |
129 library_list =[] | |
scottz-goog
2010/11/05 01:22:46
library_list = []
Raja Aluri
2010/11/05 18:58:01
Done.
| |
130 | |
131 if stdout_data: | |
scottz-goog
2010/11/05 01:22:46
should you not always have stdout_data from ldd if
Raja Aluri
2010/11/05 18:58:01
Just be extra cautious,because of ldd doesn't give
scottz-goog
2010/11/09 03:52:50
Then shouldn't you die if you don't have output? I
| |
132 logging.debug("ldd for %s = stdout = %s stderr =%s",file_name, | |
133 stdout_data, stderr_data) | |
134 library_list = SplitAndStrip(stdout_data) | |
135 | |
136 if library_list: | |
scottz-goog
2010/11/05 01:22:46
as above shouldn't this always be set? If not aren
Raja Aluri
2010/11/05 18:58:01
It can happen that all the output is stripped.
Lik
scottz-goog
2010/11/09 03:52:50
If that is the case you should add an if statement
Raja Aluri
2010/11/09 22:59:45
It can become empty after the _SplitAndStrip and s
Raja Aluri
2010/11/09 22:59:45
Done.
| |
137 library_list = ExcludeBlacklist(library_list,black_list) | |
138 | |
139 if library_list: | |
140 logging.info("Required libraries for %s=%s=",file_name,library_list) | |
141 all_files += library_list | |
142 | |
143 for file_name in all_files: | |
144 logging.info("Copying file %s to %s",file_name,dest_files_root) | |
145 shutil.copy2(file_name,dest_files_root) | |
146 | |
147 for k,v in recurse_dirs.iteritems(): | |
scottz-goog
2010/11/05 01:22:46
please use variables that are descriptive. Nice us
Raja Aluri
2010/11/05 18:58:01
Done.
| |
148 logging.info("Processing directory %s",k) | |
149 full_path = os.path.expanduser(k) | |
150 if not os.path.isdir(full_path): | |
151 logging.error("Directory given for %s exapnded to %s doens't exist.", | |
152 k,full_path) | |
153 sys.exit(1) | |
154 dest = os.path.join(dest_files_root,v) | |
155 logging.info("Copying directory %s to %s.",full_path,dest) | |
156 shutil.copytree(full_path,dest,symlinks=None,ignore=None) | |
157 | |
158 def CleanUP(temp_dir=None): | |
159 """ | |
160 | |
scottz-goog
2010/11/05 01:22:46
docstring?
Raja Aluri
2010/11/05 18:58:01
Done.
| |
161 """ | |
162 if not temp_dir: | |
scottz-goog
2010/11/05 01:22:46
Instead of setting a default just make it a requir
Raja Aluri
2010/11/05 18:58:01
It's a harmless non-fatal operation. Don't want th
scottz-goog
2010/11/09 03:52:50
If it is harmless then you should be running it al
Raja Aluri
2010/11/09 22:59:45
Changed to if os.path.exists(temp_dir):
I should
| |
163 return | |
164 shutil.rmtree(temp_dir, ignore_errors=True) | |
165 logging.info("Removed tempdir = %s",temp_dir) | |
scottz-goog
2010/11/05 01:22:46
empty lines between functions
Raja Aluri
2010/11/05 18:58:01
Done.
| |
166 def GenerateZipFile(base_name=None,format='zip',root_dir=None): | |
scottz-goog
2010/11/05 01:22:46
docstring
| |
167 if not base_name: | |
168 return False | |
scottz-goog
2010/11/05 01:22:46
same as above, if a function should never get a No
Raja Aluri
2010/11/05 18:58:01
Done.
| |
169 if not root_dir: | |
170 return False | |
171 logging.info("Generating zip file %s.zip with contents from %s", | |
172 base_name,root_dir) | |
173 current_dir = os.getcwd() | |
174 os.chdir(root_dir) | |
175 try: | |
176 output = subprocess.Popen(["zip", "-r","-9",base_name,'.'], | |
177 stdout=subprocess.PIPE).communicate()[0] | |
178 except OSError, e: | |
179 print >>sys.stderr, "Execution failed:", e | |
scottz-goog
2010/11/05 01:22:46
Why are we not using logging anymore?
Raja Aluri
2010/11/05 18:58:01
Done.
| |
180 os.chdir(current_dir) | |
scottz-goog
2010/11/05 01:22:46
This should be wrapped in a try: finally: so that
Raja Aluri
2010/11/05 18:58:01
Done.
| |
181 return False | |
scottz-goog
2010/11/05 01:22:46
Always return False?
Raja Aluri
2010/11/05 18:58:01
Mistake. Fixed
| |
182 | |
183 | |
184 def ExcludeBlacklist(library_list=None,black_list=None): | |
scottz-goog
2010/11/05 01:22:46
docstrings
Raja Aluri
2010/11/05 18:58:01
Done.
| |
185 if not library_list: | |
scottz-goog
2010/11/05 01:22:46
same as above with default arguments. Do you know
Raja Aluri
2010/11/08 17:57:17
Done.
| |
186 return None | |
187 if not black_list: | |
188 return library_list | |
189 return_list = [] | |
190 pattern = r'%s' % '|'.join(black_list) | |
191 logging.debug("PATTERN: %s=",pattern) | |
192 for library in library_list: | |
193 if re.search(pattern, library): | |
scottz-goog
2010/11/05 01:22:46
no need for regex or generating a regex pattern. U
Raja Aluri
2010/11/05 18:58:01
The values are not exact.
libc.so.1 -> we only loo
Raja Aluri
2010/11/08 17:57:17
This is not an exact match to the last dot. regex
| |
194 logging.debug("BLACK-LISTED = %s=",library) | |
195 else: | |
196 return_list.append(library) | |
scottz-goog
2010/11/05 01:22:46
You should continue in the if statement and the el
Raja Aluri
2010/11/08 17:57:17
Done.
| |
197 logging.debug("Returning return_list=%s=",return_list) | |
198 return return_list | |
199 | |
200 def SplitAndStrip(data=None): | |
scottz-goog
2010/11/05 01:22:46
default values, docstring..
The docstring should
Raja Aluri
2010/11/05 18:58:01
Done.
Raja Aluri
2010/11/08 17:57:17
Done.
| |
201 if not data: | |
202 return None | |
203 return_list = [] | |
204 for line in string.split(data,'\n'): | |
205 line = re.sub('.*not a dynamic executable.*','',line) | |
206 line = re.sub('.* =>\s+','',line) | |
207 line = re.sub('\(0x.*\)\s?','',line) | |
208 line = line.strip() | |
209 if not len(line): | |
210 continue | |
211 logging.debug("MATCHED line = %s",line) | |
212 return_list.append(line) | |
213 return return_list | |
214 | |
215 def CopyZipToFinalDestination(output_dir=None,zip_file_name=None): | |
216 """ | |
217 Copies the generated zip file to a final destination | |
218 Args: | |
219 output_dir: Directory where the file should be copied to | |
220 zip_file_name: name of the zip file that should be copied | |
221 Returns: | |
222 boolean | |
223 """ | |
224 if not output_dir: | |
scottz-goog
2010/11/05 01:22:46
defaults.
Looking thrugh this it doesn't look lik
Raja Aluri
2010/11/05 18:58:01
Done.
| |
225 logging.error("Empty output dir passed in. Returning False") | |
226 return False | |
227 | |
228 if not zip_file_name: | |
229 logging.error("Empty zip file name passed in. Returning False") | |
230 return False | |
231 | |
232 if not os.path.isfile(zip_file_name): | |
233 logging.error("Zip file %s doesn't exist. Returning False",zip_file_name) | |
234 return False | |
235 | |
236 if not os.path.isdir(output_dir): | |
237 logging.debug("Creating %s",output_dir) | |
238 os.makedirs(output_dir) | |
239 logging.info("Copying %s to %s",zip_file_name,output_dir) | |
240 shutil.copy2(zip_file_name,output_dir) | |
241 return True | |
242 def main(): | |
scottz-goog
2010/11/05 01:22:46
spaces
Raja Aluri
2010/11/05 18:58:01
Done.
| |
243 """ | |
244 Main function to start the script | |
245 """ | |
246 | |
247 #SetConsoleLogger() | |
scottz-goog
2010/11/05 01:22:46
Remove these
Raja Aluri
2010/11/05 18:58:01
Done.
Raja Aluri
2010/11/08 17:57:17
Done.
| |
248 #logging.info('Logging to Console...') | |
249 | |
250 parser = BuildOptions() | |
251 (options, args) = parser.parse_args() | |
252 if not ValidateOptions(options, args): | |
253 parser.print_help() | |
254 sys.exit(1) | |
255 temp_dir = CreateTempDir() | |
256 dest_files_root = os.path.join(temp_dir,'au-generator') | |
scottz-goog
2010/11/05 01:22:46
Since you only use CreateTempDir for this purpose
Raja Aluri
2010/11/05 18:58:01
I also need the parent directory for storing the f
| |
257 os.makedirs(dest_files_root) | |
258 CopyRequiredFiles(dest_files_root=dest_files_root) | |
259 zip_file_name = os.path.join(temp_dir,options.zip_name) | |
260 GenerateZipFile(base_name=zip_file_name,root_dir=dest_files_root) | |
261 CopyZipToFinalDestination(output_dir=options.output_dir, | |
262 zip_file_name=zip_file_name) | |
263 if not options.keep_temp: | |
264 CleanUP(temp_dir=temp_dir) | |
265 | |
266 if __name__ == '__main__': | |
267 try: | |
268 main() | |
269 except Exception: | |
270 raise | |
OLD | NEW |