From 3ebbe5c55bfbe0316652abc5e8466e78bc89eb7a Mon Sep 17 00:00:00 2001 From: "M. Sean Finney" Date: Thu, 23 Mar 2006 00:01:29 +0000 Subject: more work on check_apt. more graceful error handling and information reporting, a couple new cmdline options. still not quite ready for prime-time, maybe tomorrow :) git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1348 f882894a-f735-0410-b71e-b25c423dba1c diff --git a/plugins/check_apt.c b/plugins/check_apt.c index 8d020f5..867fe41 100644 --- a/plugins/check_apt.c +++ b/plugins/check_apt.c @@ -33,15 +33,20 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; #define APTGET_UPGRADE "/usr/bin/apt-get -o 'Debug::NoLocking=true' -s -qq upgrade" #define APTGET_DISTUPGRADE "/usr/bin/apt-get -o 'Debug::NoLocking=true' -s -qq dist-upgrade" -#define APTGET_UPDATE "/usr/bin/apt-get update" +#define APTGET_UPDATE "/usr/bin/apt-get -q update" int process_arguments(int, char **); void print_help(void); void print_usage(void); +int run_update(void); int run_upgrade(int *pkgcount); static int verbose = 0; +static int do_update = 0; +static int dist_upgrade = 0; +static int stderr_warning = 0; +static int exec_warning = 0; int main (int argc, char **argv) { int result=STATE_UNKNOWN, packages_available=0; @@ -57,17 +62,31 @@ int main (int argc, char **argv) { /* handle timeouts gracefully... */ alarm (timeout_interval); + /* if they want to run apt-get update first... */ + if(do_update) result = run_update(); + /* apt-get upgrade */ - result = run_upgrade(&packages_available); + result = max_state(result, run_upgrade(&packages_available)); + + if(stderr_warning){ + fprintf(stderr, "warning, output detected on stderr. "); + fprintf(stderr, "re-run with -v for more information.\n"); + } if(packages_available > 0){ - result = STATE_WARNING; - printf("APT WARNING: "); + result = max_state(result, STATE_WARNING); } else { - result = STATE_OK; - printf("APT OK: "); + result = max_state(result, STATE_OK); } - printf("%d packages available for upgrade\n", packages_available); + + printf("APT %s: %d packages available for %s.%s%s%s\n", + state_text(result), + packages_available, + (dist_upgrade)?"dist-upgrade":"upgrade", + (stderr_warning)?" (warnings detected)":"", + (stderr_warning && exec_warning)?",":"", + (exec_warning)?" (errors detected)":"" + ); return result; } @@ -81,11 +100,13 @@ int process_arguments (int argc, char **argv) { {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'}, {"timeout", required_argument, 0, 't'}, + {"update", no_argument, 0, 'u'}, + {"dist-upgrade", no_argument, 0, 'd'}, {0, 0, 0, 0} }; while(1) { - c = getopt_long(argc, argv, "hVvt", longopts, NULL); + c = getopt_long(argc, argv, "hVvt:ud", longopts, NULL); if(c == -1 || c == EOF || c == 1) break; @@ -102,6 +123,12 @@ int process_arguments (int argc, char **argv) { case 't': timeout_interval=atoi(optarg); break; + case 'd': + dist_upgrade=1; + break; + case 'u': + do_update=1; + break; default: /* print short usage statement if args not parsable */ usage_va(_("Unknown argument - %s"), optarg); @@ -123,15 +150,21 @@ found in Debian GNU/Linux\n\ \n\n")); print_usage(); printf(_(UT_HELP_VRSN)); - printf(_("\ - -t, --timeout=INTEGER\n\ - Seconds to wait for plugin execution to complete\n\ -")); + printf(_(UT_TIMEOUT), timeout_interval); + printf(_("\n\ + -d, --dist-upgrade\n\ + Perform a dist-upgrade instead of normal upgrade.\n\n\ +The following options require root privileges and should be used with care: \ +\n\n")); + printf(_("\ + -u, --update\n\ + First perform an 'apt-get update' (note: you may also need to use -t)\ +\n\n")); } /* simple usage heading */ void print_usage(void){ - printf ("Usage: %s [-u] [-t timeout]\n", progname); + printf ("Usage: %s [-du] [-t timeout]\n", progname); } /* run an apt-get upgrade */ @@ -140,15 +173,26 @@ int run_upgrade(int *pkgcount){ struct output chld_out, chld_err; /* run the upgrade */ - if((result = np_runcmd(APTGET_UPGRADE, &chld_out, &chld_err, 0)) != 0) - result = STATE_WARNING; + if(dist_upgrade==0){ + result = np_runcmd(APTGET_UPGRADE, &chld_out, &chld_err, 0); + } else { + result = np_runcmd(APTGET_DISTUPGRADE, &chld_out, &chld_err, 0); + } + /* apt-get only changes exit status if there is an internal error */ + if(result != 0){ + exec_warning=1; + result = STATE_UNKNOWN; + fprintf(stderr, "'%s' exited with non-zero status.\n%s\n", + APTGET_UPGRADE, + "Run again with -v for more info."); + } /* parse the output, which should only consist of lines like * * Inst package .... * Conf package .... * - * so we'll filter based on "Inst" + * so we'll filter based on "Inst". If we ever want to do */ for(i = 0; i < chld_out.lines; i++) { if(strncmp(chld_out.line[i], "Inst", 4)==0){ @@ -162,12 +206,47 @@ int run_upgrade(int *pkgcount){ /* If we get anything on stderr, at least set warning */ if(chld_err.buflen){ - fprintf(stderr, "warning, output detected on stderr\n"); - for(i = 0; i < chld_err.lines; i++) { - printf("got this: %s\n", chld_err.line[i]); - result = max_state (result, STATE_WARNING); + stderr_warning=1; + result = max_state(result, STATE_WARNING); + if(verbose){ + for(i = 0; i < chld_err.lines; i++) { + printf("%s\n", chld_err.line[i]); + } + } + } + return result; +} + +/* run an apt-get update (needs root) */ +int run_update(void){ + int i=0, result=STATE_UNKNOWN; + struct output chld_out, chld_err; + + /* run the upgrade */ + result = np_runcmd(APTGET_UPDATE, &chld_out, &chld_err, 0); + /* apt-get only changes exit status if there is an internal error */ + if(result != 0){ + exec_warning=1; + result = STATE_UNKNOWN; + fprintf(stderr, "'%s' exited with non-zero status.\n", + APTGET_UPDATE); + } + + if(verbose){ + for(i = 0; i < chld_out.lines; i++) { + printf("%s\n", chld_out.line[i]); } } + /* If we get anything on stderr, at least set warning */ + if(chld_err.buflen){ + stderr_warning=1; + result = max_state(result, STATE_WARNING); + if(verbose){ + for(i = 0; i < chld_err.lines; i++) { + printf("%s\n", chld_err.line[i]); + } + } + } return result; } -- cgit v0.10-9-g596f