- Introduce a new ignore option
- Handle properly reading from the spawned dpkg-query processes to prevent blocking
Javier Fernandez-Sanguino
11 years ago
58 | 58 | return 1 |
59 | 59 | |
60 | 60 | def usage(): |
61 | sys.stderr.write('usage: checkrestart [-vhpa]\n') | |
61 | sys.stderr.write('usage: checkrestart [-vhpa] [-bblacklist] [-iignore]\n') | |
62 | 62 | |
63 | 63 | def main(): |
64 | 64 | global lc_all_c_env, file_query_check |
70 | 70 | file_query_check = {} |
71 | 71 | blacklistFiles = [] |
72 | 72 | blacklist = [] |
73 | ignorelist = [] | |
73 | 74 | |
74 | 75 | # Process options |
75 | 76 | try: |
76 | opts, args = getopt.getopt(sys.argv[1:], "hvpab:", ["help", "verbose", "packages", "all", "blacklist"]) | |
77 | opts, args = getopt.getopt(sys.argv[1:], "hvpab:i:", ["help", "verbose", "packages", "all", "blacklist", "ignore"]) | |
77 | 78 | except getopt.GetoptError, err: |
78 | 79 | # print help information and exit: |
79 | 80 | print str(err) # will print something like "option -x not recognized" |
102 | 103 | elif o in ("-b", "--blacklist"): |
103 | 104 | blacklistFiles.append(a) |
104 | 105 | onlyPackageFiles = False |
106 | elif o in ("-i", "--ignore"): | |
107 | ignorelist.append(a) | |
105 | 108 | else: |
106 | 109 | assert False, "unhandled option" |
107 | 110 | |
149 | 152 | |
150 | 153 | packages = {} |
151 | 154 | diverted = None |
155 | ||
152 | 156 | dpkgQuery = ["dpkg-query", "--search"] + programs.keys() |
153 | dpkgProc = subprocess.Popen(dpkgQuery, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, | |
157 | dpkgProc = subprocess.Popen(dpkgQuery, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, | |
154 | 158 | env = lc_all_c_env) |
155 | dpkgProc.wait() | |
156 | 159 | if verbose: |
157 | 160 | print "Running:%s" % dpkgQuery |
158 | for line in dpkgProc.stdout.readlines(): | |
159 | if line.startswith('local diversion'): | |
160 | continue | |
161 | ||
162 | m = re.match('^diversion by (\S+) (from|to): (.*)$', line) | |
163 | if m: | |
164 | if m.group(2) == 'from': | |
165 | diverted = m.group(3) | |
161 | while True: | |
162 | line = dpkgProc.stdout.readline() | |
163 | if not line: | |
164 | break | |
165 | if verbose: | |
166 | print "Reading line: %s" % line | |
167 | if line.startswith('local diversion'): | |
166 | 168 | continue |
167 | if not diverted: | |
168 | raise Exception('Weird error while handling diversion') | |
169 | packagename, program = m.group(1), diverted | |
170 | else: | |
171 | packagename, program = line[:-1].split(': ') | |
172 | if program == diverted: | |
173 | # dpkg prints a summary line after the diversion, name both | |
174 | # packages of the diversion, so ignore this line | |
175 | # mutt-patched, mutt: /usr/bin/mutt | |
169 | if not ':' in line: | |
176 | 170 | continue |
177 | 171 | |
178 | packages.setdefault(packagename,Package(packagename)) | |
179 | packages[packagename].processes.extend(programs[program]) | |
172 | m = re.match('^diversion by (\S+) (from|to): (.*)$', line) | |
173 | if m: | |
174 | if m.group(2) == 'from': | |
175 | diverted = m.group(3) | |
176 | continue | |
177 | if not diverted: | |
178 | raise Exception('Weird error while handling diversion') | |
179 | packagename, program = m.group(1), diverted | |
180 | else: | |
181 | packagename, program = line[:-1].split(': ') | |
182 | if program == diverted: | |
183 | # dpkg prints a summary line after the diversion, name both | |
184 | # packages of the diversion, so ignore this line | |
185 | # mutt-patched, mutt: /usr/bin/mutt | |
186 | continue | |
187 | packages.setdefault(packagename,Package(packagename)) | |
188 | try: | |
189 | packages[packagename].processes.extend(programs[program]) | |
190 | except KeyError: | |
191 | sys.stderr.write ('checkrestart (program not found): %s: %s\n' % (packagename, program)) | |
192 | sys.stdout.flush() | |
193 | ||
194 | # Close the pipe | |
195 | dpkgProc.stdout.close() | |
180 | 196 | |
181 | 197 | print "(%d distinct packages)" % len(packages) |
182 | 198 | |
186 | 202 | sys.exit(0) |
187 | 203 | |
188 | 204 | for package in packages.values(): |
189 | if package == 'util-linux': | |
205 | skip = False | |
206 | if package.name == 'util-linux': | |
207 | skip = True | |
208 | if ignorelist: | |
209 | for i in ignorelist: | |
210 | if i in package.name > 0: | |
211 | skip = True | |
212 | if skip: | |
190 | 213 | continue |
191 | 214 | dpkgQuery = ["dpkg-query", "--listfiles", package.name] |
192 | 215 | dpkgProc = subprocess.Popen(dpkgQuery, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, |
193 | 216 | env = lc_all_c_env) |
194 | dpkgProc.wait() | |
195 | for line in dpkgProc.stdout.readlines(): | |
217 | while True: | |
218 | line = dpkgProc.stdout.readline() | |
219 | if not line: | |
220 | break | |
196 | 221 | path = line[:-1] |
197 | 222 | if path.startswith('/etc/init.d/'): |
198 | 223 | if path.endswith('.sh'): |
199 | 224 | continue |
200 | 225 | package.initscripts.add(path[12:]) |
226 | sys.stdout.flush() | |
227 | dpkgProc.stdout.close() | |
228 | ||
201 | 229 | # Alternatively, find init.d scripts that match the process name |
202 | 230 | if len(package.initscripts) == 0: |
203 | 231 | for process in package.processes: |
236 | 264 | # TODO - consider putting this in a --verbose option |
237 | 265 | print "These processes do not seem to have an associated init script to restart them:" |
238 | 266 | for package in nonrestartable: |
267 | skip = False | |
268 | if ignorelist: | |
269 | for i in ignorelist: | |
270 | if i in package.name > 0: | |
271 | skip = True | |
272 | if skip: | |
273 | continue | |
239 | 274 | print package.name + ':' |
240 | 275 | for process in package.processes: |
241 | 276 | print "\t%s\t%s" % (process.pid,process.program) |