Current File : //lib64/nagios/plugins/nccustom/check_software_updates |
#!/usr/libexec/platform-python
# vim:ts=4:sts=4:sw=4:et
#
# Author: Hari Sekhon
# Date: 2008-04-29 17:21:08 +0100 (Tue, 29 Apr 2008)
#
# https://github.com/HariSekhon/Nagios-Plugins
#
# License: see accompanying LICENSE file
#
# If you're using my code you're welcome to connect with me on LinkedIn
# and optionally send me feedback to help steer this or other code I publish
#
# https://www.linkedin.com/in/HariSekhon
#
"""
Nagios plugin to test for Yum updates on RedHat / CentOS Linux.
Can optionally alert on any available updates as well as just security related updates
Updated for DNF on RHEL 8
Tested on CentOS 5 / 6 / 7 / 8, Rocky Linux 8, Alma Linux 8
"""
# Updates Info vs RHEL versions (Caveat - contrary to that page, 'yum updateinfo' isn't available on CentOS 6):
#
# https://access.redhat.com/solutions/10021
from __future__ import print_function
import os
import re
import sys
import signal
OLD_PYTHON = False
# pylint: disable=wrong-import-position
try:
from subprocess import Popen, PIPE, STDOUT
except ImportError:
OLD_PYTHON = True
# pylint: disable=ungrouped-imports
try:
# Python 2
from commands import getstatusoutput # pylint: disable=no-name-in-module
except ImportError:
# Python 3
from subprocess import getstatusoutput # pylint: disable=no-name-in-module
from optparse import OptionParser
__author__ = "Hari Sekhon"
__title__ = "Nagios Plugin for Yum updates on RedHat/CentOS systems"
__version__ = "0.12.6"
# Standard Nagios return codes
OK = 0
WARNING = 1
CRITICAL = 2
UNKNOWN = 3
DEFAULT_TIMEOUT = 30
DEFAULT_WARNINGS_SIZE = 1
DEFAULT_CRITICAL_SIZE = None
support_msg = "Please make sure you have upgraded to the latest version from " + \
"https://github.com/HariSekhon/Nagios-Plugins. If the problem persists, " + \
"please raise a ticket at https://github.com/HariSekhon/Nagios-Plugins/issues "+ \
"with the full -vvv output"
def end(status, message): # lgtm [py/similar-function]
"""Exits the plugin with first arg as the return code and the second
arg as the message to output"""
check = "YUM "
if status == OK:
print("%sOK: %s" % (check, message))
sys.exit(OK)
elif status == WARNING:
print("%sWARNING: %s" % (check, message))
sys.exit(WARNING)
elif status == CRITICAL:
print("%sCRITICAL: %s" % (check, message))
sys.exit(CRITICAL)
else:
print("UNKNOWN: %s" % message)
sys.exit(UNKNOWN)
YUM = "/usr/bin/yum"
DNF = '/usr/bin/dnf'
def check_yum_usable():
"""Checks that the YUM program and path are correct and usable - that
the program exists and is executable, otherwise exits with error"""
if not os.path.exists(YUM):
end(UNKNOWN, "%s cannot be found" % YUM)
elif not os.path.isfile(YUM):
end(UNKNOWN, "%s is not a file" % YUM)
elif not os.access(YUM, os.X_OK):
end(UNKNOWN, "%s is not executable" % YUM)
# maintain Python 2 compatability
# pylint: disable=useless-object-inheritance,too-many-instance-attributes
class YumTester(object):
"""Class to hold all portage test functions and state"""
def __init__(self):
"""Initialize all object variables"""
self.all_updates = False
self.no_cache_update = False
self.no_warn_on_lock = False
self.enable_repo = ""
self.disable_repo = ""
self.disable_plugin = ""
self.yum_config = ""
self.timeout = DEFAULT_TIMEOUT
self.warnings_size = DEFAULT_WARNINGS_SIZE
self.criticals_size = DEFAULT_CRITICAL_SIZE
self.verbosity = 0
self.warn_on_any_update = False
def validate_all_variables(self):
"""Validates all object variables to make sure the
environment is sane"""
if self.timeout is None:
self.timeout = DEFAULT_TIMEOUT
try:
self.timeout = int(self.timeout)
except ValueError:
end(UNKNOWN, "Timeout must be an whole number, " \
+ "representing the timeout in seconds")
if self.timeout < 1 or self.timeout > 3600:
end(UNKNOWN, "Timeout must be a number between 1 and 3600 seconds")
# Warning size;
if self.warnings_size is None:
self.warnings_size = DEFAULT_WARNINGS_SIZE
try:
self.warnings_size = int(self.warnings_size)
except ValueError:
end(UNKNOWN, "Warnings size must be an whole number")
if self.warnings_size < 1:
end(UNKNOWN, "Warnings must be a number bigger than 1")
# Critical size;
if self.criticals_size is not None:
try:
self.criticals_size = int(self.criticals_size)
except ValueError:
end(UNKNOWN, "Criticals size must be an whole number")
if self.criticals_size < 1:
end(UNKNOWN, "Criticals must be a number bigger than 1")
if self.verbosity is None:
self.verbosity = 0
try:
self.verbosity = int(self.verbosity)
if self.verbosity < 0:
raise ValueError
except ValueError:
end(UNKNOWN, "Invalid verbosity type, must be positive numeric " \
+ "integer")
def run(self, cmd):
"""runs a system command and returns
an array of lines of the output"""
if not cmd:
end(UNKNOWN, "Internal python error - " \
+ "no cmd supplied for run function")
if 'updateinfo' not in cmd:
if self.no_cache_update:
cmd += " -C"
if self.enable_repo:
for repo in self.enable_repo.split(","):
cmd += " --enablerepo=%s" % repo
if self.disable_repo:
for repo in self.disable_repo.split(","):
cmd += " --disablerepo=%s" % repo
if self.disable_plugin:
# --disableplugin can take a comma separated list directly
#for plugin in self.disable_plugin.split(","):
#cmd += " --disableplugin=%s" % plugin
cmd += " --disableplugin=%s" % self.disable_plugin
if self.yum_config:
for repo in self.yum_config.split(","):
cmd += " --config=%s" % repo
self.vprint(3, "running command: %s" % cmd)
if OLD_PYTHON:
self.vprint(3, "subprocess not available, probably old python " \
+ "version, using shell instead")
os.environ['LANG'] = "en_US"
returncode, stdout = getstatusoutput(cmd)
if returncode >= 256:
returncode = returncode / 256
else:
try:
process = Popen(cmd.split(), stdin=PIPE, stdout=PIPE, stderr=STDOUT)
except OSError as error:
error = str(error)
if error == "No such file or directory":
end(UNKNOWN, "Cannot find utility '%s'" % cmd.split()[0])
end(UNKNOWN, "Error trying to run utility '%s' - %s" \
% (cmd.split()[0], error))
# don't comment this out even when replacing content as it'll pass None returncode to check_returncode
# which will then fail the check
output = process.communicate()
# for using debug outputs, either do not comment above line or explicitly set exit code below
#output = [open(os.path.dirname(__file__) + '/yum_input.txt').read(), '']
returncode = process.returncode
stdout = output[0]
# decode bytes to string for Python 3
stdout = stdout.decode("utf-8")
if not stdout:
end(UNKNOWN, "No output from utility '%s'" % cmd.split()[0])
self.vprint(3, "Returncode: '%s'\nOutput: '%s'" \
% (returncode, stdout))
output = str(stdout).split("\n")
for _ in output:
if 'Permission denied' in _:
end(UNKNOWN, _)
elif 'Skipping unreadable repository' in _:
end(UNKNOWN, _)
self.check_returncode(returncode, output)
return output
def check_returncode(self, returncode, output):
"""Takes the returncode and output (as an array of lines)
of the yum program execution and tests for failures, exits
with an appropriate message if any are found"""
if returncode == 0:
for line in output:
if "You must run this command as root" in line:
end(UNKNOWN, "You must run this plugin as root")
elif returncode == 100:
# Updates Available
pass
elif returncode == 200:
if "lock" in output[-2] or "another copy is running" in output[-2]:
msg = "Cannot check for updates, " \
+ "another instance of yum is running"
if self.no_warn_on_lock:
end(OK, msg)
else:
end(WARNING, msg)
else:
output = self.strip_output(output)
end(UNKNOWN, "%s" % output)
else:
if 'No more mirrors to try' in output:
end(UNKNOWN, 'connectivity issue to repos: \'No more mirrors to try\'. ' + \
'You could also try running --cache-only and ' + \
'scheduling a separate \'yum makecache\' via cron or similar')
elif "Command line error: no such option: --security" in output or \
(not ('Loading "security" plugin' in output or 'Loaded plugins:.*security' in output) \
and not os.path.exists(DNF)):
end(UNKNOWN, "Security plugin for yum is required. Try to " \
+ "'yum install yum-security' (RHEL5) or " \
+ "'yum install yum-plugin-security' (RHEL6) and then re-run " \
+ "this plugin. Alternatively, to just alert on " \
+ "any update which does not require the security " \
+ "plugin, try --all-updates")
else:
output = self.strip_output(output)
end(UNKNOWN, "exit code: %s, output: %s" % (returncode, output))
def strip_output(self, output):
"""Cleans up the output from the plugin and returns it.
Takes and returns an array of the lines of output
and returns a single string"""
self.vprint(3, "stripping output of 'Loading ... plugin' lines")
re_loading_plugin = re.compile("^Loading .+ plugin$")
output = [re_loading_plugin.sub("", line) for line in output]
output = " ".join(output).strip()
return output
def set_timeout(self):
"""sets an alarm to time out the test"""
if self.timeout == 1:
self.vprint(3, "setting plugin timeout to %s second" \
% self.timeout)
else:
self.vprint(3, "setting plugin timeout to %s seconds"\
% self.timeout)
signal.signal(signal.SIGALRM, self.sighandler)
signal.alarm(self.timeout)
def sighandler(self, _discarded, _discarded2):
"""Function to be called by signal.alarm to kill the plugin"""
end(CRITICAL, "Yum nagios plugin has self terminated after " \
+ "exceeding the timeout (%s seconds)" % self.timeout)
def get_updates(self):
"""Checks for updates and returns a tuple containing the number of
security updates and the number of total updates"""
self.vprint(2, "checking for any security updates")
if self.all_updates:
num_security_updates, num_other_updates = \
self.get_all_updates()
else:
num_other_updates = self.get_security_updates()
num_security_updates = 0
return num_security_updates, num_other_updates
def get_all_updates(self):
"""Gets all updates. Returns a single integer of the
number of available updates"""
cmd = "%s check-update" % YUM
output = self.run(cmd)
output2 = [_ for _ in "\n".join(output).split("\n\n") if _]
if self.verbosity >= 4:
for section in output2:
print("\nSection:\n%s\n" % section)
# used to be len(output2) > 2 but CentOS 8 has a condition
# where is has a blank line and then another line with 'yum.noarch 4.7.0-4.el8 baseos'
if len(output2) > 3 or (not self.no_cache_update and \
not ("Setting up repositories" in output2[0] or \
"Loaded plugins: " in output2[0] or \
"Last metadata expiration check" in output2[0] or \
"Updating Subscription Management repositories" in output2[0] or \
re.search(r'Loading\s+".+"\s+plugin', output2[0]))):
end(WARNING, "Yum output signature does not match current known format. " + support_msg)
num_packages = 0
if len(output2) == 1 and not self.no_cache_update:
# There are no updates but we have passed
# the loading and setting up of repositories
pass
else:
for line in '\n'.join(output2[1:]).split("\n"):
if len(line.split()) > 1 and \
line[0:1] != " " and \
"Obsoleting Packages" not in line:
num_packages += 1
# Extra layer of checks. This is a security plugin so it's preferable
# to fail on error rather than pass silently leaving you with an
# insecure system
count = 0
re_kernel_security_update = re.compile('^Security: kernel-.+ is an installed security update')
re_kernel_update = re.compile('^Security: kernel-.+ is the currently running version')
re_package_format = \
re.compile(r'^.+\.(i[3456]86|x86_64|noarch)\s+.+\s+.+$')
# This is to work around a yum truncation issue effectively changing
# the package output format. Currently only very long kmod lines
# are seen to have caused this so we stick to what we know for safety
# and raise an unknown error on anything else for maximum security
#re_package_format_truncated = \
# re.compile("^[\w-]+-kmod-\d[\d\.-]+.*\s+.+\s+.+$")
obsoleting_packages = False
for line in output:
# pylint: disable=no-else-continue
if ' excluded ' in line:
continue
elif obsoleting_packages and line[0:1] == " ":
continue
elif "Obsoleting Packages" in line:
obsoleting_packages = True
continue
elif re_kernel_security_update.match(line):
end(WARNING, 'Kernel security update is installed but requires a reboot')
elif re_kernel_update.match(line):
continue
if re_package_format.match(line):
count += 1
if count != num_packages:
end(UNKNOWN, "Error parsing package information, inconsistent " \
+ "package count (%d count vs %s num packages)" % (count, num_packages) \
+ ", yum output may have changed. " + support_msg)
return num_packages
def get_security_updates(self):
"""Gets all updates, but differentiates between
security and normal updates. Returns a tuple of the number
of security and normal updates"""
cmd = "%s --security check-update" % YUM
output = self.run(cmd)
re_security_summary = \
re.compile(r'Needed (\d+) of (\d+) packages, for security')
re_summary_rhel6 = re.compile(r'(\d+) package\(s\) needed for security, out of (\d+) available')
re_no_sec_updates = re.compile(r'No packages needed,? for security[;,] (\d+) (?:packages )?available')
re_no_sec_updates_dnf = re.compile(r'No security updates needed, but (\d+) updates available')
re_kernel_update = re.compile(r'^Security: kernel-.+ is an installed security update')
summary_line_found = False
for line in output:
_ = re_summary_rhel6.match(line)
if _:
summary_line_found = True
num_security_updates = _.group(1)
num_total_updates = _.group(2)
break
_ = re_no_sec_updates.match(line)
if _:
summary_line_found = True
num_security_updates = 0
num_total_updates = _.group(1)
break
_ = re_no_sec_updates_dnf.match(line)
if _:
summary_line_found = True
num_security_updates = 0
num_total_updates = _.group(1)
break
_ = re_security_summary.match(line)
if _:
summary_line_found = True
num_security_updates = _.group(1)
num_total_updates = _.group(2)
break
_ = re_kernel_update.match(line)
if _:
end(CRITICAL, "Kernel security update is installed but requires a reboot")
using_dnf = False
using_cloud_linux = False
if not summary_line_found:
if os.path.exists(DNF) and re.match('Last metadata expiration check: ', ''.join(output)):
using_dnf = True
num_total_updates = 0
# this will be updated to num non-excluded lines further down
num_security_updates = 0
elif os.path.exists(DNF) and re.match('Updating Subscription Management repositories.', ''.join(output)):
using_dnf = True
(num_security_updates, num_total_updates) = self.yum_updateinfo()
# for CloudLinux distro
#elif 'This system is receiving updates from CloudLinux Network server' in ''.join(output):
elif 'This system is receiving updates from CloudLinux' in ''.join(output):
using_cloud_linux = True
num_total_updates = 0
# this will be updated to num non-excluded lines further down
num_security_updates = 0
elif 'This system is receiving updates from ' in ''.join(output):
num_total_updates = 0
# default to zero unless we find package_lines further down
num_security_updates = 0
else:
end(WARNING, "Cannot find summary line in yum output. " + support_msg)
if 'num_security_updates' not in locals():
end(UNKNOWN, "parsing failed - number of security updates could not be determined. " + support_msg)
if 'num_total_updates' not in locals():
end(UNKNOWN, "parsing failed - number of total updates could not be determined. " + support_msg)
try:
num_security_updates = int(num_security_updates)
num_total_updates = int(num_total_updates)
except ValueError:
end(WARNING, "Error parsing package information, yum output " \
+ "may have changed. " + support_msg)
num_other_updates = num_total_updates - num_security_updates
excluded_regex = re.compile('|'.join(
[' from .+ excluded ',
r'^\s*\*\s*',
r'^\s*$',
'Determining fastest mirrors',
'^Including mirror:',
'Updating Subscription Management repositories',
'Last metadata expiration check',
'Loaded plugins',
'Loading mirror speeds from cached hostfile',
'Obsoleting Packages',
'Failed to set locale',
'security updates? needed',
'updates? available',
'packages? available',
'Limiting package lists to security relevant ones',
#'This system is receiving updates from RHN Classic or Red Hat Satellite.',
#'This system is receiving updates from CloudLinux Network server.',
'This system is receiving updates from .+',
r'Repo [\w-]+ forced skip_if_unavailable=\w+ due to',
r'Uploading Enabled Repositories Report',
r'^Red Hat\s+',
r'^EPEL\d+\s+',
#r'^gitlab_gitlab-[\w-]+\s+.+\s+|\s+.+\d+:\d+$',
r'^[\w-]+\s+.+\s+|\s+.+\d+:\d+$',
r'^\s*:\s+'
]))
output = [_ for _ in output if not excluded_regex.search(_)]
# only count unique packages (first token), as some packages are duplicated in their output,
# especially when on Redhat Network subscriptions, see sample output in #328
#
# Python 2.6 compatability for RHEL6 - don't use set comprehension, cast instead it's more portable
# pylint: disable=consider-using-set-comprehension
len_output = len(set([_.split()[0] for _ in output if _]))
if len_output > num_total_updates:
if using_dnf or using_cloud_linux:
num_security_updates = len_output
else:
self.vprint(3, "output lines not accounted for: %s" % output)
#self.vprint(3, "security updates: %s, total updates: %s" % (num_security_updates, num_total_updates))
end(WARNING, "Yum output signature (%s unique lines) is larger than number of total updates (%s). " \
% (len_output, num_total_updates) + support_msg)
return num_security_updates, num_other_updates
# Warning: yum updateinfo returns no output even when yum --security check-update returns
# 'No security updates needed, but 1 update available'
# so we are only calling this on Redhat Network subscriptions where we have a sample output in #328 from a user
def yum_updateinfo(self):
""" runs 'yum updateinfo' and returns a tuple of the number of security updates and total updates """
output = self.run('yum updateinfo')
# for using debug outputs
#output = open(os.path.dirname(__file__) + '/yuminfo_input.txt').read().split('\n')
#self.vprint(3, "yuminfo output: %s" % output)
num_total_updates = 0
num_security_updates = 0
re_security_notices = re.compile(r'^\s*(\d+)\s+Security notice')
re_bugfix_notices = re.compile(r'^\s*(\d+)\s+Bugfix notice')
#re_new_package_notices = r'^(\d+)\s+New Package notice'
#re_enhancement_notices = r'^(\d+)\s+Enhancement notice'
#if 'Updates Information Summary: available' in output:
for line in output:
_ = re_security_notices.match(line)
if _:
num_security_updates = int(_.group(1))
_ = re_bugfix_notices.match(line)
if _:
num_total_updates += int(_.group(1))
return (num_security_updates, num_total_updates)
def test_yum_updates(self):
"""Starts tests and controls logic flow"""
check_yum_usable()
self.vprint(3, "%s - Version %s\nAuthor: %s\n" \
% (__title__, __version__, __author__))
self.validate_all_variables()
self.set_timeout()
if self.all_updates:
return self.test_all_updates()
return self.test_security_updates()
def test_all_updates(self):
"""Tests for all updates, and returns a tuple
of the status code and output"""
#status = UNKNOWN
#message = "code error. " + support_msg
num_updates = self.get_all_updates()
if num_updates == 0:
status = OK
message = "0 Updates Available"
else:
status = CRITICAL
if num_updates == 1:
message = "1 Update Available"
else:
message = "%s Updates Available" % num_updates
message += " | total_updates_available=%s" % num_updates
return status, message
def test_security_updates(self):
"""Tests for security updates and returns a tuple
of the status code and output"""
#status = UNKNOWN
#message = "code error. " + support_msg
num_security_updates, num_other_updates = \
self.get_security_updates()
if num_security_updates == 0:
status = OK
message = "0 Security Updates Available"
else:
status = CRITICAL
if num_security_updates == 1:
message = "1 Security Update Available"
elif num_security_updates > 1:
message = "%s Security Updates Available" \
% num_security_updates
if num_other_updates != 0:
if self.warn_on_any_update and status != CRITICAL:
if self.criticals_size is not None:
# Ensure warnings_size cannot exceed criticals_size;
if self.warnings_size >= self.criticals_size:
raise ValueError("CRITICAL: The warning threshold cannot be greater than or equal to the critical threshold!")
if num_other_updates >= self.criticals_size:
status = CRITICAL
if num_other_updates >= self.warnings_size and status != CRITICAL:
status = WARNING
elif status != CRITICAL:
status = OK
# Get all number of all updates;
num_all_updates = self.get_all_updates()
not_sec_update = num_all_updates - num_security_updates
if num_other_updates == 1:
message += ". 1 Non-Security Update Available"
else:
message += ". %s Non-Security Updates Available" \
% not_sec_update
message += " | security_updates_available=%s non_security_updates_available=%s total_updates_available=%s" \
% (num_security_updates, not_sec_update, num_all_updates)
return status, message
def vprint(self, threshold, message):
"""Prints a message if the first arg is numerically greater than the
verbosity level"""
if self.verbosity is None:
self.verbosity = 0
if self.verbosity >= threshold:
print("%s" % message)
def main():
"""Parses command line options and calls the test function"""
tester = YumTester()
parser = OptionParser()
parser.add_option("-A",
"--all-updates",
action="store_true",
dest="all_updates",
help="Does not distinguish between security and " \
+ "non-security updates, but returns critical for " \
+ "any available update. This may be used if the " \
+ "yum security plugin is absent or you want to " \
+ "maintain every single package at the latest " \
+ "version. You may want to use " \
+ "--warn-on-any-update instead of this option")
parser.add_option("-W",
"--warn-on-any-update",
action="store_true",
dest="warn_on_any_update",
help="Warns if there are any (non-security) package " \
+ "updates available. By default only warns when " \
+ "security related updates are available. If " \
+ "--all-updates is used, then this option is " \
+ "redundant as --all-updates will return a " \
+ "critical result on any available update, " \
+ "whereas using this switch still allows you to " \
+ "differentiate between the severity of updates ")
parser.add_option("-C",
"--cache-only",
action="store_true",
dest="no_cache_update",
help="Run entirely from cache and do not update the " \
+ "cache when running yum. Useful if you have " \
+ "'yum makecache' cronned so that the nagios " \
+ "check itself doesn't have to do it, possibly " \
+ "speeding up execution (by 1-2 seconds in tests)")
parser.add_option("-c",
"--config",
dest="yum_config",
help="Run with custom repository config in order to use " \
+ "custom repositories in case of special setup for")
parser.add_option("-N",
"--no-warn-on-lock",
action="store_true",
dest="no_warn_on_lock",
help="Return OK instead of WARNING when yum is locked " \
+ "and fails to check for updates due to another " \
+ "instance running. This is not recommended from " \
+ "the security standpoint, but may be wanted to " \
+ "reduce the number of alerts that may " \
+ "intermittently pop up when someone is running " \
+ "yum for package management")
parser.add_option("-e",
"--enablerepo",
dest="repository_to_enable",
help="Explicitly enables a reposity when calling yum. " +
"Can take a comma separated list of repositories")
parser.add_option("-d",
"--disablerepo",
dest="repository_to_disable",
help="Explicitly disables a repository when calling yum. " \
+ "Can take a comma separated list of repositories")
parser.add_option("--disableplugin",
dest="plugin_to_disable",
help="Explicitly disables a plugin when calling yum. " \
+ "Can take a comma separated list of plugins")
parser.add_option("-t",
"--timeout",
dest="timeout",
help="Sets a timeout in seconds after which the " \
+"plugin will exit (defaults to %s seconds). " \
% DEFAULT_TIMEOUT)
parser.add_option("-w",
"--warnings_size",
dest="warnings_size",
help="Sets a warning size, if size bigger or equal " \
+"we will get WARNING for non security updates (defaults to %s warning). " \
% DEFAULT_WARNINGS_SIZE)
parser.add_option("-r",
"--criticals_size",
dest="criticals_size",
help="Sets a critical size, if size bigger or equal " \
+"we will get CRITICAL for non security updates (defaults to %s warning). " \
% DEFAULT_CRITICAL_SIZE)
parser.add_option("-v",
"--verbose",
action="count",
dest="verbosity",
help="Verbose mode. Can be used multiple times to " \
+ "increase output. Use -vvv for debugging output. " \
+ "By default only one result line is printed as " \
+ "per Nagios standards")
parser.add_option("-V",
"--version",
action="store_true",
dest="version",
help="Print version number and exit")
parser.add_option("-D",
"--debug",
action="store_true",
dest="debug",
help="Debug mode (same as -vvv)")
(options, args) = parser.parse_args()
if args:
parser.print_help()
sys.exit(UNKNOWN)
tester.all_updates = options.all_updates
tester.no_cache_update = options.no_cache_update
tester.no_warn_on_lock = options.no_warn_on_lock
tester.enable_repo = options.repository_to_enable
tester.disable_repo = options.repository_to_disable
tester.disable_plugin = options.plugin_to_disable
tester.yum_config = options.yum_config
tester.timeout = options.timeout
tester.warnings_size = options.warnings_size
tester.criticals_size = options.criticals_size
tester.verbosity = options.verbosity
tester.warn_on_any_update = options.warn_on_any_update
if options.debug or ('DEBUG' in os.environ and os.environ['DEBUG']):
tester.verbosity = 3
if options.version:
print("%s - Version %s\nAuthor: %s\n" \
% (__title__, __version__, __author__))
sys.exit(OK)
result, output = tester.test_yum_updates()
end(result, output)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("Caught Control-C...")
sys.exit(CRITICAL)