Codebase list debian-goodies / a419b46
Merge branch 'master' of git+ssh://git.debian.org/git/collab-maint/debian-goodies Axel Beckert 6 years ago
4 changed file(s) with 138 addition(s) and 42 deletion(s). Raw diff Collapse all Expand all
6565 return 1
6666
6767 def usage():
68 sys.stderr.write('usage: checkrestart [-vhpa] [ -b blacklist_file ] [ -i package_name ] [ -e pid ]\n')
68 sys.stderr.write('usage: checkrestart [-vhpam] [ -b blacklist_file ] [ -i package_name ] [ -e pid ]\n')
6969
7070 def main():
7171 global lc_all_c_env, file_query_check
8484
8585 # Process options
8686 try:
87 opts, args = getopt.getopt(sys.argv[1:], "hvpab:i:ne:", ["help", "verbose", "packages", "all", "blacklist", "ignore", "nolsof", "excludepid"])
87 opts, args = getopt.getopt(sys.argv[1:], "hvpamb:i:ne:t", ["help", "verbose", "packages", "all", "machine", "blacklist", "ignore", "nolsof", "excludepid", "terse"])
8888 except getopt.GetoptError as err:
8989 # print help information and exit:
9090 print(err) # will print something like "option -x not recognized"
9898 onlyPackageFiles = False
9999 # Look for any deleted file
100100 allFiles = False
101 # Generate terse output, disabled by default
102 terseOutput = False
103 # Generate machine parsable output, disabled by default
104 machineOutput = False
101105
102106 for o, a in opts:
103107 if o in ("-v", "--verbose"):
112116 onlyPackageFiles = False
113117 elif o in ("-e", "--excludepid"):
114118 excludepidlist.append(a)
119 elif o in ("-m", "--machine"):
120 machineOutput = True
115121 elif o in ("-b", "--blacklist"):
116122 blacklistFiles.append(a)
117123 onlyPackageFiles = False
119125 ignorelist.append(a)
120126 elif o in ("-n", "--nolsof"):
121127 useLsof = False
128 elif o in ("-t", "--terse"):
129 terseOutput = True
122130 else:
123131 assert False, "unhandled option"
124132
149157 else:
150158 toRestart = lsoffilescheck(blacklist = blacklist)
151159
152
153 print("Found %d processes using old versions of upgraded files" % len(toRestart))
160 if terseOutput:
161 # Terse output and exit
162 # Use Nagios exit codes: 0 OK, 1 warning, 2 critical, 3 unknown
163 # we only care for 0 or 1
164 if len(toRestart):
165 print("%d processes using old versions of upgraded files" % len(toRestart))
166 sys.exit(1)
167 # Exit with no error if there is nothing to restart
168 print("No processes found using old versions of upgraded files")
169 sys.exit(0)
170
171 if not machineOutput:
172 print("Found %d processes using old versions of upgraded files" % len(toRestart))
173 else:
174 print("PROCESSES: %d" % len(toRestart))
154175
155176 if len(toRestart) == 0:
156177 sys.exit(0)
160181 programs.setdefault(process.program, [])
161182 programs[process.program].append(process)
162183
163 if len(programs) == 1:
164 print("(%d distinct program)" % len(programs))
184 if not machineOutput:
185 if len(programs) == 1:
186 print("(%d distinct program)" % len(programs))
187 else:
188 print("(%d distinct programs)" % len(programs))
165189 else:
166 print("(%d distinct programs)" % len(programs))
190 print("PROGRAMS: %d" % len(programs))
191
167192
168193 #services Verbose information
169194 if verbose:
170195 for process in toRestart:
171 print("[DEBUG] Process %s (PID: %d) " % (process.program, process.pid))
172 process.listDeleted()
196 if not machineOutput:
197 print("[DEBUG] Process %s (PID: %d) " % (process.program, process.pid))
198 process.listDeleted()
199 else:
200 process.listDeletedMachine()
173201
174202 packages = {}
175203 diverted = None
228256 except KeyError:
229257 continue
230258
231 print("(%d distinct packages)" % len(packages))
259 if not machineOutput:
260 print("(%d distinct packages)" % len(packages))
261 else:
262 print("PACKAGES: %d" % len(packages))
263
232264
233265 if len(packages) == 0:
234 print("No packages seem to need to be restarted.")
235 print("(please read checkrestart(1))")
266 if not machineOutput:
267 print("No packages seem to need to be restarted.")
268 print("(please read checkrestart(1))")
236269 sys.exit(0)
237270
238271 for package in list(packages.values()):
287320 nonrestartable.append(package)
288321
289322 if len(restartable) > 0:
290 print()
291 print("Of these, %d seem to contain systemd service definitions or init scripts which can be used to restart them." % len(restartable))
292 # TODO - consider putting this in a --verbose option
293 print("The following packages seem to have definitions that could be used\nto restart their services:")
294 for package in restartable:
295 print(package.name + ':')
296 for process in package.processes:
297 print("\t%s\t%s" % (process.pid,process.program))
298
299 if len(restartServiceCommands)>0:
323 if not machineOutput:
300324 print()
301 print("These are the systemd services:")
302 print('\n'.join(restartServiceCommands))
303 print()
304
305 if len(restartInitCommands)>0:
306 print("These are the initd scripts:")
307 print('\n'.join(restartInitCommands))
308 print()
325 print("Of these, %d seem to contain systemd service definitions or init scripts which can be used to restart them." % len(restartable))
326 # TODO - consider putting this in a --verbose option
327 print("The following packages seem to have definitions that could be used\nto restart their services:")
328 for package in restartable:
329 print(package.name + ':')
330 for process in package.processes:
331 print("\t%s\t%s" % (process.pid,process.program))
332
333 if len(restartServiceCommands)>0:
334 print()
335 print("These are the systemd services:")
336 print('\n'.join(restartServiceCommands))
337 print()
338
339 if len(restartInitCommands)>0:
340 print("These are the initd scripts:")
341 print('\n'.join(restartInitCommands))
342 print()
343 else:
344 for package in restartable:
345 for process in package.processes:
346 print('SERVICE:%s,%s,%s' % (package.name, process.pid,process.program))
309347
310348 if len(nonrestartable) == 0:
311349 sys.exit(0)
312350
313351 # TODO - consider putting this in a --verbose option
314 print("These processes (%d) do not seem to have an associated init script to restart them:" %len(nonrestartable))
352 if not machineOutput:
353 print("These processes (%d) do not seem to have an associated init script to restart them:" %len(nonrestartable))
315354 for package in nonrestartable:
316 print(package.name + ':')
317 for process in package.processes:
318 print("\t%s\t%s" % (process.pid,process.program))
355 if not machineOutput:
356 print(package.name + ':')
357 for process in package.processes:
358 print("\t%s\t%s" % (process.pid,process.program))
359 else:
360 for process in package.processes:
361 print('OTHER:%s,%s,%s' % (package.name,process.pid,process.program))
362
319363
320364 def lsoffilescheck(blacklist = None):
321365 # Use LSOF to extract the list of deleted files
707751 # print "Changing usr to " + newusr + " result:" +f; # Debugging
708752 return re.sub('( \(deleted\)|.dpkg-new).*$','',f)
709753
710 def listDeleted(self):
754 def listDeletedHelper(self):
711755 listfiles = []
712756 listdescriptors = []
713757 for f in self.files:
714758 if isdeletedFile(f):
715759 listfiles.append(f)
716 if listfiles != []:
717 print("List of deleted files in use:")
718 for file in listfiles:
719 print("\t" + file)
760 return listfiles
761 def listDeleted(self):
762 listfiles = self.listDeletedHelper()
763 if listfiles != []:
764 print "List of deleted files in use:"
765 for file in listfiles:
766 print "\t" + file
767 def listDeletedMachine(self):
768 listfiles = self.listDeletedHelper()
769 for file in listfiles:
770 print 'file\t%s\t%s\t%s' % (self.pid, self.program, file)
771
720772
721773 # Check if a process needs to be restarted, previously we would
722774 # just check if it used libraries named '.dpkg-new' since that's
1111 .SH NAME
1212 checkrestart \- check which processes need to be restarted after an upgrade
1313 .SH SYNOPSIS
14 .B checkrestart [ -hvpan ] [ -b blacklist_file ] [ -i package_name ] [ -e pid ]
14 .B checkrestart [ -hvpanmt ] [ -b blacklist_file ] [ -i package_name ] [ -e pid ]
1515 .SH DESCRIPTION
1616 The
1717 .B checkrestart
6161 simultaneously with the
6262 .B -p
6363 option.
64
65 .TP
66 \fB-m\fP, \fB\-\-machine\fP
67 Generate machine readable output. One line is printed per program which must be
68 restarted: "TYPE:package_name,pid,program". Where TYPE is
69 .B INIT
70 , if a systemd service file or an init script is available to restart the program, and
71 .B OTHER
72 otherwise.
6473
6574 .TP
6675 \fB\-b\fP \fIfile\fP, \fB\-\-blacklist=\fP\fIfile\fP
97106 .B lsof(8)
98107 installed.
99108
109 .TP
110 .BI -t, --terse
111 Terse output, just print the number of open deleted files and exit with a code
112 suitable for use by Nagios and similar monitoring tools (see Exit Status).
113
114
100115 .SH EXIT STATUS
101116
102 The program will exit with error (1) if a non-root user tries to run it. Otherwise,
117 Normally, the program will exit with error (1) if a non-root user tries to run it. Otherwise,
103118 it will always exit with error status 0.
119
120 If the \fI\-\-terse\fP switch is given, the exit code is 1 when there are deleted
121 open files and 0 when there are none. This is intended for consumption by Nagios and
122 similar automated monitoring tools.
123
104124
105125 .SH EXAMPLE
106126
157177 isc-dhcp-client:
158178 3775 /sbin/dhclient
159179
180 This is another example to show the machine-readable output:
181
182 # checkrestart --machine
183 PROCESSES: 4
184 PROGRAMS: 4
185 PACKAGES: 2
186 INIT:bcfg2-server,6974,/usr/sbin/bcfg2-server
187 INIT:exim4-daemon-light,857,/usr/sbin/exim4
188 OTHER:aptitude,11679,/usr/bin/aptitude-curses
189 OTHER:xscreensaver,6562,/usr/bin/xscreensaver
190
160191 .SH BUGS
161192 This program might fail if the output of the \fBlsof(8)\fP utility changes since it
162193 depends on it to detect which deleted files are used by processes. It might
22 [ Axel Beckert ]
33 * Set "Rules-Requires-Root: no".
44 * debian/copyright: Switch one previously overseen URL to HTTPS.
5
6 [ Javier Fernández-Sanguino ]
7 * checkrestart:
8 - Provide a switch (-m, --machine) to generate machine readable output
9 based on the patch provided by Simon Ruderich and incorporating the
10 suggestions from Tollef Fog Heen (Closes: #568359)
11 - Provide a switch (-t, --terse) to provide terse output with
12 Nagios exit codes to facilitate integration into Nagios based
13 on patch provided by Jonathan Wiltshire
14 * dman:
15 - Fix "not found" error reporting, broken in
16 27ac5129ce187c6f571cac25ef70553bb9c9d475 (Closes: #877137)
517
618 [ Nicolas Braud-Santoni ]
719 * checkrestart: Properly error-out when calling lsof or pmap
6161 fi
6262
6363 BASE_URL="https://dyn.manpages.debian.org"
64 URL="$BASE_URL/$DISTRIB_CODENAME/$PAGE$LOCDOT.gz"
6465
6566 mandir=`mktemp --tmpdir="${TMPDIR:-/tmp}" -d dman.XXXXXX`
6667 trap "rm -rf $mandir" EXIT HUP INT QUIT TERM
6768 man="$mandir/$PAGE"
68 if wget -O "$man" "$BASE_URL/$DISTRIB_CODENAME/$PAGE$LOCDOT.gz" 2>/dev/null; then
69 if wget -O "$man" "$URL" 2>/dev/null; then
6970 man $MAN_ARGS -l "$man" || true
7071 exit 0
7172 else