check_xbps.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #!/usr/bin/env python2
  2. # -*- encoding: utf-8 -*-
  3. #####################################################################
  4. # (c) 2016 by Sven Velt, Germany #
  5. # sven-mymonplugins@velt.biz #
  6. # #
  7. # This file is part of "velt.biz - My Monitoring Plugins" #
  8. # a fork of "team(ix) Monitoring Plugins" in 2015 #
  9. # URL: https://gogs.velt.biz/velt.biz/MyMonPlugins/ #
  10. # #
  11. # This file is free software: you can redistribute it and/or modify #
  12. # it under the terms of the GNU General Public License as published #
  13. # by the Free Software Foundation, either version 2 of the License, #
  14. # or (at your option) any later version. #
  15. # #
  16. # This file is distributed in the hope that it will be useful, but #
  17. # WITHOUT ANY WARRANTY; without even the implied warranty of #
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
  19. # GNU General Public License for more details. #
  20. # #
  21. # You should have received a copy of the GNU General Public License #
  22. # along with this file. If not, see <http://www.gnu.org/licenses/>. #
  23. #####################################################################
  24. import subprocess
  25. import sys
  26. import time
  27. try:
  28. from monitoringplugin import MonitoringPlugin
  29. except ImportError:
  30. print '=========================='
  31. print 'AIKS! Python import error!'
  32. print '==========================\n'
  33. print 'Could not find "monitoringplugin.py"!\n'
  34. print 'Did you download "%s"' % os.path.basename(sys.argv[0])
  35. print 'without "monitoringplugin.py"?\n'
  36. print 'Please go back to'
  37. print 'https://gogs.velt.biz/velt.biz/MyMonPlugins and download it,'
  38. print 'or even better:'
  39. print 'get a full archive at http://gogs.velt.biz/velt.biz/MyMonPlugins/releases'
  40. print 'or a master snapshot at http://gogs.velt.biz/velt.biz/MyMonPlugins/archive/master.tar.gz\n'
  41. sys.exit(127)
  42. plugin = MonitoringPlugin(
  43. pluginname='check_xbps',
  44. tagforstatusline='XBPS',
  45. description='Check XBPS package manager for updates',
  46. version='0.1',
  47. )
  48. plugin.add_cmdlineoption('-P', '--path-xbps-install', 'xbps_install', 'full path to xbps-install', default='/usr/bin/xbps-install')
  49. plugin.add_cmdlineoption('-S', '--sync-repo-index', 'sync_repo_index', 'sync repository index files at startup', default=False, action='store_true')
  50. plugin.add_cmdlineoption('', '--ignore-sync-failure', 'fail_on_sync_failure', 'ignore repo index sync failures', default=True, action='store_false')
  51. plugin.add_cmdlineoption('', '--mymonplugins-testmode', 'mymonplugins_testmode', None, default=False, action='store_true')
  52. plugin.parse_cmdlineoptions()
  53. ##############################################################################
  54. ##### Testmode
  55. if plugin.options.mymonplugins_testmode:
  56. mymonplugins_testmode = {}
  57. mymonplugins_testmode['xbps-install -S'] = '''[*] Updating `https://repo.voidlinux.eu/current/x86_64-repodata' ...
  58. '''.split('\n')
  59. mymonplugins_testmode['xbps-install -un'] = '''elementary-1.17.1_1 remove x86_64 https://repo.voidlinux.eu/current 19821495 12302924
  60. bash-4.3.046_2 update x86_64 https://repo.voidlinux.eu/current 5019665 998440
  61. libllvm3.9-3.9.0_2 install x86_64 https://repo.voidlinux.eu/current 51052672 12480860
  62. linux4.7-4.7.4_1 install x86_64 https://repo.voidlinux.eu/current 61839987 55203908
  63. linux-4.7_1 update x86_64 https://repo.voidlinux.eu/current 624
  64. linux4.6-4.6.7_1 update x86_64 https://repo.voidlinux.eu/current 60995961 54434936
  65. lxc-2.0.4_1 update x86_64 https://repo.voidlinux.eu/current 1837102 468024'''.split('\n')
  66. ##############################################################################
  67. def run_command(cmdline):
  68. tstart = time.time()
  69. plugin.verbose(1, 'Running command line: %s' % subprocess.list2cmdline(cmdline))
  70. try:
  71. cmd = subprocess.Popen(
  72. cmdline,
  73. stdout = subprocess.PIPE,
  74. stderr = subprocess.PIPE
  75. )
  76. except OSError:
  77. plugin.back2nagios(plugin.RETURNCODE['UNKNOWN'], 'Could not execute command line: %s' % subprocess.list2cmdline(cmdline))
  78. (sout,serr) = cmd.communicate()
  79. plugin.verbose(2, 'Runtime %.3fs' % (time.time() - tstart, ) )
  80. sout = sout.rstrip().split('\n')
  81. if sout == ['']:
  82. sout = []
  83. serr = serr.rstrip().split('\n')
  84. if serr == ['']:
  85. serr = []
  86. return( (sout, serr, cmd.returncode,) )
  87. ##############################################################################
  88. if plugin.options.sync_repo_index:
  89. plugin.verbose(1, '-S/--sync_repo_index given')
  90. cmdline = [plugin.options.xbps_install, '-S',]
  91. (sout, serr, rc) = run_command(cmdline)
  92. sout and plugin.verbose(3, sout, prefix='stdout: ')
  93. serr and plugin.verbose(3, serr, prefix='stderr: ')
  94. plugin.verbose(2, 'Return code: %d' % rc)
  95. if rc != 0 and plugin.options.fail_on_sync_failure:
  96. plugin.back2nagios(plugin.RETURNCODE['CRITICAL'], 'Syncing of repository index files failed')
  97. ##############################################################################
  98. cmdline = [plugin.options.xbps_install, '-un',]
  99. (sout, serr, rc) = run_command(cmdline)
  100. sout and plugin.verbose(3, sout, prefix='stdout: ')
  101. serr and plugin.verbose(3, serr, prefix='stderr: ')
  102. plugin.verbose(2, 'Return code: %d' % rc)
  103. if rc == 8:
  104. # RC 8: Transaction aborted due to unresolved shlibs.
  105. plugin.back2nagios(plugin.RETURNCODE['WARNING'], serr[-1], serr[:-1])
  106. elif rc not in [0, 6]:
  107. # RC 0: Packages to update
  108. # RC 6: Package(s) already installed
  109. plugin.back2nagios(plugin.RETURNCODE['WARNING'], 'Unknown returncode "%s", please contact the author of plugin or open an issue!' % rc)
  110. action = {'remove':[], 'update':[], 'install':[],}
  111. arch = {}
  112. repo = {}
  113. downby = 0L
  114. for line in sout:
  115. cols = line.split(' ')
  116. # Append package name to action type list
  117. try:
  118. action[cols[1]].append(cols[0])
  119. except KeyError:
  120. action[cols[1]] = [ cols[0], ]
  121. # Count per arch
  122. try:
  123. arch[cols[2]] += 1
  124. except KeyError:
  125. arch[cols[2]] = 1
  126. # Count per repo
  127. try:
  128. repo[cols[3]] += 1
  129. except KeyError:
  130. repo[cols[3]] = 1
  131. # Count bytes to download
  132. if len(cols) == 5:
  133. downby += long(cols[4])
  134. else:
  135. downby += long(cols[5])
  136. if len(sout) == 0:
  137. plugin.remember_check('Updates', plugin.RETURNCODE['OK'], 'Everything uptodate')
  138. else:
  139. out = []
  140. multiline = []
  141. for act in ['update', 'install', 'remove']:
  142. pkgs = action.pop(act)
  143. pkgs.sort()
  144. l = len(pkgs)
  145. out.append('%s package%s to %s' % (l, l != 1 and 's' or '', act) )
  146. l and multiline.append('%s(%s): %s' % (act, l, ', '.join(pkgs)) )
  147. for act in action:
  148. pkgs = action.pop(act)
  149. pkgs.sort()
  150. l = len(pkgs)
  151. out.append('%s package%s to %s' % (l, l != 1 and 's' or '', act) )
  152. l and multiline.append('%s(%s): %s' % (act, l, ', '.join(pkgs)) )
  153. out = ', '.join(out)
  154. if downby:
  155. out += ' - %s to download' % plugin.value_to_human_binary(downby, 'B')
  156. stats = 'Statistics: '
  157. for (k, v) in arch.iteritems():
  158. stats += '%sx %s, ' % (v, k)
  159. for (k, v) in repo.iteritems():
  160. stats += '%s from %s, ' % (v, k)
  161. multiline.append(stats[:-2])
  162. plugin.remember_check('Updates', plugin.RETURNCODE['CRITICAL'], out, multilineoutput=multiline)
  163. # Exit
  164. plugin.brain2output()
  165. plugin.exit()