104 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env python
 | |
| 
 | |
| # Check for freshness of various components using needrestart
 | |
| 
 | |
| import subprocess
 | |
| import re
 | |
| import json
 | |
| 
 | |
| try:
 | |
|     nrout = subprocess.run(["/usr/sbin/needrestart", "-b"], timeout=5, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 | |
| except subprocess.TimeoutExpired:
 | |
|     exit(2)
 | |
| except Exception:
 | |
|     exit(1)
 | |
| 
 | |
| stdout = nrout.stdout.decode("ascii").split('\n')
 | |
| stderr = nrout.stdout.decode("ascii").split('\n')
 | |
| 
 | |
| # Output data structure after parsing needrestart output
 | |
| data = {
 | |
|     'kernel': {
 | |
|         'current': None,
 | |
|         'pending': None,
 | |
|         'state': 0,
 | |
|     },
 | |
|     'microcode': {
 | |
|         'current': None,
 | |
|         'pending': None,
 | |
|         'state': 0,
 | |
|     },
 | |
|     'services': {
 | |
|         'count': 0,
 | |
|         'list': list(),
 | |
|     },
 | |
|     'containers': {
 | |
|         'count': 0,
 | |
|         'list': list(),
 | |
|     },
 | |
|     'sessions': {
 | |
|         'count': 0,
 | |
|         'list': list(),
 | |
|     },
 | |
| }
 | |
| 
 | |
| # NEEDRESTART-VER: 3.4
 | |
| # NEEDRESTART-KCUR: 4.19.0-6-amd64
 | |
| # NEEDRESTART-KEXP: 4.19.0-20-amd64
 | |
| # NEEDRESTART-KSTA: 3
 | |
| # NEEDRESTART-UCSTA: 2
 | |
| # NEEDRESTART-UCCUR: 0xb000038
 | |
| # NEEDRESTART-UCEXP: 0xb000040
 | |
| # NEEDRESTART-SVC: acpid
 | |
| # NEEDRESTART-SVC: cron
 | |
| # NEEDRESTART-SVC: irqbalance
 | |
| # NEEDRESTART-SVC: mcelog
 | |
| # NEEDRESTART-SVC: munin-node
 | |
| # NEEDRESTART-SVC: ntp
 | |
| # NEEDRESTART-SVC: ssh
 | |
| # NEEDRESTART-SVC: syslog-ng
 | |
| # NEEDRESTART-SVC: trousers
 | |
| # NEEDRESTART-SVC: watchdog
 | |
| # NEEDRESTART-SVC: wd_keepalive
 | |
| # NEEDRESTART-CONT: LXC web1
 | |
| # NEEDRESTART-SESS: metabase @ user manager service
 | |
| # NEEDRESTART-SESS: root @ session #28017
 | |
| 
 | |
| # STA:
 | |
| #  0: unknown or failed to detect
 | |
| #  1: no pending upgrade
 | |
| #  2: ABI compatible upgrade pending
 | |
| #  3: version upgrade pending
 | |
| 
 | |
| for line in stdout:
 | |
|     # Kernel version
 | |
|     if re.match(r'^NEEDRESTART-KSTA', line):
 | |
|         data['kernel']['state'] = int(line.split(': ')[-1])
 | |
|     elif re.match(r'^NEEDRESTART-KCUR', line):
 | |
|         data['kernel']['current'] = line.split(': ')[-1]
 | |
|     elif re.match(r'^NEEDRESTART-KEXP', line):
 | |
|         data['kernel']['pending'] = line.split(': ')[-1]
 | |
|     # Microcode version
 | |
|     elif re.match(r'^NEEDRESTART-UCSTA', line):
 | |
|         data['microcode']['state'] = int(line.split(': ')[-1])
 | |
|     elif re.match(r'^NEEDRESTART-UCCUR', line):
 | |
|         data['microcode']['current'] = line.split(': ')[-1]
 | |
|     elif re.match(r'^NEEDRESTART-UCEXP', line):
 | |
|         data['microcode']['pending'] = line.split(': ')[-1]
 | |
|     # Services needing restart
 | |
|     elif re.match(r'^NEEDRESTART-SVC', line):
 | |
|         data['services']['count'] += 1
 | |
|         data['services']['list'].append(' '.join(line.split(': ')[1:]))
 | |
| 	# Containers needing restart
 | |
|     elif re.match(f'^NEEDRESTART-CONT', line):
 | |
|         data['containers']['count'] += 1
 | |
|         data['containers']['list'].append(' '.join(line.split(': ')[1:]))
 | |
|     # Sessions needing restart
 | |
|     elif re.match(f'^NEEDRESTART-SESS', line):
 | |
|         data['sessions']['count'] += 1
 | |
|         data['sessions']['list'].append(' '.join(line.split(': ')[1:]))
 | |
| 
 | |
| print("<<<freshness>>>")
 | |
| print(json.dumps(data))
 | |
| exit(0)
 |