New plugin: check_apk for Alpine Linux
This commit is contained in:
parent
598eeab975
commit
fc37d736f5
177
check_apk.py
Executable file
177
check_apk.py
Executable file
|
@ -0,0 +1,177 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
#####################################################################
|
||||
# (c) 2016- by Sven Velt, Germany #
|
||||
# sven-mymonplugins@velt.biz #
|
||||
# #
|
||||
# This file is part of "velt.biz - My Monitoring Plugins" #
|
||||
# a fork of "team(ix) Monitoring Plugins" in 2015 #
|
||||
# URL: https://gogs.velt.biz/velt.biz/MyMonPlugins/ #
|
||||
# #
|
||||
# This file is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published #
|
||||
# by the Free Software Foundation, either version 2 of the License, #
|
||||
# or (at your option) any later version. #
|
||||
# #
|
||||
# This file is distributed in the hope that it will be useful, but #
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this file. If not, see <http://www.gnu.org/licenses/>. #
|
||||
#####################################################################
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
try:
|
||||
from MyMonPlugin import MonitoringPlugin
|
||||
except ImportError:
|
||||
print('==========================')
|
||||
print('AIKS! Python import error!')
|
||||
print('==========================\n')
|
||||
print('Could not find class "MonitoringPlugin"!\n')
|
||||
print('Did you download "%s"' % os.path.basename(sys.argv[0]))
|
||||
print('without "MyMonPlugin/"?\n')
|
||||
print('Please go back to')
|
||||
print('https://gogs.velt.biz/velt.biz/MyMonPlugins and:')
|
||||
print('- get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases')
|
||||
print('- or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n')
|
||||
sys.exit(127)
|
||||
|
||||
|
||||
plugin = MonitoringPlugin(
|
||||
pluginname='check_apk',
|
||||
tagforstatusline='APK',
|
||||
description='Check APK package manager for updates',
|
||||
version='0.1',
|
||||
)
|
||||
|
||||
plugin.add_cmdlineoption('-P', '--path-apk', 'apk', 'full path to apk', default='/sbin/apk')
|
||||
plugin.add_cmdlineoption('-S', '--sync-repo-index', 'sync_repo_index', 'sync repository index files at startup', default=False, action='store_true')
|
||||
plugin.add_cmdlineoption('', '--ignore-sync-failure', 'fail_on_sync_failure', 'ignore repo index sync failures', default=True, action='store_false')
|
||||
plugin.add_cmdlineoption('', '--sudo', 'sudo', 'call "apk" with sudo', default=False, action='store_true')
|
||||
|
||||
plugin.add_cmdlineoption('', '--mymonplugins-testmode', 'mymonplugins_testmode', None, default=False, action='store_true')
|
||||
|
||||
plugin.parse_cmdlineoptions()
|
||||
|
||||
##############################################################################
|
||||
##### Testmode
|
||||
|
||||
if plugin.options.mymonplugins_testmode:
|
||||
mymonplugins_testmode = {}
|
||||
|
||||
mymonplugins_testmode['apk update'] = '''fetch http://dl-cdn.alpinelinux.org/alpine/latest-stable/main/x86_64/APKINDEX.tar.gz
|
||||
fetch http://dl-cdn.alpinelinux.org/alpine/latest-stable/community/x86_64/APKINDEX.tar.gz
|
||||
v3.17.3-13-g98fa1f428e9 [http://dl-cdn.alpinelinux.org/alpine/latest-stable/main]
|
||||
v3.17.3-12-g492f704d069 [http://dl-cdn.alpinelinux.org/alpine/latest-stable/community]
|
||||
OK: 17824 distinct packages available
|
||||
'''.split('\n')
|
||||
|
||||
mymonplugins_testmode['apk -s upgrade'] = '''(1/6) Upgrading alpine-release (3.17.2-r0 -> 3.17.3-r0)
|
||||
(2/6) Upgrading libcrypto3 (3.0.8-r1 -> 3.0.8-r3)
|
||||
(3/6) Upgrading libssl3 (3.0.8-r1 -> 3.0.8-r3)
|
||||
(4/6) Upgrading alpine-base (3.17.2-r0 -> 3.17.3-r0)
|
||||
(5/6) Upgrading mkinitfs (3.7.0-r0 -> 3.7.0-r1)
|
||||
(6/6) Upgrading openssl (3.0.8-r1 -> 3.0.8-r3)
|
||||
OK: 258 MiB in 220 packages
|
||||
'''.split('\n')
|
||||
|
||||
##############################################################################
|
||||
|
||||
def run_command(cmdline, needs_sudo=False):
|
||||
tstart = time.time()
|
||||
if needs_sudo and plugin.options.sudo:
|
||||
new = ['sudo', '-n', '--']
|
||||
new.extend(cmdline)
|
||||
cmdline = new
|
||||
plugin.verbose(1, 'Running command line: %s' % subprocess.list2cmdline(cmdline))
|
||||
try:
|
||||
cmd = subprocess.Popen(
|
||||
cmdline,
|
||||
stdout = subprocess.PIPE,
|
||||
stderr = subprocess.PIPE
|
||||
)
|
||||
except OSError:
|
||||
plugin.back2nagios(plugin.RETURNCODE['UNKNOWN'], 'Could not execute command line: %s' % subprocess.list2cmdline(cmdline))
|
||||
|
||||
(sout,serr) = cmd.communicate()
|
||||
plugin.verbose(2, 'Runtime %.3fs' % (time.time() - tstart, ) )
|
||||
|
||||
sout = sout.rstrip().decode('utf-8').split('\n')
|
||||
if sout == ['']:
|
||||
sout = []
|
||||
serr = serr.rstrip().decode('utf-8').split('\n')
|
||||
if serr == ['']:
|
||||
serr = []
|
||||
|
||||
return( (sout, serr, cmd.returncode,) )
|
||||
|
||||
##############################################################################
|
||||
|
||||
if plugin.options.sync_repo_index:
|
||||
plugin.verbose(1, '-S/--sync_repo_index given')
|
||||
cmdline = [plugin.options.apk, 'update', '--no-progress',]
|
||||
(sout, serr, rc) = run_command(cmdline, needs_sudo=True)
|
||||
sout and plugin.verbose(3, sout, prefix='stdout: ')
|
||||
serr and plugin.verbose(3, serr, prefix='stderr: ')
|
||||
plugin.verbose(2, 'Return code: %d' % rc)
|
||||
if plugin.options.fail_on_sync_failure and (rc != 0 or 'ERROR:' in ' '.join(serr)):
|
||||
if 'Permission denied' in ' '.join(serr):
|
||||
plugin.back2nagios(plugin.RETURNCODE['CRITICAL'], 'Syncing of repository index files failed, permission denied. Do you need "--sudo"?', multiline=serr)
|
||||
plugin.back2nagios(plugin.RETURNCODE['CRITICAL'], 'Syncing of repository index files failed', multiline=serr)
|
||||
|
||||
##############################################################################
|
||||
|
||||
cmdline = [plugin.options.apk, 'upgrade', '--simulate', '--no-progress',]
|
||||
(sout, serr, rc) = run_command(cmdline)
|
||||
sout and plugin.verbose(3, sout, prefix='stdout: ')
|
||||
serr and plugin.verbose(3, serr, prefix='stderr: ')
|
||||
plugin.verbose(2, 'Return code: %d' % rc)
|
||||
|
||||
if plugin.options.sudo and 'sudo: ' in ' '.join(serr):
|
||||
# Running with sudo
|
||||
if rc == 1:
|
||||
# sudo RC 1: a password is required
|
||||
plugin.back2nagios(plugin.RETURNCODE['CRITICAL'], ' '.join(serr))
|
||||
if rc == 8:
|
||||
# RC 8: Transaction aborted due to unresolved shlibs.
|
||||
plugin.back2nagios(plugin.RETURNCODE['WARNING'], serr[-1], serr[:-1])
|
||||
elif rc not in [0, 6]:
|
||||
# RC 0: Packages to update
|
||||
# RC 6: Package(s) already installed
|
||||
plugin.back2nagios(plugin.RETURNCODE['WARNING'], 'Unknown returncode "%s", please contact the author of plugin or open an issue!' % rc)
|
||||
|
||||
action = {'Upgrading':[], 'Installing':[], 'Purging':[], }
|
||||
action_verb = {'Upgrading':'upgrade', 'Installing':'install', 'Purging':'purge', }
|
||||
|
||||
for line in sout[0:-1]:
|
||||
cols = line.split(' ')
|
||||
# Append package name to action type list
|
||||
action[cols[1]].append(cols[2])
|
||||
|
||||
if len(sout) == 1:
|
||||
plugin.remember_check('Updates', plugin.RETURNCODE['OK'], 'Everything uptodate')
|
||||
else:
|
||||
out = []
|
||||
multiline = []
|
||||
for act in list(action.keys()):
|
||||
pkgs = action.pop(act)
|
||||
pkgs.sort()
|
||||
l = len(pkgs)
|
||||
out.append('%s package%s to %s' % (l, l != 1 and 's' or '', action_verb[act]) )
|
||||
l and multiline.append('%s(%s): %s' % (act, l, ', '.join(pkgs)) )
|
||||
|
||||
out = ', '.join(out)
|
||||
|
||||
plugin.remember_check('Updates', plugin.RETURNCODE['CRITICAL'], out, multilineoutput=multiline)
|
||||
|
||||
# Exit
|
||||
plugin.brain2output()
|
||||
plugin.exit()
|
||||
|
Loading…
Reference in a new issue