diff -Nru munin-2.0.37/ChangeLog munin-2.0.47/ChangeLog --- munin-2.0.37/ChangeLog 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/ChangeLog 2019-02-28 14:43:36.000000000 +0000 @@ -1,5 +1,481 @@ -*- text -*- +munin-2.0.47, 2019-02-28 + +------- +Summary +------- + +Bugfix release. + +------------------ +Detailed Changelog +------------------ + +Steve Schnepp (2): + fix t/munin_master_update.t warning + t: remove munin_master_processmanager.t + +munin-2.0.46, 2019-02-28 + +------- +Summary +------- + +Bugfix release. + +------------------ +Detailed Changelog +------------------ + +Lars Kruse (9): + travis: switch to Ubuntu Xenial and add missing dependencies + shellcheck: ignore interpreter warnings (SC2239) + shellcheck: simplify inverted tests (SC2236) + travis: switch to Linux virtualization infrastructure + Unify whitespace formatting + Plugin apt_all: handle configured list of "releases" properly + Plugin apt_all: filter the stored state for wanted releases + Plugin apt_all: improve readability of labels + Plugin apt_all: escape release name for field name + +Steve Schnepp (1): + Remove munin-sched + +lonepsycho (1): + fix idle connections showing as waiting for lock + + +munin-2.0.45, 2019-02-06 + +------- +Summary +------- + +Bugfix release. + +------------------ +Detailed Changelog +------------------ + +Damian Lukowski (1): + Graph idle kernel threads as available since Linux 4.2 + +Darafei Praliaskouski (1): + Support Samsung SSD 970 EVO + +Lars Kruse (8): + Disable another flaky munin-node proxyspooler test + Do not misinterpret an original umask of zero as a failure + munin-node: announce UTF-8 to locale-aware plugin interpreters + Revert "munin-node: announce UTF-8 to locale-aware plugin interpreters" + Force UTF-8 encoding for plugins related to Python3 + Plugin cupsys_pages: handle weekly logrotated file (for redhat) + PostgreSQL plugins: adjust version comparison for v10 or later + Plugin postgres_connections_: fix backend_type in filter expression + + +munin-2.0.44, 2018-12-19 + +------- +Summary +------- + +Bugfix release. + +------------------ +Detailed Changelog +------------------ + +Kim B. Heino (2): + plugins/mailman: fix to return values if there is no rotated logfile + plugins/postfix_mailvolume: fix typo in queue ID expire + +Lars Kruse (18): + Fix spelling issues + Plugin ipmi_sensor_: fix python2/3 migration issue with "decode" + Revert "p/ipmi_sensor_: fix fan thresholds" + "lint" target: tolerate shellcheck's "SC2230" + Plugin ipmi_sensor_: use explicit raw string for regular expression + Plugin ipmi_sensor_: handle devices without assertions + Avoid reliance on network access in tests + Makefile: avoid duplicate processing of Makefile.config + Makefile: handle test for user existence for multiple platforms + Remove obsolete Makefile.config-maint + Fix dependencies for configurable Makefile location + Remove "get_fq_hostname" test + Plugin memory (linux): use fixed colors for all fields + Plugin mysql_: remove non-working (AREA|LINE)STACK backwards compatibility + Plugin apt_all: automatically determine 'releases' + Plugin postfix_mailstats: fixed various variable handling issues + Respect custom color for warning thresholds + Plugin smart_: ignore invalid threshold data + +Stefan Huehner (2): + Split query as preparation for specific change applicable + Fix issue with PostgreSQL 10. Only count lines related to client + + +munin-2.0.43, 2018-11-16 + +------- +Summary +------- + +Bugfix release. + +------------------ +Detailed Changelog +------------------ + +Christoph Moench-Tegeder (1): + make Linux diskstats plugin comaptible with Linux 4.19+ + +Kim B. Heino (1): + munin-asyncd: sync munin-cron and munin-asyncd runtimes to not overlap + +Lars Kruse (27): + getversion: fix shellcheck issue + getversion: treat all states unrelated to branches equally + getversion: use commit tag if possible; update documentation + Clarify conditional usage of the CGI workaround + Plugin bind9_rndc: stabilize order of values in graph + Plugin smart_: fix variable handling during first run + Update master configuration test + Revive "_extract_name_from_greeting" for tests + Fix test for output of munin-node-configure + Use unique CNs for test TLS certificates + Remove trailing whitespace from openssl.cnf file + Remove outdated "md5" hash from OpenSSL configuration for tests + Recreate TLS certificate for tests + Enable evaluation of test results for test-common and test-plugins + Fix remaining broken master tests + travis: add missing dependency + travis: ignore result of "test-master" + Use "Alien::RRDtool" for travis tests + Disable the failing "proxyspooler" test for "test-node" + munindoc: output reasonable error message if plugin is not found + munindoc: prevent stderr output from perldoc + Plugin apt_all: allow status update after "apt-get update" + Plugin apt_all: fix "apt-get update" call + Tests: allow to run tests as root + Tests: allow to run in an autopkgtest environment lacking a FQDN + Tests: skip the tests around the effective user ID for root + Munin::Node::Service: accept zero (root) as defuser/defgroup + +RenWal (2): + Narrowed down voltage regex + Narrow down regex for all modes + +SeeSchloss (1): + smartctl_exit_status should be a single number and not a range (fixes #1100) + +Steve Mokris (1): + Only apply Perl 5.20 CGI workaround when needed + + +munin-2.0.42, 2018-09-21 + +------- +Summary +------- + +Bugfix release. + +------------------ +Detailed Changelog +------------------ + +Lars Kruse (5): + Fix Module::Build instance parameters for master and node + Retrieve version number for modules "Munin::Common" and "Munin::Plugins" + Module description: set contact to mailing list address + getversion: hide error message for detached HEAD + getversion: prevent localized output format for "git branch" + + +munin-2.0.41, 2018-09-19 + +------- +Summary +------- + +Bugfix release. + +------------------ +Detailed Changelog +------------------ + +Alejandro Suarez (1): + Update default warning threshold + +Christian Göttsche (6): + give reasons why a plugin says no on more occasions + [plugins] give reasons for autoconf no response + [plugins] drop autoconf capability when no real autoconf is supported + [plugins] overlook exim_mailstats + [mnc] fix documentation so that --help works + [munin-node-configure] print autoconf response on parse error + +Dmitry Marakasov (1): + Fix CDEF variable substitution + +Kim B. Heino (6): + ProcessManager: remove \n from output before it's logged + plugins/squeezebox: add missing graph_vlabel + plugins/bind9: use category "dns" as in other similar plugins, not "BIND" + plugins/nginx_request: stats are for all ports (80+443), never for single port + plugins/squid_traffic: allow negative numbers + munin-asyncd: retry connection to node once in startup + +Lars Kruse (21): + Plugin postgres_users: ignore undefined usename + Makefile: fix "tar" target + Makefile: increase compression level for 'tar' target + Plugins: replace all absolute references to shells with placeholders + Plugin http_loadtime: fix shellcheck issue + Whitespace cleanup: remove trailing and unify some spaces/tabs + Plugin cpuspeed: add support for 'intel_pstate' driver + Plugin cpuspeed: minor cleanup; support capability DIRTYCONFIG + Plugin cpuspeed: fix data type for "intel_pstate" driver + Build.PL: define a 'module_name' and a proper version string + Nagios command format: ensure non-empty plugin output + dev_scripts: fix processing of configuration files + munin-node: set default port if not mentioned in config file + Plugin apc_nis: autoconf tests connection to socket + Plugin acp_nis: unify whitespace + Replace CGITMPDIR placeholder during build + Plugin apt_all: simplify conditional expression for "update" operation + Plugin apt_all: update the current status before calculating the summary + munin-asyncd: improve messages in case of failed connections to munin-node + Plugins apache_: add documentation for HTTPS connections + Plugin acpi: prevent error message for missing thermal sys directory + + +munin-2.0.40, 2018-08-15 + +------- +Summary +------- + +Bugfix release. + +------------------ +Detailed Changelog +------------------ + +Christian Göttsche (15): + [plugins] fix varnish autoconf errors + [plugins] fix nestats_multi autoconf error + [plugins] fix meminfo autoconf error + [plugins] fix ejabberd_ autoconf error + fix pgsql plugin driver to give a well formed autoconf reply + fix warning on node list operation + [plugins] give reasons for inactive plugins + [plugins] return 0 in autoconf + [munin-node-configure] expect autoconf to return 0 even in the no case + [plugins] fix autoconf for lpstat + overlook some plugins + [munin-node-configure] do not error out on empty suggest output + [plugins] quote variable + [plugins] fix hddtemp_smartctl autoconf + [plugins] overlook df and netstat linux plugins + +Hiroaki Abe (1): + plugins/freebsd/{df,df_inode}: exclude cd9660 file systems. + +Lars Kruse (24): + Makefile: add current directory to perl include path + Plugin digitemp_: unify whitespace + Plugin digitemp_: fix shellcheck issues; clarify error message + Plugin digitemp_: reduce code duplication + Plugin digitemp_: implement "autoconf" and "suggest" + Plugin digitemp_: mention the configuration file + Plugin hddtemp_smartctl: unify whitespace + Plugin sensors_: enable 'auto' family + Plugin smart_: unify state file access + Plugin smart_: pythonize expressions + Plugin smart_: simplify output parser + Plugin smart_: remove hard disk list weirdness + Plugin smart_: simplify 'SunOS' disk handling + Plugin smart_: unify code for guessing of full path + Plugin smart_: assemble environment configuration at the beginning + Plugin smart_: use 'subprocess' for safe command execution + Plugin smart_: improve exit code handling + Plugin smart_: avoid global variables and clarify data structure + Plugin smart_: update version information + Revert "fix warning on node list operation" + Plugin digitemp_: fix shellcheck issue + postfix_mailsts plugin: add 'milter-reject' event + Makefile: add targets "tar-signed" and "tar-upload" + Update release checklist + +Mathieu Arnold (1): + Fix when using more than one swap device. + + +munin-2.0.39, 2018-07-24 + +------- +Summary +------- + +Bugfix release. + +------------------ +Detailed Changelog +------------------ + +Hans de Graaff (1): + Fix syntax error in make install sh code + +Lars Kruse (37): + Merge pull request #985 from bunder2015/patch-1 + Merge pull request #988 from graaff/make-install-bash-syntax-error + plugin postfix_mailvolume: handle statefile upgrade from previous version + plugin threads: tolerate SELinux policies and other read errors + Makefile / dev_scripts: simplify variables + Fix shellcheck issues in dev_scripts/ + Plugin cpuspeed: fix documentation of 'scaleto100' configuration + Plugins for Linux: fix shellcheck issues + Plugin tcp: fix autoconf exit code + Makefile: add lint check for Linux plugins + Plugin cpu: configurable 'scaleto100' + Plugins for Linux: fix more shellcheck issues + Plugin snort_pkts: remove dependency on 'bc' + Plugins: fix shellcheck issues for bash plugins + Plugins: fix MUNIN_LIBDIR source quoting + Plugin qmailqstat: fix misspelled configuration documentation + Plugin foldingathome: improve path handling + Plugin ipac-ng: return "U" in case of errors + Plugin multiping: remove unusable symlink detection + Plugins: fix more trivial shellcheck issues + Plugins: a bit more complicated fixes for shellcheck issues + Plugins: fix trivial quoting issues for non-Linux platforms + 'make lint': add more platforms for shell checks and add python checks + 'make lint': add python plugins + travis: add 'make lint' for style checks + Merge pull request #977 from sumpfralle/style-checks + Makefile: improve robustness of "Defaults" variable substitution + Makefile: unify usage of whitespace + Makefile: prevent repeated substitution of "Defaults.pm" during "install" + Makefile: remove obsolete 'build-common-prime' target + Makefile: prevent repetitive rebuild of man pages + Makefile: prevent repetitive substitutions for generated files + Travis: add 'liblog-log4perl-perl' dependency + Makefile: handle filenames with colons even with old versions of Make + Travis: reduce set of perl versions for CI + Plugin postfix_mailvolume: handle long queue IDs + Plugins postfix_*: unify whitespace + +Steve Schnepp (1): + Merge pull request #980 from zmousm/fix-asynd-fork-bomb + +Zenon Mousmoulas (1): + Fix munin-asyncd fork bomb + +bunder2015 (1): + Fix paths on nutups_ + + +munin-2.0.38, 2018-06-29 + +------- +Summary +------- + +Bugfix release. + +------------------ +Detailed Changelog +------------------ + +Dmitry Marakasov (5): + Specify minimum value for tuples + Specify minimal value for postgres scans + Specify minimal value for bgwriter + Speficy minimal value for PostgreSQL checkpoints + Specify minimal value for postgresql buffer cache + +Jose-Marcio Martins da Cruz (1): + Update ntp_states.in + +Kenyon Ralph (3): + add Transport Domain environment variable for Munin::Plugin::SNMP + add SNMP domain to tests + munin-node-configure: allow setting SNMP domain + +Lars Kruse (55): + Plugin postfix_mailvolume: calculate separate volume for delivered mails + move debug plugin 'sincos' to debug plugin directory + plugin smart_: fix flake8 warnings + plugin threads (Linux): use "find" instead of globbing; handle zero threads + plugins postgres_*: unify commas in arrays and hashes + plugins postgres_*: unify end of plugin + backport plugin changes from master + Makefile: "build-man" depends on "infiles" + dynazoom: cleanup whitespace + dynazoom: add missing closing tags + dynazoom: fix validation issues and mark as XHTML 1.1 + dynazoom: cgi-based template adapted to cron-based template + Template 'problemview': fix HTML validation problems + Template 'serviceview': use double quotes for tag attributes + plugin postfix_mailvolume: do not use hashs with save_state/restore_state + dynazoom: temporarily remove doctype line + plugin hddtemp_smartctl: handle missing 'smartctl' gracefully + Java compilation: change source and target specification from 1.5 to 1.7 + getversion: replace '$(...)' with backticks (for portability) + getversion: unify whitespace + getversion: improve shell style + getversion: fix or override shellcheck warnings + plugin quota_usage_: backport changes from master + mysql_innodb: fix version string comparisons for v10.x (or later) + memory (freebsd): add new "laundry" counter + plugin bonding_err_: improve input parsing + plugin bonding_err_: separate interface name parsing + plugin bonding_err_: separate BONDINGIF assembly + plugin bonding_err_: separate misconfiguration warning; exit with error + plugin bonding_err_: rename variable 'if' to 'if_name' + plugin bonding_err_: fix remaining shellcheck issues + plugin iostat_ios: fix major block device number for filtering LVM + plugin iostat_ios: clarify documentation (only low-level devices are tracked) + plugin ipmi_sensor_: handle lines without values + plugin ipmi_sensor_: indicate possible symlink names in case of error + plugin ipmi_sensor_: unify whitespace + plugin ipmi_sensor_: python3 compatibility + plugin ipmi_sensor_: fix flake8 style issues + plugin ipmi_sensor_: decoding for python3 + plugin ipmi_: add hint for "power", support %-based fan speed + Python plugin: Python3 compatibility + plugin df_inode_ (FreeBSD): adjust filesystem exclusion to 'df' plugin + plugin df_ (FreeBSD): ignore /sys via the filesystem type + plugin df_inode (FreeBSD): exclude sysfs + HTML: escape ampersand in URL + plugin ntp_: reduce DNS timeout to 5 seconds + plugin netstat: unify the two sets of netstat plugins + Makefile: clarify plugin order comment + Makefile: simplify HP-UX-specific plugin handling + switch default python interpreter for plugins to python3 + COPYING: remove obsolete reference to Bitstream Vera Mono + update COPYING based on commits + plugin samba: improve documentation formatting + plugin samba: warn if run as non-root + plugin samba: improve formatting, fix shellcheck issue + +Robert (1): + Fix argument size too big in threads plugin when there are too many processes. + +Tom Hendrikx (1): + Add a lower limit of 0 to postgres database size + +Tomohiro Hosaka (1): + Do not set database=undef when paramdatabase. + +leeclemens (2): + Graph system peer's stratum + Add missing parens around $syspeer_stratum_value + + munin-2.0.37, 2018-03-28 ------- diff -Nru munin-2.0.37/Checklist munin-2.0.47/Checklist --- munin-2.0.37/Checklist 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/Checklist 2019-02-28 14:43:36.000000000 +0000 @@ -24,49 +24,32 @@ # Git release - We follow the workflow documented at - http://nvie.com/posts/a-successful-git-branching-model/ - The tag used here is "2.0.1", exchange this with a current version. - * Create release branch from "devel" - - git checkout -b release-2.0.1 devel - * Update ChangeLog - $EDITOR Changelog - git commit -m 'Update changelog for release' -- ChangeLog - - * Merge release branch to master - - git checkout master - git merge --no-ff release-2.0.1 + new="2.0.1"; old=$(git describe --abbrev=0) + header=$(printf '\nmunin-%s, %s\n%s' "$new" "$(date +%Y-%m-%d)" "$(sed -n 4,14p ChangeLog)") + shortlog=$(git log --pretty=short --no-merges "${old}.." | git shortlog) + printf "%s\n\n%s\n\n" "$header" "$shortlog" | sed -i "1r /dev/stdin" ChangeLog - (handle any conflicts, and "git commit" the result) + * Commit the updated changelog and tag this release - * Tag on master - - git tag -a -s -m 'Release 2.0.1' 2.0.1 master - - * Merge the release branch back to devel - - git checkout devel - git merge --no-ff release-2.0.1 + git commit -m "$new" -- ChangeLog + git tag -s "$new" -m "$new" # Make tarball from tag git checkout 2.0.1 make tar + OR + make tar-signed # Propaganda * Broadcast the good news: - 1. make a sha256sum : sha256sum munin-version.tar.gz > munin-version.tar.gz.sha256sum - and sign it using gpg. - 2. Upload the tar.gz on sourceforge.net - 3. Create a news on sf annoucing it - 4. Update our front page - 5. Create a new release on freshmeat.net - 6. Send an email to the ML - + 1. Upload the release tar and signature: + make tar-upload + 2. Update our website + 3. Send an email to the ML + 4. Update the version in the topic of the IRC channel diff -Nru munin-2.0.37/common/Build.PL munin-2.0.47/common/Build.PL --- munin-2.0.37/common/Build.PL 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/common/Build.PL 2019-02-28 14:43:36.000000000 +0000 @@ -1,9 +1,12 @@ use Module::Build; +my $version = `../getversion`; +chomp($version); + my $build = Module::Build->new( dist_name => 'Munin::Common', - dist_version => '0.0.0', - dist_author => 'The Munin Team ', + dist_version => $version, + dist_author => 'The Munin Team ', dist_abstract => 'Shared libraries for Munin Node and Munin Master', license => 'gpl', requires => {}, diff -Nru munin-2.0.37/common/t/tls/CA/ca_cert.pem munin-2.0.47/common/t/tls/CA/ca_cert.pem --- munin-2.0.37/common/t/tls/CA/ca_cert.pem 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/common/t/tls/CA/ca_cert.pem 2019-02-28 14:43:36.000000000 +0000 @@ -1,22 +1,28 @@ -----BEGIN CERTIFICATE----- -MIIDqDCCAxGgAwIBAgIJAKxAPCweEB0oMA0GCSqGSIb3DQEBBAUAMIGVMQswCQYD -VQQGEwJNVTEaMBgGA1UECBMRUHJvdmluY2Ugb2YgTXVuaW4xEzARBgNVBAcTCk11 -bmluIFRvd24xEzARBgNVBAoTCk11bmluIEluYy4xCjAIBgNVBAsTAS4xEjAQBgNV -BAMTCTEyNy4wLjAuMTEgMB4GCSqGSIb3DQEJARYRbXVuaW5AZXhhbXBsZS5vcmcw -HhcNMDkwNDA3MDkxNzIwWhcNMTkwNDA1MDkxNzIwWjCBlTELMAkGA1UEBhMCTVUx -GjAYBgNVBAgTEVByb3ZpbmNlIG9mIE11bmluMRMwEQYDVQQHEwpNdW5pbiBUb3du -MRMwEQYDVQQKEwpNdW5pbiBJbmMuMQowCAYDVQQLEwEuMRIwEAYDVQQDEwkxMjcu -MC4wLjExIDAeBgkqhkiG9w0BCQEWEW11bmluQGV4YW1wbGUub3JnMIGfMA0GCSqG -SIb3DQEBAQUAA4GNADCBiQKBgQDp/gJd5Mjr9Ua8JTnV1luXWtUvkReaBmputQvN -znGIEMjj7wLkbEXPIUhQk8Rq/5yRWFrsLMrO4Uo3SIOEPxYhdININAjkOklV4DMn -CKBL6HfqUg4pmugFg31ZDI+3YD/3Ysa+e9qKODcYbgofDpbXT5ib+Wjf+06ZYiFo -+xfC5wIDAQABo4H9MIH6MAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFB7J3QHgITfo -TUWxvXolLl5/pWeBMIHKBgNVHSMEgcIwgb+AFB7J3QHgITfoTUWxvXolLl5/pWeB -oYGbpIGYMIGVMQswCQYDVQQGEwJNVTEaMBgGA1UECBMRUHJvdmluY2Ugb2YgTXVu -aW4xEzARBgNVBAcTCk11bmluIFRvd24xEzARBgNVBAoTCk11bmluIEluYy4xCjAI -BgNVBAsTAS4xEjAQBgNVBAMTCTEyNy4wLjAuMTEgMB4GCSqGSIb3DQEJARYRbXVu -aW5AZXhhbXBsZS5vcmeCCQCsQDwsHhAdKDANBgkqhkiG9w0BAQQFAAOBgQBxigr1 -n/AgUK4BSml19Q4QDt3J+qOkOSg/d9rKRUUIpy12KmwjJNR9emNGV6AuJP843Cq7 -rXrG3+K5MBysud6/3qzSEPV9dbxbdI8Lz2BSTkMAjB8vgvzfADiY8SIbzmHrTmVR -6RemleiYAdAywToya5824mdyVANbz1Y2e5anwQ== +MIIEyDCCA7CgAwIBAgIUWtSxMOW82eJPsbsxT8CoZ6I8fGkwDQYJKoZIhvcNAQEL +BQAwgZYxCzAJBgNVBAYTAk1VMRowGAYDVQQIDBFQcm92aW5jZSBvZiBNdW5pbjET +MBEGA1UEBwwKTXVuaW4gVG93bjETMBEGA1UECgwKTXVuaW4gSW5jLjELMAkGA1UE +CwwCQ0ExEjAQBgNVBAMMCTEyNy4wLjAuMTEgMB4GCSqGSIb3DQEJARYRbXVuaW5A +ZXhhbXBsZS5vcmcwHhcNMTgxMTAxMDM0OTE4WhcNMjgxMDI5MDM0OTE4WjCBljEL +MAkGA1UEBhMCTVUxGjAYBgNVBAgMEVByb3ZpbmNlIG9mIE11bmluMRMwEQYDVQQH +DApNdW5pbiBUb3duMRMwEQYDVQQKDApNdW5pbiBJbmMuMQswCQYDVQQLDAJDQTES +MBAGA1UEAwwJMTI3LjAuMC4xMSAwHgYJKoZIhvcNAQkBFhFtdW5pbkBleGFtcGxl +Lm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALxwztS2TLsqVV5J +zTg5GsBxO7ajuNJ1xANa1+Fv6rnjo3fE4hu66HcmjOMv1odk/dXte2w9HFctQ7Bg +XBtUZea3xOH4pPYLiz+YsrdDCi5WwQUIsCxKvD0qVW7mQhsjadGzsN2kFSWXMBR4 +vs8zPo2gAGdH1zhtY+rxdu6v8jgqwEKSzwk5Hd+t8CSOSIXVACPPm42dxNhT1sv1 +s5fdG+Jew5qDKpSiLeikbOHBnkD8jyrVcO2YvYAzZKL6UhXUVswJQbCpIJRPuiol +4HRIL2Sp/eNUeEA9geh5QhrcT7wD0nTKPltGnHQQuZf1duj6niE9nQv7K6rfJwdQ +qrUbERMCAwEAAaOCAQowggEGMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFCAhB/IB +dM2Lo+7kqJy2rvAbOSnMMIHWBgNVHSMEgc4wgcuAFCAhB/IBdM2Lo+7kqJy2rvAb +OSnMoYGcpIGZMIGWMQswCQYDVQQGEwJNVTEaMBgGA1UECAwRUHJvdmluY2Ugb2Yg +TXVuaW4xEzARBgNVBAcMCk11bmluIFRvd24xEzARBgNVBAoMCk11bmluIEluYy4x +CzAJBgNVBAsMAkNBMRIwEAYDVQQDDAkxMjcuMC4wLjExIDAeBgkqhkiG9w0BCQEW +EW11bmluQGV4YW1wbGUub3JnghRa1LEw5bzZ4k+xuzFPwKhnojx8aTANBgkqhkiG +9w0BAQsFAAOCAQEAPdomAFKx4UyxcK/Y/abModSuN36GdnIZP5eyZmWtDYQkTw74 +21TyZx6iYHOq/TUtF4zzWz6QHUXGbJbggOrMkLz9G3haRcFW3kv14+fch4ywkmd0 +i1tIhY1Pqyq8oMccrtSfBWOj31faH6GpdRejmhUZWYvmpCHGRofzuEjlFWdipuUs +KLo7HsEEOF4UqM/T9eUJCloEmt1/rwegPZWo6GyPEVkZ09zhlsmY8/olDKJ09Asb +r6qYflpWkDAyjFFgnEY+Ef3cf8IC7kPai0FRMOTlPY9miUB9uf7Z59PNRcVszBr6 +Sm47SMD03pY46BnXr9G6KHB/WD6nrFC6+LiP8g== -----END CERTIFICATE----- diff -Nru munin-2.0.37/common/t/tls/Makefile munin-2.0.47/common/t/tls/Makefile --- munin-2.0.37/common/t/tls/Makefile 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/common/t/tls/Makefile 2019-02-28 14:43:36.000000000 +0000 @@ -1,3 +1,7 @@ +SUBJECT_CA = /C=MU/ST=Province of Munin/L=Munin Town/O=Munin Inc./OU=CA/CN=127.0.0.1/emailAddress=munin@example.org/ +SUBJECT_MASTER = /C=MU/ST=Province of Munin/L=Munin Town/O=Munin Inc./OU=Master/CN=127.0.0.1/emailAddress=munin@example.org/ +SUBJECT_NODE = /C=MU/ST=Province of Munin/L=Munin Town/O=Munin Inc./OU=Node/CN=127.0.0.1/emailAddress=munin@example.org/ + .PHONY: all clean @@ -6,9 +10,9 @@ mkdir CA/newcerts CA/private touch CA/index.txt echo '01' > CA/serial - openssl req -new -nodes -x509 -extensions v3_ca -keyout CA/private/ca_key.pem -out CA/ca_cert.pem -days 3650 -config ./openssl.cnf - openssl req -new -nodes -keyout node_key.pem -out node_req.pem -config ./openssl.cnf - openssl req -new -nodes -keyout master_key.pem -out master_req.pem -config ./openssl.cnf + openssl req -new -nodes -x509 -extensions v3_ca -subj "$(SUBJECT_CA)" -keyout CA/private/ca_key.pem -out CA/ca_cert.pem -days 3650 -config ./openssl.cnf + openssl req -new -nodes -subj "$(SUBJECT_NODE)" -keyout node_key.pem -out node_req.pem -config ./openssl.cnf + openssl req -new -nodes -subj "$(SUBJECT_MASTER)" -keyout master_key.pem -out master_req.pem -config ./openssl.cnf yes | openssl ca -out node_cert.pem -in node_req.pem -config ./openssl.cnf -days 3650 yes | openssl ca -out master_cert.pem -in master_req.pem -config ./openssl.cnf -days 3650 diff -Nru munin-2.0.37/common/t/tls/master_cert.pem munin-2.0.47/common/t/tls/master_cert.pem --- munin-2.0.37/common/t/tls/master_cert.pem 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/common/t/tls/master_cert.pem 2019-02-28 14:43:36.000000000 +0000 @@ -2,47 +2,69 @@ Data: Version: 1 (0x0) Serial Number: 2 (0x2) - Signature Algorithm: md5WithRSAEncryption - Issuer: C=MU, ST=Province of Munin, L=Munin Town, O=Munin Inc., OU=., CN=127.0.0.1/emailAddress=munin@example.org + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=MU, ST=Province of Munin, L=Munin Town, O=Munin Inc., OU=CA, CN=127.0.0.1/emailAddress=munin@example.org Validity - Not Before: Apr 7 09:17:20 2009 GMT - Not After : Apr 5 09:17:20 2019 GMT - Subject: C=MU, ST=Province of Munin, O=Munin Inc., OU=., CN=127.0.0.1 + Not Before: Nov 1 03:49:21 2018 GMT + Not After : Oct 29 03:49:21 2028 GMT + Subject: C=MU, ST=Province of Munin, O=Munin Inc., OU=Master, CN=127.0.0.1 Subject Public Key Info: Public Key Algorithm: rsaEncryption - RSA Public Key: (1024 bit) - Modulus (1024 bit): - 00:ce:82:56:87:ad:d4:21:27:ea:3c:f8:f4:58:ca: - e6:a1:54:16:9a:80:bc:4c:d3:6b:a7:f1:86:0d:a1: - 52:81:2a:5d:f1:c6:9d:cc:bf:72:c3:c7:26:58:ea: - ca:62:5b:cf:03:4b:41:56:68:3d:51:e4:b0:b2:67: - f2:44:db:dc:1c:cc:40:60:ce:dc:ad:41:fe:1e:0b: - a5:47:c0:35:97:ad:45:e8:b8:6f:0b:b7:16:d4:cf: - 4d:8e:b5:df:1c:50:27:63:58:3a:7c:9a:ee:fb:74: - b8:cf:fb:84:f6:c3:c0:f8:88:cd:7a:26:3a:72:0c: - 15:f6:d7:99:98:c6:2d:52:97 + RSA Public-Key: (2048 bit) + Modulus: + 00:cb:62:78:95:15:55:0f:16:a5:6a:3a:99:83:4d: + b0:38:2f:4c:58:22:76:cf:48:a3:36:ef:47:2c:86: + 8b:bb:cc:33:41:40:cf:14:90:b3:05:d0:38:02:10: + 95:75:62:d6:75:ec:9c:fe:1e:cf:fe:8a:42:ee:a7: + fa:80:63:3e:d5:fc:1d:e9:a8:b8:d3:96:9f:67:4c: + be:56:7e:3f:1b:ca:90:58:14:80:ea:ec:eb:5d:e9: + 5f:21:4b:a5:e7:ef:fb:43:b4:70:7f:d0:02:ac:31: + 91:ef:8e:26:96:6c:aa:fa:ba:95:6a:a7:25:8b:8f: + 6c:fc:8a:eb:bb:b0:c4:0d:cc:65:96:78:1e:ce:10: + ab:09:50:ac:7a:96:9b:cf:a6:89:46:6c:be:94:4e: + 6c:3c:42:57:02:63:94:16:30:f4:99:dc:9f:f3:e6: + f6:30:50:29:04:bd:e9:79:12:46:4b:f1:54:f3:c7: + c7:6a:e9:fd:bd:12:40:ff:01:e8:f8:9c:5a:11:50: + 3d:06:ce:1c:12:fb:a2:dd:c6:b4:ff:31:29:7d:02: + ce:10:0b:9b:7b:33:02:0d:1c:a0:30:24:06:7b:e7: + 4f:ae:04:39:bc:5e:10:20:8f:18:d3:2d:02:3c:e9: + 45:87:a5:ac:28:5e:80:12:be:43:37:fe:42:5d:29: + 7b:b5 Exponent: 65537 (0x10001) - Signature Algorithm: md5WithRSAEncryption - c5:ee:69:b5:7c:c3:87:23:32:88:b4:b5:08:3b:39:80:99:9d: - 03:f1:d1:ac:76:45:b5:46:8a:0f:9f:10:67:b3:c4:c3:3a:aa: - 34:37:32:96:4f:29:2e:ee:05:e3:18:27:7f:61:6d:6c:09:5f: - b5:b6:b1:80:c0:d5:80:7c:8d:32:33:16:8e:ff:25:59:58:48: - ad:a7:b9:ab:53:06:91:f7:88:0e:10:a0:ef:af:d1:47:b5:38: - 03:c4:0e:9a:23:79:94:6e:c0:8d:c8:91:9f:f4:63:44:dd:ca: - 06:02:b0:5b:68:65:c3:c9:1a:0d:b1:a6:dd:d1:e0:30:af:52: - fb:84 + Signature Algorithm: sha256WithRSAEncryption + 41:d8:09:20:d2:98:40:8c:f3:40:a5:c9:fd:3b:24:f9:6b:ed: + 88:1c:a8:04:36:9d:ac:ee:34:70:a7:e6:bf:8a:23:66:f2:ce: + b5:8d:a2:59:72:b5:8b:de:bd:63:ce:c2:85:24:51:28:b9:1c: + 6b:74:b7:35:94:84:c8:17:b6:2a:95:02:e2:63:a5:9a:fb:13: + c1:a8:e2:e2:73:cc:28:31:fc:9c:ec:b1:7e:a5:22:55:22:56: + 16:c3:71:1b:13:bc:e2:4e:4b:d9:ef:2f:13:e2:12:7b:d0:0a: + 70:05:57:aa:f1:5b:d4:22:9d:38:20:12:93:30:6d:e6:65:24: + 2d:7f:34:5f:64:6e:ed:a0:72:8d:a0:ec:a5:9f:8f:8d:b5:8d: + 57:01:6a:e9:8e:48:71:2d:4e:5a:cc:6e:fb:2f:5c:49:d3:b7: + 1f:ea:a3:65:cc:a5:ce:d6:5e:18:70:74:a4:7a:e7:dd:b7:38: + 51:7b:20:2f:8f:29:c5:86:af:e4:26:da:da:9d:16:5e:a2:45: + 0d:10:31:25:bd:64:d8:28:23:c9:dc:44:3a:61:7a:98:e0:b9: + 1c:a9:06:6c:9c:19:cb:6c:00:38:00:e6:3a:00:d0:4a:60:ab: + 70:5e:5f:ae:ed:96:84:83:e1:b0:11:f5:c2:95:e4:f3:53:71: + 47:23:75:e6 -----BEGIN CERTIFICATE----- -MIICYzCCAcwCAQIwDQYJKoZIhvcNAQEEBQAwgZUxCzAJBgNVBAYTAk1VMRowGAYD -VQQIExFQcm92aW5jZSBvZiBNdW5pbjETMBEGA1UEBxMKTXVuaW4gVG93bjETMBEG -A1UEChMKTXVuaW4gSW5jLjEKMAgGA1UECxMBLjESMBAGA1UEAxMJMTI3LjAuMC4x -MSAwHgYJKoZIhvcNAQkBFhFtdW5pbkBleGFtcGxlLm9yZzAeFw0wOTA0MDcwOTE3 -MjBaFw0xOTA0MDUwOTE3MjBaMF4xCzAJBgNVBAYTAk1VMRowGAYDVQQIExFQcm92 -aW5jZSBvZiBNdW5pbjETMBEGA1UEChMKTXVuaW4gSW5jLjEKMAgGA1UECxMBLjES -MBAGA1UEAxMJMTI3LjAuMC4xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO -glaHrdQhJ+o8+PRYyuahVBaagLxM02un8YYNoVKBKl3xxp3Mv3LDxyZY6spiW88D -S0FWaD1R5LCyZ/JE29wczEBgztytQf4eC6VHwDWXrUXouG8LtxbUz02Otd8cUCdj -WDp8mu77dLjP+4T2w8D4iM16JjpyDBX215mYxi1SlwIDAQABMA0GCSqGSIb3DQEB -BAUAA4GBAMXuabV8w4cjMoi0tQg7OYCZnQPx0ax2RbVGig+fEGezxMM6qjQ3MpZP -KS7uBeMYJ39hbWwJX7W2sYDA1YB8jTIzFo7/JVlYSK2nuatTBpH3iA4QoO+v0Ue1 -OAPEDpojeZRuwI3IkZ/0Y0TdygYCsFtoZcPJGg2xpt3R4DCvUvuE +MIIDbjCCAlYCAQIwDQYJKoZIhvcNAQELBQAwgZYxCzAJBgNVBAYTAk1VMRowGAYD +VQQIDBFQcm92aW5jZSBvZiBNdW5pbjETMBEGA1UEBwwKTXVuaW4gVG93bjETMBEG +A1UECgwKTXVuaW4gSW5jLjELMAkGA1UECwwCQ0ExEjAQBgNVBAMMCTEyNy4wLjAu +MTEgMB4GCSqGSIb3DQEJARYRbXVuaW5AZXhhbXBsZS5vcmcwHhcNMTgxMTAxMDM0 +OTIxWhcNMjgxMDI5MDM0OTIxWjBjMQswCQYDVQQGEwJNVTEaMBgGA1UECAwRUHJv +dmluY2Ugb2YgTXVuaW4xEzARBgNVBAoMCk11bmluIEluYy4xDzANBgNVBAsMBk1h +c3RlcjESMBAGA1UEAwwJMTI3LjAuMC4xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAy2J4lRVVDxalajqZg02wOC9MWCJ2z0ijNu9HLIaLu8wzQUDPFJCz +BdA4AhCVdWLWdeyc/h7P/opC7qf6gGM+1fwd6ai405afZ0y+Vn4/G8qQWBSA6uzr +XelfIUul5+/7Q7Rwf9ACrDGR744mlmyq+rqVaqcli49s/Irru7DEDcxllngezhCr +CVCsepabz6aJRmy+lE5sPEJXAmOUFjD0mdyf8+b2MFApBL3peRJGS/FU88fHaun9 +vRJA/wHo+JxaEVA9Bs4cEvui3ca0/zEpfQLOEAubezMCDRygMCQGe+dPrgQ5vF4Q +II8Y0y0CPOlFh6WsKF6AEr5DN/5CXSl7tQIDAQABMA0GCSqGSIb3DQEBCwUAA4IB +AQBB2Akg0phAjPNApcn9OyT5a+2IHKgENp2s7jRwp+a/iiNm8s61jaJZcrWL3r1j +zsKFJFEouRxrdLc1lITIF7YqlQLiY6Wa+xPBqOLic8woMfyc7LF+pSJVIlYWw3Eb +E7ziTkvZ7y8T4hJ70ApwBVeq8VvUIp04IBKTMG3mZSQtfzRfZG7toHKNoOyln4+N +tY1XAWrpjkhxLU5azG77L1xJ07cf6qNlzKXO1l4YcHSkeufdtzhReyAvjynFhq/k +JtranRZeokUNEDElvWTYKCPJ3EQ6YXqY4LkcqQZsnBnLbAA4AOY6ANBKYKtwXl+u +7ZaEg+GwEfXCleTzU3FHI3Xm -----END CERTIFICATE----- diff -Nru munin-2.0.37/common/t/tls/master_key.pem munin-2.0.47/common/t/tls/master_key.pem --- munin-2.0.37/common/t/tls/master_key.pem 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/common/t/tls/master_key.pem 2019-02-28 14:43:36.000000000 +0000 @@ -1,15 +1,28 @@ ------BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDOglaHrdQhJ+o8+PRYyuahVBaagLxM02un8YYNoVKBKl3xxp3M -v3LDxyZY6spiW88DS0FWaD1R5LCyZ/JE29wczEBgztytQf4eC6VHwDWXrUXouG8L -txbUz02Otd8cUCdjWDp8mu77dLjP+4T2w8D4iM16JjpyDBX215mYxi1SlwIDAQAB -AoGAXlUZk9bq7M5f6MRMUfc1jQJtZNxjp7B4H/prIvTLTGd/DH+O+8WEdjwVn055 -bp7DnJyW1xK82BjgQk7LU3sfO1IDXZMVzj2Aw7x482K2JV03IAGLIT05yL4uk4WP -sI1LKh+4TljajStG/wO8MwytUkD2gNR5uns7rIynQSpwNwECQQDzr2yDVOxuZsQT -j1i/tyDDN4u3/rwXNW6jPBTCscebwrssO9a9RhYMXL/6pXypf4OnrTYMTLd8Kv3B -rscez+qBAkEA2PH2sbB2kIGcrPlL6iLp6uGjXVSJzfIxsXLV2XYnF5uR2p3w15s2 -v75s7r4NQ0XnYPYcJCsVqv+b7wCD37TBFwJBAOP30q4yPlUx8nDSA5amvRGj3yOs -PU4BAJXY2Rsisbf3vp6tBEFhVbMO+dKEClGPJx0wH4X2JxkUJvyQg1tB6wECQQCj -O5QR6KOdYVigsccT+Ycl6va/f59cbTJEwRH02LjbQ3vAEXyozampJj/Sdv+FsbBB -vYw5Do30JvWOJEYVaWyrAkAYNUP95eP9OJ3oKCuvl6ErOBfnpwne5795F1PgzWIu -vK3H5/qqFMCB9zWEZ2x9sHvDb8I7qOrNGkUS+ouGGcrt ------END RSA PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDLYniVFVUPFqVq +OpmDTbA4L0xYInbPSKM270cshou7zDNBQM8UkLMF0DgCEJV1YtZ17Jz+Hs/+ikLu +p/qAYz7V/B3pqLjTlp9nTL5Wfj8bypBYFIDq7Otd6V8hS6Xn7/tDtHB/0AKsMZHv +jiaWbKr6upVqpyWLj2z8iuu7sMQNzGWWeB7OEKsJUKx6lpvPpolGbL6UTmw8QlcC +Y5QWMPSZ3J/z5vYwUCkEvel5EkZL8VTzx8dq6f29EkD/Aej4nFoRUD0GzhwS+6Ld +xrT/MSl9As4QC5t7MwINHKAwJAZ750+uBDm8XhAgjxjTLQI86UWHpawoXoASvkM3 +/kJdKXu1AgMBAAECggEBAMA8xg7cB/boB9fdpaZHMy4X/sg7YyNP2/2bsyFx1vfd +7gBaeqFMl/oBsj65YBuBHYZ+7HEBvMUx+EvN+GeL5yOpVri5YmGUN/0Su8HTOGFT +WJX4Y1YqM9ojMGivMRSGb2+ySLd2bGBHxlGwgeaitgWhgIM7k7BTE8eso15XmSgT +/5jR+6E5c4uvfmRcKshVKjUfpzb4bVhyk3LMH2uFyTFzBunLHV4hbyU318+0aJpr +fHgJ1zYMymDWEfwZesvRcXfz1R0xu0MSHiAblH5QjChdQ9P02VZ4TcljurMtwOZf +YkKyTpBLYj/a0NMFOde3QE42gwzLURUU0Dt7JPMZGWECgYEA7mGqb4dwemgpmwgU +BkmBvl+l0gD2+wncMjI+PUqmH6HxL9SB+oJyUcwDulZZZsPXGkgPnAYs70VfKoqh +AvAE6wYJ0OddTIAYdE43A2oOqvY9aycHL52mgAU4Uz68SNUQ0dKViPvctJS5MjPy +JcA5iao2dh95TZPwDInBAu0IeIkCgYEA2mqkUIMi6YvpDoOBbSQutXW4KjQzN7+u +BBfL1QixaF5QjA1Z2mS12gEcBpALJDrupW25OOl6BKulTk+7YVsuuf426ovL6P+7 +nVdJnf5288aNqQdfjvvY3vGD5p80OOef/9ezzOwOTy4idd7JVzuJyH8o+YsNmVkp +RJ52kycvxs0CgYAnib9xHC/Fvb0Y37AiktKYNtkUCeDtJmeFU9wK4nTHTl7opgCh +Aj3f30zG/Ud6ygTFcSpVoJiXXxQ3xCKMkC7gpHHAWn+ZDq3/rHFneZHRPWJWgXSp +qyZQmY0MEZ29HsnZY2o1/EBRG1HUR9Vj+YwRj0/VK8c83Mq16as/xvzesQKBgQCf +n8BmdvBU7sNsr/8u3Hqmc1ocvfmQjK2IoDt/fdLqC8OiFz/LtD6TDKyGv07lM4yl +qgLr7PYX47nz+aFgDVug4oEP+QsVRZC/9MMAjLAyiLGPDqxvuu9MQAW9zixESkNM +nz/wS7RJedYFfsR21DRmK0iu10khAWB/na/a65CnIQKBgDg5aUgPYjo5V9rQU5Xy +8Qm1V/WP424bM2C9tpOc6vlShlgeie7gUKB4St4JnjPE7GYOt80LxianfmG9v56S +fKfOMm6k9WaaU8Pd+9SJSGTAaIYHN8VRBH2xwAh7rsHSGuK3dnNBKv4BEzmb/FFQ +P8sJupQvqEvhNRuo7oBgbk/1 +-----END PRIVATE KEY----- diff -Nru munin-2.0.37/common/t/tls/node_cert.pem munin-2.0.47/common/t/tls/node_cert.pem --- munin-2.0.37/common/t/tls/node_cert.pem 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/common/t/tls/node_cert.pem 2019-02-28 14:43:36.000000000 +0000 @@ -2,47 +2,69 @@ Data: Version: 1 (0x0) Serial Number: 1 (0x1) - Signature Algorithm: md5WithRSAEncryption - Issuer: C=MU, ST=Province of Munin, L=Munin Town, O=Munin Inc., OU=., CN=127.0.0.1/emailAddress=munin@example.org + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=MU, ST=Province of Munin, L=Munin Town, O=Munin Inc., OU=CA, CN=127.0.0.1/emailAddress=munin@example.org Validity - Not Before: Apr 7 09:17:20 2009 GMT - Not After : Apr 5 09:17:20 2019 GMT - Subject: C=MU, ST=Province of Munin, O=Munin Inc., OU=., CN=127.0.0.1 + Not Before: Nov 1 03:49:21 2018 GMT + Not After : Oct 29 03:49:21 2028 GMT + Subject: C=MU, ST=Province of Munin, O=Munin Inc., OU=Node, CN=127.0.0.1 Subject Public Key Info: Public Key Algorithm: rsaEncryption - RSA Public Key: (1024 bit) - Modulus (1024 bit): - 00:d6:43:f2:48:72:ef:58:d6:66:89:c9:8a:d2:ce: - 24:b6:50:85:a5:83:55:97:cb:fd:d5:f7:38:16:73: - 07:8a:eb:7b:3b:af:35:ef:8c:2e:ed:60:f3:78:81: - 49:94:75:04:1f:71:5f:09:d1:cf:ec:14:6a:5b:3e: - e8:26:6a:e9:e5:9f:dd:fa:96:de:9d:53:7c:18:fb: - 11:64:aa:34:3d:e1:86:38:b7:69:54:4e:b6:67:b3: - b6:c9:3e:5e:7e:9c:4d:49:21:73:d8:71:3b:c9:1c: - 61:fb:71:c1:ff:ad:7a:9c:07:cb:dd:e3:34:29:a3: - 34:4b:c1:10:2a:67:31:a2:1d + RSA Public-Key: (2048 bit) + Modulus: + 00:9e:bf:2a:53:9b:3f:c8:26:24:80:02:15:9f:5d: + 4b:96:2b:4d:81:16:48:fe:8b:a3:80:2e:c0:6b:07: + 9d:cf:f5:1c:83:59:92:35:c2:df:bb:e8:f8:b3:1a: + a8:0a:ed:4d:05:52:03:47:af:e4:e7:12:c2:23:94: + e6:14:8e:87:cf:b3:3e:26:54:5a:b3:3d:5a:d8:45: + 07:6f:d0:94:7a:e9:d7:ac:d5:e1:9a:0e:1b:4c:12: + a0:c1:75:b6:13:3c:75:5b:08:51:3d:e4:3c:dd:a8: + 02:16:a4:ee:2a:a6:fc:da:e6:31:ba:54:ac:26:96: + b9:eb:f0:77:a9:99:1a:d8:a5:9e:ea:69:15:95:f9: + e9:9c:0d:ff:d6:7f:7c:32:d4:31:dd:21:19:1f:45: + e4:36:8c:8e:14:6c:9e:92:56:b2:27:f8:bd:aa:1a: + 90:c5:c0:40:8f:27:30:19:ce:6d:51:1b:62:e4:3d: + 19:8b:73:2a:1e:b5:fe:14:66:b7:12:8c:bc:41:a1: + a6:00:d3:2a:9c:fc:1b:b9:70:94:b4:53:3b:0c:d1: + 49:e4:3e:b7:2f:8f:0e:ed:bd:7b:a2:1c:d8:f7:6b: + 26:5b:ff:4a:a3:83:02:3b:6e:9d:22:12:d2:8e:0d: + 37:f4:1f:5b:44:d5:df:35:f7:1b:39:02:73:4f:ea: + 11:75 Exponent: 65537 (0x10001) - Signature Algorithm: md5WithRSAEncryption - 04:0e:00:80:33:73:2f:29:37:73:89:1f:fb:00:df:af:1b:94: - a7:e4:da:4d:5f:29:a5:d6:dd:77:71:5a:a2:dc:c0:53:7a:58: - 25:fe:4b:64:5d:8f:71:e3:aa:82:3d:14:8c:89:66:cd:9b:ee: - b1:bd:fe:d8:65:f7:27:15:a7:56:e1:c9:cc:64:90:1c:e4:62: - 2d:ee:c0:53:cb:dd:8a:c6:c0:cb:60:66:1e:ae:7f:17:8f:0e: - f5:8e:ab:24:50:8a:a3:36:01:76:23:d1:1e:45:01:1c:6c:6f: - f9:a1:b5:89:55:ba:06:3c:2e:ff:09:0f:e5:4b:55:b8:a8:4a: - 4e:2f + Signature Algorithm: sha256WithRSAEncryption + 7c:18:5e:6e:a0:c3:7b:d5:bd:b4:16:40:74:77:0d:ce:a4:7a: + 1a:d3:58:1e:15:9d:25:53:6c:a6:58:a4:71:fb:53:ea:52:d4: + 56:a3:f3:2d:b7:f8:2f:af:22:bc:1f:b1:1b:cb:35:d8:d4:c6: + ac:89:f4:d2:f5:17:80:86:e4:5c:0e:4a:ec:a4:e8:fe:93:21: + 77:2e:cd:bd:8c:1e:6e:eb:65:82:35:42:53:3e:26:e4:f8:7c: + 14:08:d0:a3:3f:c1:1c:69:a2:2e:84:55:32:f9:96:7f:b9:b9: + cb:e8:7a:77:58:55:f4:26:e5:63:10:58:88:35:34:f9:ca:8d: + 1d:24:f9:fa:36:c8:ce:f0:99:8b:6f:b8:1d:11:01:97:95:8f: + 83:6a:ac:25:3a:01:e8:16:29:82:11:15:7b:c9:56:6e:21:b2: + 58:fe:57:c8:3a:3b:d2:94:49:c5:a7:f1:c2:69:5a:fb:03:3b: + f9:c8:8a:23:2d:58:23:4e:11:d1:8f:46:80:ec:e8:a4:d8:0c: + 39:bc:e4:d6:ea:5f:4c:dd:d3:4d:3b:ed:02:c3:45:2e:f4:0f: + 07:4c:ff:21:46:d2:dc:fe:50:7b:65:2f:94:34:7c:80:e3:f3: + ff:3e:59:46:4d:8b:1f:70:da:25:17:73:93:ca:d3:87:1d:fa: + 97:69:77:31 -----BEGIN CERTIFICATE----- -MIICYzCCAcwCAQEwDQYJKoZIhvcNAQEEBQAwgZUxCzAJBgNVBAYTAk1VMRowGAYD -VQQIExFQcm92aW5jZSBvZiBNdW5pbjETMBEGA1UEBxMKTXVuaW4gVG93bjETMBEG -A1UEChMKTXVuaW4gSW5jLjEKMAgGA1UECxMBLjESMBAGA1UEAxMJMTI3LjAuMC4x -MSAwHgYJKoZIhvcNAQkBFhFtdW5pbkBleGFtcGxlLm9yZzAeFw0wOTA0MDcwOTE3 -MjBaFw0xOTA0MDUwOTE3MjBaMF4xCzAJBgNVBAYTAk1VMRowGAYDVQQIExFQcm92 -aW5jZSBvZiBNdW5pbjETMBEGA1UEChMKTXVuaW4gSW5jLjEKMAgGA1UECxMBLjES -MBAGA1UEAxMJMTI3LjAuMC4xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDW -Q/JIcu9Y1maJyYrSziS2UIWlg1WXy/3V9zgWcweK63s7rzXvjC7tYPN4gUmUdQQf -cV8J0c/sFGpbPugmaunln936lt6dU3wY+xFkqjQ94YY4t2lUTrZns7bJPl5+nE1J -IXPYcTvJHGH7ccH/rXqcB8vd4zQpozRLwRAqZzGiHQIDAQABMA0GCSqGSIb3DQEB -BAUAA4GBAAQOAIAzcy8pN3OJH/sA368blKfk2k1fKaXW3XdxWqLcwFN6WCX+S2Rd -j3HjqoI9FIyJZs2b7rG9/thl9ycVp1bhycxkkBzkYi3uwFPL3YrGwMtgZh6ufxeP -DvWOqyRQiqM2AXYj0R5FARxsb/mhtYlVugY8Lv8JD+VLVbioSk4v +MIIDbDCCAlQCAQEwDQYJKoZIhvcNAQELBQAwgZYxCzAJBgNVBAYTAk1VMRowGAYD +VQQIDBFQcm92aW5jZSBvZiBNdW5pbjETMBEGA1UEBwwKTXVuaW4gVG93bjETMBEG +A1UECgwKTXVuaW4gSW5jLjELMAkGA1UECwwCQ0ExEjAQBgNVBAMMCTEyNy4wLjAu +MTEgMB4GCSqGSIb3DQEJARYRbXVuaW5AZXhhbXBsZS5vcmcwHhcNMTgxMTAxMDM0 +OTIxWhcNMjgxMDI5MDM0OTIxWjBhMQswCQYDVQQGEwJNVTEaMBgGA1UECAwRUHJv +dmluY2Ugb2YgTXVuaW4xEzARBgNVBAoMCk11bmluIEluYy4xDTALBgNVBAsMBE5v +ZGUxEjAQBgNVBAMMCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAJ6/KlObP8gmJIACFZ9dS5YrTYEWSP6Lo4AuwGsHnc/1HINZkjXC37vo ++LMaqArtTQVSA0ev5OcSwiOU5hSOh8+zPiZUWrM9WthFB2/QlHrp16zV4ZoOG0wS +oMF1thM8dVsIUT3kPN2oAhak7iqm/NrmMbpUrCaWuevwd6mZGtilnuppFZX56ZwN +/9Z/fDLUMd0hGR9F5DaMjhRsnpJWsif4vaoakMXAQI8nMBnObVEbYuQ9GYtzKh61 +/hRmtxKMvEGhpgDTKpz8G7lwlLRTOwzRSeQ+ty+PDu29e6Ic2PdrJlv/SqODAjtu +nSIS0o4NN/QfW0TV3zX3GzkCc0/qEXUCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA +fBhebqDDe9W9tBZAdHcNzqR6GtNYHhWdJVNsplikcftT6lLUVqPzLbf4L68ivB+x +G8s12NTGrIn00vUXgIbkXA5K7KTo/pMhdy7NvYwebutlgjVCUz4m5Ph8FAjQoz/B +HGmiLoRVMvmWf7m5y+h6d1hV9CblYxBYiDU0+cqNHST5+jbIzvCZi2+4HREBl5WP +g2qsJToB6BYpghEVe8lWbiGyWP5XyDo70pRJxafxwmla+wM7+ciKIy1YI04R0Y9G +gOzopNgMObzk1upfTN3TTTvtAsNFLvQPB0z/IUbS3P5Qe2UvlDR8gOPz/z5ZRk2L +H3DaJRdzk8rThx36l2l3MQ== -----END CERTIFICATE----- diff -Nru munin-2.0.37/common/t/tls/node_key.pem munin-2.0.47/common/t/tls/node_key.pem --- munin-2.0.37/common/t/tls/node_key.pem 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/common/t/tls/node_key.pem 2019-02-28 14:43:36.000000000 +0000 @@ -1,15 +1,28 @@ ------BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDWQ/JIcu9Y1maJyYrSziS2UIWlg1WXy/3V9zgWcweK63s7rzXv -jC7tYPN4gUmUdQQfcV8J0c/sFGpbPugmaunln936lt6dU3wY+xFkqjQ94YY4t2lU -TrZns7bJPl5+nE1JIXPYcTvJHGH7ccH/rXqcB8vd4zQpozRLwRAqZzGiHQIDAQAB -AoGBAIFekSExVFadTVgQemOB2CTERY2D2OBIaMER/amAVqOIPuXwim5Sg9sL2LV/ -yn96j7y0ZR+2sQXn5bemKeFYWFQTkKfOr6AxtkkBNOtuaNght5zNnfpjuoQi5KW3 -wNPXNWQrQP1mDNZnWPi6S6E/Ocbg9fSwxI8ePsTx7CGUbQFBAkEA9zVAVicl4lCU -egmofI67bM4RGL4JeAk+N7u26ezedTxfKrrH9SHAjqa4tD7MB4zKYHPyDgkSsIIL -ZNqF+bL4dQJBAN3iw3Gd/yoeSgkZJZ+SzyEfG5dnvL5LFacJeAdPdMEwSEXMldQP -ZQCVO3KHM/CyiAaEnXgGTfW5ipZZ0r7+jgkCQCWo9yQo0pynqfbtgb14ARWSTwh1 -6vtebRwQfM0mSL2TdOwNiGjPu4X/4COVbX+48xu+jiGVQEOjjBjRMZfYrAECQQCA -Zcx7XtZdZRGqmiavZKD/paStxJXv+DsbYdtXP59se6gW3ACHqjDkWXcBG0PvMSCN -xQfqgJt0al3MC0Zsx5khAkBV8LsKqrfMuFtQ+XXNNR/PTm2TJyiOKSVgKeJ2aSe1 -9W/UYBLPpAFtso6eqj3pIj0Jw8YasSPZ+vi3z5eRFJBs ------END RSA PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCevypTmz/IJiSA +AhWfXUuWK02BFkj+i6OALsBrB53P9RyDWZI1wt+76PizGqgK7U0FUgNHr+TnEsIj +lOYUjofPsz4mVFqzPVrYRQdv0JR66des1eGaDhtMEqDBdbYTPHVbCFE95DzdqAIW +pO4qpvza5jG6VKwmlrnr8HepmRrYpZ7qaRWV+emcDf/Wf3wy1DHdIRkfReQ2jI4U +bJ6SVrIn+L2qGpDFwECPJzAZzm1RG2LkPRmLcyoetf4UZrcSjLxBoaYA0yqc/Bu5 +cJS0UzsM0UnkPrcvjw7tvXuiHNj3ayZb/0qjgwI7bp0iEtKODTf0H1tE1d819xs5 +AnNP6hF1AgMBAAECggEAXHWlVnrXBGFK4w/TvjVdoAJqquPq8e8s9KzGP9B41zXB +PLO/1/Y/z7eamt7Mv0iFkrK43FkTbo7balQASjrV2WBhs3twNHNo5QwXj8WhpZFr +n+wW8V6EAaPb47IGsV+GTtYiU3ULCmMfjEbVvRvzrB9lGUzV08f4U/aEC9Dz9Phf +HBIBPfrSswxCpC3R+waccDDBr0TrSgCBaFPGdkm3Sk8Jk9LwflmQMxqiedS1uT1h +83I+TTyGYHtaVCzGF1pJaxVI5z2+X/8gbpoA+zgIVnzayqgy+tnGW1Fo4SFcHqBT +9GV1i56c9qYfMHOaAppmFVlueQJEt2s25wUERctWpQKBgQDN0VSPyYab2L0zo7AI +vZAdJvx292C0DU8zT8DUYiLbKkkcNBkbQb5KB096WnQtBfwvKagt6yCRfD2JX5ZM +CeICKlSz0f7O/jbgQf5ff4fTel0IyQlA4Ae7L1+6pZqPapPbh1doeAS5sL5/XziM +TQ7i5Zl7xHrIxqhjfNEpkTbpewKBgQDFc8YKCLPe9oqXTooQFGyqoHj6LITQ/MTo +KMKS4MY45Qe5Nc5aJolaeb1XmKI8mukLY7Bb611Zf4KxB3kaLydmCmfYttYXPaXc +w31zdLqkEcPw5dt+pY5+wnBRCrZIShYp0oUyb0h99WPvtZhPsguBmOzEkjleTjQw +0oUBX+WlzwKBgQC3xYJgxMtpWlRNyIlEtKX6MbZZLzbsbbnbEgoWWO3QjWgsQ6Rr +Pv9+sBpaIGv9S4vKPMLLBVfWL33urCfSCzz/O/bXfNis0DYFdUeA06levbJWRtL5 +V0/v5jPuvzFLfxk4ehck0408lED0D/y44ZE6LVInPd94aFEwS+Gi4OOMAwKBgQDE +QlglHxNSWjHVRT6bzwFX89trpxZ499XsgJ8uCPdeE+BCasXp+4XpBTp7N/6CSOO8 +62CfbOnDjKdluOzZZuc9WLhxwwI35ZHYRgOK4AqoC/R7nK04S+y/+BpVo1Uds24m +MdctE0m10VR9Lj3vcSRYs50bodAd+ZOMt6N2g1ArJwKBgBuLxgdH1OztXiB27WuP +VNHioNLw230vI0p4OhyVxCLHmosX9DyQWTt0l+7Xc/zmIIlzNv7i2XlSEesVIv+f +VodXMNEjyFdD5mdiBEc5lCrByd2RH5fqIaWa1BBbhza50vHW2toXof+9Xuj0hiux +y7b0H/NLY88/7vRCiXGr5WDD +-----END PRIVATE KEY----- diff -Nru munin-2.0.37/common/t/tls/openssl.cnf munin-2.0.47/common/t/tls/openssl.cnf --- munin-2.0.37/common/t/tls/openssl.cnf 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/common/t/tls/openssl.cnf 2019-02-28 14:43:36.000000000 +0000 @@ -1,58 +1,45 @@ -# -# OpenSSL configuration file. -# - -# Establish working directory. -dir = . - -[ ca ] -default_ca = CA_default - -[ CA_default ] -serial = $dir/CA/serial -database = $dir/CA/index.txt -new_certs_dir = $dir/CA/newcerts -certificate = $dir/CA/ca_cert.pem -private_key = $dir/CA/private/ca_key.pem -default_days = 365 -default_md = md5 -preserve = no -email_in_dn = no -nameopt = default_ca -certopt = default_ca -policy = policy_match - -[ policy_match ] -countryName = match -stateOrProvinceName = match -organizationName = match -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - - -[ req ] -default_bits = 1024 # Size of keys -default_md = md5 # message digest algorithm -string_mask = nombstr # permitted characters -distinguished_name = req_distinguished_name +# +# OpenSSL configuration file. +# + +# Establish working directory. +dir = . + +[ ca ] +default_ca = CA_default + +[ CA_default ] +serial = $dir/CA/serial +database = $dir/CA/index.txt +new_certs_dir = $dir/CA/newcerts +certificate = $dir/CA/ca_cert.pem +private_key = $dir/CA/private/ca_key.pem +default_md = default +email_in_dn = no +policy = policy_match + +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ req ] +default_bits = 2048 +string_mask = utf8only +distinguished_name = req_distinguished_name prompt = no req_extensions = v3_req [ req_distinguished_name ] -C = MU -ST = Province of Munin -L = Munin Town -O = Munin Inc. -OU = . -CN = 127.0.0.1 -emailAddress = munin@example.org - -[ v3_ca ] -basicConstraints = CA:TRUE -subjectKeyIdentifier = hash -authorityKeyIdentifier = keyid:always,issuer:always - -[ v3_req ] -basicConstraints = CA:FALSE -subjectKeyIdentifier = hash + +[ v3_ca ] +basicConstraints = CA:TRUE +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always + +[ v3_req ] +basicConstraints = CA:FALSE +subjectKeyIdentifier = hash diff -Nru munin-2.0.37/contrib/python-plugin/munin.py munin-2.0.47/contrib/python-plugin/munin.py --- munin-2.0.37/contrib/python-plugin/munin.py 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/contrib/python-plugin/munin.py 2019-02-28 14:43:36.000000000 +0000 @@ -10,10 +10,12 @@ 12/12 2008 """ -def getOptionOrDefault(option, default=None): + +def getOptionOrDefault(option, default=None): # noqa: N802 from os import environ return environ.setdefault(option, default) + class DataSource(object): """Represents a single data source. @@ -21,14 +23,14 @@ transparently by the Plugin-class.""" __slots__ = ['label', 'cdef', 'draw', 'graph', 'info', 'extinfo', 'max', - 'min', 'negative', 'type', 'warning', 'critical', 'colour', - 'skipdraw', 'sum', 'stack', 'line', 'value'] + 'min', 'negative', 'type', 'warning', 'critical', 'colour', + 'skipdraw', 'sum', 'stack', 'line', 'value'] # Allowed draw modes - _draw_modes = ['AREA', 'STACK', \ - 'LINE1', 'LINE2', 'LINE3', \ - 'LINESTACK1', 'LINESTACK2', 'LINESTACK3', \ - 'AREASTACK'] + _draw_modes = ['AREA', 'STACK', + 'LINE1', 'LINE2', 'LINE3', + 'LINESTACK1', 'LINESTACK2', 'LINESTACK3', + 'AREASTACK'] def get_config(self): if hasattr(self, "draw"): @@ -52,6 +54,7 @@ return self.value + class Plugin(object): """Facilitates OO creation of Munin plugins. @@ -62,8 +65,8 @@ p.autoconf = False for name, value in {'a': 1, 'b': 2}: - p[ name ].label = name - p[ name ].value = value + p[name].label = name + p[name].value = value p.run() @@ -74,10 +77,8 @@ """ - def __init__(self, title, vlabel, - category="misc", info="", - args="", - scale=True): + def __init__(self, title, vlabel, category="misc", info="", args="", + scale=True): """Sets up the plugin; title, vertical label, category -- all things that are global for the plugin. """ @@ -96,9 +97,9 @@ assert type(category) is str def __getitem__(self, key): - if not key in self._values: - self._values[ key ] = DataSource() - return self._values[ key ] + if key not in self._values: + self._values[key] = DataSource() + return self._values[key] def __setitem__(self, key, value): self._values[key] = value @@ -116,8 +117,8 @@ Similar to running with "values"-argument.""" for prefix, line in self._values.items(): value = line.get_value(prefix) - assert type(value) is int - print "%s.value %s" % (prefix, value) + assert isinstance(value, int) + print("%s.value %s" % (prefix, value)) def _print_config(self): """Print the output needed for setting up the graph - i.e. when the @@ -125,11 +126,11 @@ # Print graph_-variables for prop in ['title', 'category', 'vlabel', 'info', 'args', 'draw']: - if not prop in self.__dict__: + if prop not in self.__dict__: continue - if not self.__dict__[ prop ]: + if not self.__dict__[prop]: continue - print "graph_%s %s" % (prop, self.__dict__[ prop ]) + print("graph_%s %s" % (prop, self.__dict__[prop])) # Print setup for individual lines for prefix, line in self._values.items(): @@ -138,7 +139,7 @@ assert "label" in line.get_config().keys(), "No 'label' defined." for attr, value in line.get_config().items(): - print "%s.%s %s" % (prefix, attr, value) + print("%s.%s %s" % (prefix, attr, value)) def _print_autoconf(self): """Running autoconf-mode.""" @@ -150,17 +151,17 @@ else: aconf = self.autoconf - if bool(aconf): - print "YES" + if aconf: + print("yes") else: - print "NO" + print("no") def run(self, force_mode=None): """Run the plugin and "do the right thing"^(TM).""" mode = force_mode - if mode == None: + if mode is None: import sys if len(sys.argv) == 2: mode = sys.argv[1] diff -Nru munin-2.0.37/contrib/python-plugin/setup.py munin-2.0.47/contrib/python-plugin/setup.py --- munin-2.0.37/contrib/python-plugin/setup.py 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/contrib/python-plugin/setup.py 2019-02-28 14:43:36.000000000 +0000 @@ -3,22 +3,19 @@ from distutils.core import setup from subprocess import Popen, PIPE -from glob import glob # Get the current revision from SVN try: p = Popen(['svnversion'], stdout=PIPE) version = p.stdout.read().strip() -except: +except OSError: version = "unknown" -setup( - name = "python-munin", - version = version, - url = "http://dev.sbhr.dk/svn/python-munin", - author = "Morten Siebuhr", - author_email = "sbhr@sbhr.dk", - description = "", - #packages = ['munin'], - py_modules = ['munin'], - ) + +setup(name="python-munin", + version=version, + url="http://dev.sbhr.dk/svn/python-munin", + author="Morten Siebuhr", + author_email="sbhr@sbhr.dk", + description="", + py_modules=['munin']) diff -Nru munin-2.0.37/contrib/python-plugin/test.py munin-2.0.47/contrib/python-plugin/test.py --- munin-2.0.37/contrib/python-plugin/test.py 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/contrib/python-plugin/test.py 2019-02-28 14:43:36.000000000 +0000 @@ -15,25 +15,27 @@ p = Plugin("Approx cache", "files", "Approx") p.info = "Shows how many files the Approx cache stores, split by file-type." + def test(data_source): if data_source == 'deb': return 42 return 24 + # Set up graph p['deb'].label = "deb files" p['deb'].value = test p['deb'].info = "Number of .deb-files." p['tar.gz'].label = "tar.gz files" p['tar.gz'].value = test -#p['gzip'].value = 123 +# p['gzip'].value = 123 # Run -print "AUTOCONFIG" +print("AUTOCONFIG") p.run("autoconf") -print "CONFIG" +print("CONFIG") p.run("config") -print "PLAIN" +print("PLAIN") p.run() diff -Nru munin-2.0.37/COPYING munin-2.0.47/COPYING --- munin-2.0.37/COPYING 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/COPYING 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,21 @@ Munin - a network-wide graphing framework - Copyright (C) 2002-2009 Jimmy Olsen, et al. + Copyright (C) 2004-2010 Lupe Christoph + Copyright (C) 2004-2011 Jimmy Olsen + Copyright (C) 2006-2013 Nicolai Langfeldt + Copyright (C) 2007-2014 Matthias Schmitz + Copyright (C) 2007-2017 Stig Sandbeck Mathisen + Copyright (C) 2009-2009 Kjell-Magne Øierud + Copyright (C) 2009-2011 Matthew Boyle + Copyright (C) 2009-2011 Tom Feiner + Copyright (C) 2009-2012 Erik I. Bolsø + Copyright (C) 2010-2018 Steve Schnepp + Copyright (C) 2011-2018 Kenyon Ralph + Copyright (C) 2012-2015 Daniel Black + Copyright (C) 2013-2018 Gabriele Pohl + Copyright (C) 2015-2018 Quentin Stoeckel + Copyright (C) 2016-2018 Lars Kruse + ... and many more contributors This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -14,51 +29,3 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Includes the font Bitstream Vera Mono, which is under the following license: - - Copyright (C) 2003 Bitstream, Inc. - All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. - - Permission is hereby granted, free of charge, to any person obtaining a - copy of the fonts accompanying this license ("Fonts") and associated - documentation files (the "Font Software"), to reproduce and distribute - the Font Software, including without limitation the rights to use, copy, - merge, publish, distribute, and/or sell copies of the Font Software, and - to permit persons to whom the Font Software is furnished to do so, - subject to the following conditions: - - The above copyright and trademark notices and this permission notice - shall be included in all copies of one or more of the Font Software - typefaces. - - The Font Software may be modified, altered, or added to, and in - particular the designs of glyphs or characters in the Fonts may be - modified and additional glyphs or characters may be added to the Fonts, - only if the fonts are renamed to names not containing either the words - "Bitstream" or the word "Vera". - - This License becomes null and void to the extent applicable to Fonts or - Font Software that has been modified and is distributed under the - "Bitstream Vera" names. - - The Font Software may be sold as part of a larger software package but - no copy of one or more of the Font Software typefaces may be sold by - itself. - - THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL - BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, - OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR - OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT - SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. - - Except as contained in this notice, the names of Gnome, the Gnome - Foundation, and Bitstream Inc., shall not be used in advertising or - otherwise to promote the sale, use or other dealings in this Font - Software without prior written authorization from the Gnome Foundation - or Bitstream Inc., respectively. For further information, contact: - . diff -Nru munin-2.0.37/cpanfile munin-2.0.47/cpanfile --- munin-2.0.37/cpanfile 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/cpanfile 2019-02-28 14:43:36.000000000 +0000 @@ -2,6 +2,7 @@ # In all other regards (besides being used for testing) it is probably not # accurate (too many dependencies, ...). +requires 'Alien::RRDtool'; requires 'Digest::MD5'; requires 'File::Path'; requires 'File::ReadBackwards'; @@ -19,6 +20,7 @@ requires 'Log::Dispatch'; requires 'Log::Dispatch::Screen'; requires 'Log::Dispatch::Syslog'; +requires 'Log::Log4perl'; requires 'MIME::Base64'; requires 'Module::Build'; requires 'Net::DNS'; diff -Nru munin-2.0.37/debian/changelog munin-2.0.47/debian/changelog --- munin-2.0.37/debian/changelog 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/changelog 2019-04-13 00:33:48.000000000 +0000 @@ -1,3 +1,264 @@ +munin (2.0.47-1ubuntu3) disco; urgency=medium + + * Add missing test dependency on net-tools for netstat plugin. + + -- Steve Langasek Fri, 12 Apr 2019 17:33:48 -0700 + +munin (2.0.47-1ubuntu2) disco; urgency=medium + + * Drop sysvinit autopkgtests, sysvinit is not supported in Ubuntu. + + -- Steve Langasek Fri, 12 Apr 2019 15:01:41 -0700 + +munin (2.0.47-1ubuntu1) disco; urgency=low + + * Merge from Debian unstable. Remaining changes: + - Run the setup again, if upgrading from 2.0.37-1. This change can be + dropped after the Ubuntu 20.04 LTS release. + * Dropped changes, included in Debian: + - Revert more of f1f48dee so that directories are again setup correctly on + initial installations of munin-node and munin-async. + + -- Steve Langasek Fri, 12 Apr 2019 12:31:44 -0700 + +munin (2.0.47-1) unstable; urgency=medium + + [ Holger Levsen ] + * New upstream version 2.0.47. + + [ Lars Kruse ] + * New upstream version 2.0.46, Closes: #715141 + * Add 'Webservice' field to upstream metadata. + * munin-node.README.Debian: update plugin customization hints + * munin-node.README.Debian: mention behavioural changes due to systemd + (Closes: #921985) + * Remove references to "munin-sched" (removed by upstream) + + -- Holger Levsen Thu, 28 Feb 2019 16:06:07 +0100 + +munin (2.0.45-1) unstable; urgency=medium + + * New upstream release. + + -- Holger Levsen Thu, 07 Feb 2019 00:10:46 +0100 + +munin (2.0.44-2) unstable; urgency=medium + + [ Lars Kruse ] + * Add "netbase" to Depends for "munin" + * Add "netbase" to Depends for "munin-node" + + [ Holger Levsen ] + * Bump Standards-Version to 4.3.0, no changes needed. + + -- Holger Levsen Thu, 24 Jan 2019 13:02:41 +0100 + +munin (2.0.44-1) unstable; urgency=medium + + * New upstream bugfix release. + + [ Lars Kruse ] + * Move plugin-related "Suggests" from "munin-node" to plugin packages. + Closes: #755257 + * munin-node: + - move "gawk" and "procps" from Depends to Recommends. + - move "libnet-snmp-perl" from "Recommends" to "Suggests". + - remove suggests "libcrypt-ssleay-perl" and "libwww-perl". + + -- Holger Levsen Fri, 21 Dec 2018 15:59:09 +0100 + +munin (2.0.43-3) unstable; urgency=medium + + [ Lars Kruse ] + * Tests: handle autoconf detection for plugins "acpi" and "cpuspeed". + * Try to work around autopkgtest failure experienced on ci.d.n but not + locally. + + -- Holger Levsen Wed, 05 Dec 2018 12:42:56 +0100 + +munin (2.0.43-2) unstable; urgency=medium + + [ Lars Kruse ] + * Increase failure verbosity of "default plugin user" test. + + -- Holger Levsen Sun, 02 Dec 2018 18:22:42 +0100 + +munin (2.0.43-1) unstable; urgency=medium + + [ Lars Kruse ] + * New upstream version 2.0.43, Closes: #913661 + * Remove duplicate systemd-tmpfiles line for /run/munin from munin-node. + Thanks to Vincas Dargis (Closes: #913784) + * Add autopktest for default user context of plugins. + * Tests: remove temporary exception for stderr from "munindoc" + * Change Vcs-Git to canonical URL (appending ".git") + Thanks to lintian + * Lintian: override suggested service for init script. + The purpose of the init script is covered by munin.tmpfiles. + + -- Holger Levsen Sun, 18 Nov 2018 12:23:38 +0100 + +munin (2.0.42-6) unstable; urgency=medium + + [ Lars Kruse ] + * Fix test for MIME type of generated graphs (ignored before). + * Merge test code details from debian-experimental. + * Fix permissions of test files. + * Unify usage of comma/whitespace in debian/tests/control. + * Use more verbose tests for "expect no files". + * Tests: tolerate stderr output of "munindoc" for now. + + -- Holger Levsen Thu, 15 Nov 2018 11:41:20 +0100 + +munin (2.0.42-5) unstable; urgency=medium + + [ Lars Kruse ] + * Re-arrange tests for improved readability of test output + * Tests: Properly detect the assumed presence of the conntrack-related munin + plugins. Previously only the conntrack executable was checked - now the + alternative procfs files are evaluated, too. (Really closes: #910684) + + -- Holger Levsen Sun, 11 Nov 2018 13:48:17 +0100 + +munin (2.0.42-4) unstable; urgency=medium + + [ Lars Kruse ] + * tests for munin-node plugins: add conntrack-related plugins to the list of + expected plugins, if conntrack is available in the test environment. + This fixes the current autopktest failure. (Closes: #910684) + + -- Holger Levsen Sat, 10 Nov 2018 14:38:42 +0100 + +munin (2.0.42-3) unstable; urgency=medium + + [ Lars Kruse ] + * munin-async.postinst: fix handling of a missing "munin-async" group + (do not try to create the user again, but add it to the group instead) + * tests: do not rely on /var/cache/munin/www/localdomain to be created in + CGI mode + * add more build dependencies for upstream tests (test failures are + currently tolerated by upstream) + * d/tests/munin-node: increase verbosity of output in case of failure + for the test of available plugins + * d/tests/control: remove dependency on net-tools (introduced in 2.0.42-2) + as it did not fix the test failure + * Remove the empty directory /var/lib/munin-async from "munin" and add it to + "munin-node". This directory is required by "munin-sched" (shipped in + "munin-node"). + * munin and munin-node: remove the empty directory /var/run. + This directory was moved to /run, thus we should not create it + explicitly anymore. + * fix spelling of test filename munin-master/01.master-components.t + + -- Holger Levsen Thu, 08 Nov 2018 12:43:40 +0100 + +munin (2.0.42-2) unstable; urgency=medium + + * d/tests/control: Add dependency on net-tools for the plugin tests of + munin-node running with systemd. Thanks to Ivo De Decker for the analysis. + (Closes: #910684) + * d/control: Use the new debhelper-compat(=11) notation and drop d/compat. + + -- Holger Levsen Thu, 18 Oct 2018 14:12:57 +0200 + +munin (2.0.42-1) unstable; urgency=low + + [ Lars Kruse ] + * New upstream version 2.0.42. + * New upstream version 2.0.41, Closes: #717287 + * New upstream version 2.0.38, fixing various issues, including bugs in: + - postfix_mailstats: incorrect delivered message count (Closes: #675318) + - quota_usage_: documentation deviates from behaviour (Closes: #730030) + - munin outputs malformed XHTML (Closes: #732149) + - iostat_ios: plugin should support configuration (Closes: #767018) + - mysql_innodb: improve version detection (Closes: #901729) + * mysql plugins: switch the "mysqluser" from "debian-sys-maint" to "root" + in the plugin configuration. + See munin-node.NEWS entry for details. + (Closes: #862238, #864845) + * fix trivial spelling mistakes below debian/ (thanks "codespell") + * explicitly fail on erroneous OSTYPE detection + (this may help with analyzing #839233) + * use /run/munin/ instead of /var/run/munin/ (Closes: #790009) + * munin-node.service: create /var/log/munin, if missing + (Closes: #808988, Thanks Alejandro Suarez) + * remove outdated cached files (Closes: #700298) + * move program and file manpages from munin-doc to their respective + packages (Closes: 896440) + * munin: add missing manpage for "munin-graph" (Closes: #693402) + * munin-node: add missing manpage for "munin-sched" + * remove obsolete configuration file for apache2.2 in order to avoid + confusion (Closes: #700025, #783499) + * add /etc/munin/plugin-conf.d/README explaining order of processing + of config files (Closes: #767200) + * add separate plugin configuration file for "spamstats" plugin + (Closes: #831464) + * plugin dhcpd3: adjust default leases and config file locations + (Closes: #863534) + * Revert more of f1f48dee so that directories are again setup correctly on + initial installations of munin-node and munin-async. + Thanks Stefano Rivera! (Closes: #885454) + * munin-node: use the same group for chown of /var/log/munin as the + munin package (group "adm" instead of "www-data") + * adjust javac compile version to currently packaged Java versions + (Closes: #873993) + * remove references to missing documentation (munin-doc.* and munin-faq.*) + from "munin-node" (removed by upstream) + * improve README.PluginConfiguration (for "munin-node") + * increase compatibility level from 10 to 11 + * munin-plugins-extra: remove outdated alternate dependency on + "ruby-interpreter" (thanks piuparts) + * copyright: remove outdated reference to previously embedded fonts + * autopkgtest: update embedded "sharness" from 0.3 to 1.0 + (Thanks to Christian Göttsche: + https://github.com/munin-monitoring/munin/issues/844) + * autopkgtest: remove unused old test "munin-master" + * enable upstream tests during package build + * Remove upstreamed patch for Java version + * apache configuration: improved documentation and simplified switching + between "html_strategy cron" and "html_strategy cgi" + * munin.README.Debian: describe apache2 configuration (cgi/cron) + * Specify "Rules-Requires-Root" as "no" + * Bump Standards-Version to 4.2.1, no changes needed. + * Replace embedded copy of "sharness" with test dependency on the package + * Remove upstreamed patches for Java version and Makefile dependency + * Remove munin.service and skip init script instead for systemd + (Closes: 837788) + * Change Suggest for munin-plugins-core and munin-plugins-extra from + python to python3 (plugins were upgraded) + * Change copyright file to DEP-5 format (thanks, lintian) + * Add packages used for tests to "Build-Depends-Indep". + Previously the affected tests were simply skipped without the + requirement being installed. + * Remove "time" from "Suggests" (obsolete since v2.0.36) + * Remove "bc" from "Suggests" (obsolete since v2.0.39) + * Do not remove the user "munin-async" in postrm maintainer script + (see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=228692#18) + * Remove obsolete Suggest for "python" from munin-node + * Remove upstreamed patch for perl include directory + * Add Recommends for libnet-ldap-perl to munin-plugins-core + (Thanks, Christian Göttsche) + * debian/(changelog|control|rules): drop trailing whitespaces + (Thanks, lintian) + * Add multiple Suggests for munin-plugins-(core|extra) + * Add privilege limits to munin-node.service + * Use dpkg/pkg-info.mk for DEB_VERSION_UPSTREAM instead of + dpkg-parsechangelog (Thanks, lintian) + * Remove chmod-workaround for executable debian/ostype_helper + (obsolete due to the switch to quilt source format: #651449) + * Add debian/upstream/metadata + + -- Holger Levsen Mon, 08 Oct 2018 21:56:32 +0100 + +munin (2.0.37-2) unstable; urgency=medium + + * d/control: + - switch packaging to salsa.debian.org. Thanks to the alioth admins for + providing such a nice service so long! + - bump Standards-Version to 4.1.4, no changes needed. + + -- Holger Levsen Wed, 30 May 2018 23:41:48 +0000 + munin (2.0.37-1ubuntu1) cosmic; urgency=medium * Revert more of f1f48dee so that directories are again setup correctly on @@ -22,7 +283,7 @@ - add suggests to time. Closes: #862794 - add suggests to bc. Closes: #886516 * Switch maintainer address to team+munin@tracker.debian.org. - * debian/changelog: drop trailing whitespaces, thanks lintian. + * debian/changelog: drop trailing whitespaces, thanks lintian. -- Holger Levsen Thu, 29 Mar 2018 15:26:26 +0000 @@ -462,8 +723,8 @@ * Include the changes from 2.0.6-2 as actually uploaded to sid - and not as proposed in #694790. - * For 2.0.9-2 this effectly means stop using quilt (all patches have been - removed anyway, see 2.0.6-2 changelog) and a different (=the actual) + * For 2.0.9-2 this effectively means stop using quilt (all patches have + been removed anyway, see 2.0.6-2 changelog) and a different (=the actual) debian/changelog entry for 2.0.6-2. So this upload is basically a no-op. * Which actually means that 2.0.9-2 equals 2.0.9 plus 099cc00f, which was added in 2.0.6-2. @@ -687,7 +948,7 @@ munin (2.0~rc5-3) unstable; urgency=low - * Create /var/lib/munin/plugin-state in munin-node.postinst if it doesnt + * Create /var/lib/munin/plugin-state in munin-node.postinst if it does not exist. (Closes: #668975) -- Holger Levsen Mon, 16 Apr 2012 12:33:08 +0200 @@ -705,14 +966,14 @@ [ Holger Levsen ] * New upstream release candidate, quoting the upstream Changelog: - Adding the current action to the command line. Useful for debugging. - - Adding a new URL param full_size_mode to enable predictible IMG sizes + - Adding a new URL param full_size_mode to enable predictable IMG sizes - Enable sparklines with the url param "only_graph" - Start RRD just before first update. To avoid a very costly 1st update. - Emit the hosts in a sorted order, instead of somewhat random. - Do not emit png list if file handle is not defined. (Closes: #666759) - Add old option of --force-root, but with a new name. more explicit (Closes: #601371) - - We dont generate the png list when using cgi html. + - We do not generate the png list when using cgi html. - Remove warning when asking "list" w/o a hostname (LP: #907952) - Many bug fixes (trac: Closes #967, #1210) (Closes: #583189, #568511, Closes: #475078) @@ -1097,7 +1358,7 @@ * Remove 62 patches that have been merged in trunk. * Move htmldir to /var/cache/munin/www. (Closes: #553555) If you are upgrading, read NEWS.Debian. - Theres still work to be done implementing debconf presenting an option + There is still work to be done implementing debconf presenting an option where to install the htmldir, and possibly support more webservers by default. * Add new binary package: munin-common, which contains code shared by @@ -1229,7 +1490,8 @@ [ Matthias Schmitz ] * Add suggest to hdparm as need by hddtemp_smartctl (Closes: #531714) - * Catch unitialized values and munindoc'ify postgres_space_ (Closes: #518790) + * Catch uninitialized values and munindoc'ify postgres_space_ + (Closes: #518790) [ Holger Levsen ] * Bump Standards-version to 3.8.2. @@ -1248,7 +1510,7 @@ (Closes: #501189) * Add patch to linux cpu plugin to output correct graph if HZ value != 100, thanks to Valentin Vidic for the patch. (Closes: #500226) - * Add patch to acpi plugin to call acpi without -B as requiered by acpi in + * Add patch to acpi plugin to call acpi without -B as required by acpi in lenny and newer, thanks to Joey Hess. (Closes: #523239) * Include ejabberd plugin in munin-plugins-extra. Thanks to Christian Dröge for the plugin. (Closes: #505684) @@ -1288,7 +1550,7 @@ * munin-html: create needed directories if they don't exist. Normally this is done in munin-graph, but that's not used in cgi mode. Thanks to Peter Palfrader for the bugreport with patch! (Closes: #514634) - * node.d.linux/netstat.in: fix regex to only match openened connections, + * node.d.linux/netstat.in: fix regex to only match opened connections, thanks to Paul Slootman for 460-netstat-regex.patch. (Closes: #507069) -- Holger Levsen Sat, 28 Feb 2009 19:54:14 +0100 @@ -1482,7 +1744,7 @@ * Fix formatting errors in debian/NEWS. * Bump standards version to 3.7.3, no changes needed. * Remove versioned dependencies/suggests on python, perl-modules and - debhelper as they are all fullfilled even in oldstable. + debhelper as they are all fulfilled even in oldstable. * Update debian/copyright to reflect that munin is under the GPL2. * debian/rules: Don't ignore failures in the clean target. * Move debhelper and quilt to Build-Depends:. @@ -1607,7 +1869,7 @@ * server/munin-graph.in: - Gave up waiting for the new upstream release, and applied Robert Loomans' patch to make Munin support RRDtool 1.2, closes: #324605, - closes: #325280. Thanks, Robert! Note that this breaks compability + closes: #325280. Thanks, Robert! Note that this breaks compatibility with RRDtool 1.0. Sarge users should wait for the new upstream release which will support both RRDtool 1.0 and 1.2. @@ -1751,7 +2013,7 @@ file, closes: #291849. - Plugin linux/fw_forwarded_local now correctly reports 0 instead of NaN in some situations, closes: #284673. - - Plugin linux/iostat now ingores devices that have had no I/O operations + - Plugin linux/iostat now ignores devices that have had no I/O operations whatsoever and thus are assumed to be unused, closes: #267195. - New plugin: linux/forks. Closes: #225638. - New plugin: linux/uptime. Closes: #283622. @@ -1796,7 +2058,7 @@ * server/munin-limits.in: - Change lock file directory to match that of munin-update, munin-graph, and munin-html (grabbed from upstream CVS). - - Fix a string comparsions where the "==" operator was used instead of + - Fix a string comparisons where the "==" operator was used instead of "eq" (grabbed from upstream CVS). * debian/munin.postinst: @@ -1841,7 +2103,7 @@ munin (1.0.2-1) unstable; urgency=low - * New upstream release, fixing the follwing: + * New upstream release, fixing the following: - munin-graph spews uninitialized value in concatenation [precedence error], thanks to Don Armstrong (Closes: #267185). * Run the hddtemp plugins as root, write access to the device isn't @@ -1959,7 +2221,7 @@ sort-of closes: #214277. - Relaxes the paranoia regarding the plugins' ownership and permission modes somewhat, closes: #214186, #216401. - - Further impovements to the error-handling logic in lrrd-server, which + - Further improvements to the error-handling logic in lrrd-server, which hopefully closes: #215739, #222674, #222821. - Removed the spurious use of Config::General in lrrd-client, closes: #216176. @@ -1979,7 +2241,7 @@ - Polished slightly. * debian/lrrd-client.dirs: - - Removed unecessary entry /var/run/lrrd, which is installed from the + - Removed unnecessary entry /var/run/lrrd, which is installed from the Makefile. * debian/lrrd-client.init: @@ -2102,3 +2364,4 @@ * Initial release, closes: #169079. -- Tore Anderson Sat, 31 May 2003 17:15:35 +0200 + diff -Nru munin-2.0.37/debian/compat munin-2.0.47/debian/compat --- munin-2.0.37/debian/compat 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -10 diff -Nru munin-2.0.37/debian/control munin-2.0.47/debian/control --- munin-2.0.37/debian/control 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/control 2019-04-12 19:31:44.000000000 +0000 @@ -3,50 +3,54 @@ Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Munin Debian Maintainers -Uploaders: Holger Levsen , +Uploaders: Holger Levsen , Stig Sandbeck Mathisen Build-Depends-Indep: - openjdk-8-jdk, + default-jdk, html2text, htmldoc, + libfile-slurp-perl, + libhtml-template-perl, + libio-stringy-perl, + liblist-moreutils-perl, + liblog-log4perl-perl, + libnet-server-perl, + libnet-snmp-perl, + libnet-ssleay-perl, + librrds-perl, + libtest-deep-perl, + libtest-differences-perl, + libtest-exception-perl, + libtest-longstring-perl, + libtest-mockmodule-perl, + libtest-mockobject-perl, perl, Build-Depends: - debhelper (>=10.2.5~), + debhelper-compat (=11), libmodule-build-perl, -Standards-Version: 4.1.3 +Rules-Requires-Root: no +Standards-Version: 4.3.0 Homepage: http://munin-monitoring.org -Vcs-Git: https://anonscm.debian.org/git/collab-maint/munin.git -b debian -Vcs-Browser: https://anonscm.debian.org/git/collab-maint/munin.git +Vcs-Git: https://salsa.debian.org/debian/munin.git -b debian +Vcs-Browser: https://salsa.debian.org/debian/munin Package: munin-node Architecture: all Depends: ${misc:Depends}, ${perl:Depends}, - gawk, libnet-server-perl, lsb-base (>= 4.1), munin-common (>= ${binary:Version}), munin-plugins-core, + netbase, +Recommends: + gawk, + munin-plugins-extra, procps, -Recommends: libnet-snmp-perl, munin-plugins-extra Suggests: - acpi | lm-sensors, - ethtool, - hdparm, - libcrypt-ssleay-perl, - libdbd-pg-perl, - liblwp-useragent-determined-perl, - libnet-irc-perl, - libtext-csv-xs-perl, - libwww-perl, - libxml-simple-perl, - logtail, munin, munin-plugins-java, - default-mysql-client, - net-tools, - python, - ruby, - smartmontools, +Replaces: munin-doc (<< 2.0.37-3) +Breaks: munin-doc (<< 2.0.37-3) Description: network-wide graphing framework (node) Munin is a highly flexible and powerful solution used to create graphs of virtually everything imaginable throughout your network, while still @@ -67,17 +71,29 @@ Depends: ${perl:Depends}, ${misc:Depends}, munin-common (>= ${binary:Version}) Recommends: libnet-snmp-perl Suggests: - bc, + acpi | lm-sensors, conntrack, + default-mysql-client, + ethtool, + hdparm, + libdbd-pg-perl, + libhttp-date-perl, + liblwp-useragent-determined-perl, + libnet-ip-perl, + libnet-irc-perl, + libnet-ldap-perl, libnet-netmask-perl, libnet-telnet-perl, libxml-parser-perl, + libxml-simple-perl, libcache-cache-perl, libdbd-mysql-perl, libnet-dns-perl, - python, - ruby | ruby-interpreter, - time, + logtail, + net-tools, + python3, + ruby, + smartmontools, Description: network-wide graphing framework (plugins for node) Munin is a highly flexible and powerful solution used to create graphs of virtually everything imaginable throughout your network, while still @@ -85,9 +101,9 @@ . This package contains the official plugins for the Munin node, capable of extracting common values such as cpu usage, network usage, load average, and - so on. + so on. . - Creating your own plugins which are capable of extracting other system-specific + Creating your own plugins which are capable of extracting other system-specific values is very easy, and is often done in a matter of minutes. You can also create plugins which relay information from other devices in your network that can't run Munin, such as a switch or a server running another @@ -100,14 +116,23 @@ Package: munin-plugins-extra Architecture: all Depends: ${misc:Depends}, ${perl:Depends}, munin-common (>= ${binary:Version}) -Suggests: libnet-netmask-perl, python, libnet-telnet-perl +Suggests: + libcache-memcached-perl, + liblwp-useragent-determined-perl, + libnet-ip-perl, + libnet-netmask-perl, + libnet-telnet-perl, + libnet-snmp-perl, + libtext-csv-xs-perl, + libxml-libxml-perl, + python3, Description: network-wide graphing framework (user contributed plugins for node) Munin is a highly flexible and powerful solution used to create graphs of virtually everything imaginable throughout your network, while still maintaining a rattling ease of installation and configuration. . This package contains unsupported plugins for the Munin node, contributed by - various users of Munin. + various users of Munin. . Munin is written in Perl, and relies heavily on Tobi Oetiker's excellent RRDtool. To see a real example of Munin in action, you can follow a link @@ -123,8 +148,8 @@ virtually everything imaginable throughout your network, while still maintaining a rattling ease of installation and configuration. . - This package contains the java based plugins that are used by munin-node to - monitor Java Management Extensions (JMX). + This package contains the java based plugins that are used by munin-node to + monitor Java Management Extensions (JMX). . Munin is written in Perl, and relies heavily on Tobi Oetiker's excellent RRDtool. To see a real example of Munin in action, you can follow a link @@ -147,9 +172,12 @@ libtime-hires-perl, liburi-perl, munin-common (>= ${binary:Version}), + netbase, rrdtool, Recommends: munin-node, munin-doc, libcgi-fast-perl Suggests: www-browser, httpd, libnet-ssleay-perl, libapache2-mod-fcgid +Replaces: munin-doc (<< 2.0.37-3) +Breaks: munin-doc (<< 2.0.37-3) Description: network-wide graphing framework (grapher/gatherer) Munin is a highly flexible and powerful solution used to create graphs of virtually everything imaginable throughout your network, while still @@ -174,6 +202,8 @@ Depends: ${perl:Depends}, ${misc:Depends}, adduser, liblist-moreutils-perl, +Replaces: munin-doc (<< 2.0.37-3) +Breaks: munin-doc (<< 2.0.37-3) Description: network-wide graphing framework (common) Munin is a highly flexible and powerful solution used to create graphs of virtually everything imaginable throughout your network, while still diff -Nru munin-2.0.37/debian/copyright munin-2.0.47/debian/copyright --- munin-2.0.37/debian/copyright 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/copyright 2019-03-01 00:01:25.000000000 +0000 @@ -1,67 +1,41 @@ -Munin is maintained for Debian by Tore Anderson . +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Source: https://github.com/munin-monitoring/munin -The upstream source is available from . - -Lead developers include: - - Audun Ytterdal - Jimmy Olsen - Tore Anderson - Knut Haugen - Ingvar Hagelund - -Munin is licensed under the terms of the GNU General Public License, version 2. -A verbatim copy of this license is found in the file - - `/usr/share/common-licenses/GPL-2' - -on every Debian GNU/Linux system. - -The font Bitstream Vera Mono is bundled with this package, and is distributed -under the following licence: - - Copyright (C) 2003 Bitstream, Inc. - All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. - - Permission is hereby granted, free of charge, to any person obtaining a - copy of the fonts accompanying this license ("Fonts") and associated - documentation files (the "Font Software"), to reproduce and distribute - the Font Software, including without limitation the rights to use, copy, - merge, publish, distribute, and/or sell copies of the Font Software, and - to permit persons to whom the Font Software is furnished to do so, - subject to the following conditions: - - The above copyright and trademark notices and this permission notice - shall be included in all copies of one or more of the Font Software - typefaces. - - The Font Software may be modified, altered, or added to, and in - particular the designs of glyphs or characters in the Fonts may be - modified and additional glyphs or characters may be added to the Fonts, - only if the fonts are renamed to names not containing either the words - "Bitstream" or the word "Vera". - - This License becomes null and void to the extent applicable to Fonts or - Font Software that has been modified and is distributed under the - "Bitstream Vera" names. - - The Font Software may be sold as part of a larger software package but - no copy of one or more of the Font Software typefaces may be sold by - itself. - - THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL - BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, - OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR - OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT - SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. - - Except as contained in this notice, the names of Gnome, the Gnome - Foundation, and Bitstream Inc., shall not be used in advertising or - otherwise to promote the sale, use or other dealings in this Font - Software without prior written authorization from the Gnome Foundation - or Bitstream Inc., respectively. For further information, contact: - . +Files: * +License: GPL-2 +Copyright: 2004-2010 Lupe Christoph + 2004-2011 Jimmy Olsen + 2006-2013 Nicolai Langfeldt + 2007-2014 Matthias Schmitz + 2007-2017 Stig Sandbeck Mathisen + 2009-2009 Kjell-Magne Øierud + 2009-2011 Matthew Boyle + 2009-2011 Tom Feiner + 2009-2012 Erik I. Bolsø + 2010-2018 Steve Schnepp + 2011-2018 Kenyon Ralph + 2012-2015 Daniel Black + 2013-2018 Gabriele Pohl + 2015-2018 Quentin Stoeckel + 2016-2018 Lars Kruse + ... and many more contributors + +Files: debian/* +License: GPL-2 +Copyright: 2008-2018 Holger Levsen + 2009-2017 Stig Sandbeck Mathisen + 2016-2018 Lars Kruse + +License: GPL-2 + This program 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; version 2 dated June, 1991. + . + This program 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. + . + A copy of the GNU General Public License is available as + /usr/share/common-licenses/GPL-2 in the Debian distribution or on the World + Wide Web at https://www.gnu.org/licenses/. diff -Nru munin-2.0.37/debian/examples/nginx/munin-cgi-graph.init munin-2.0.47/debian/examples/nginx/munin-cgi-graph.init --- munin-2.0.37/debian/examples/nginx/munin-cgi-graph.init 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/examples/nginx/munin-cgi-graph.init 2019-03-01 00:01:25.000000000 +0000 @@ -21,8 +21,8 @@ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin NAME=munin-cgi-graph -PID_FILE="/var/run/munin/$NAME.pid" -SOCK_FILE="/var/run/munin/$NAME.socket" +PID_FILE="/run/munin/$NAME.pid" +SOCK_FILE="/run/munin/$NAME.socket" CGI_SCRIPT="/usr/lib/munin/cgi/$NAME" DAEMON=/usr/bin/spawn-fcgi DAEMON_OPTS="-s $SOCK_FILE -U www-data -u munin -g munin -P $PID_FILE -- $CGI_SCRIPT" diff -Nru munin-2.0.37/debian/examples/nginx/munin-cgi-html.init munin-2.0.47/debian/examples/nginx/munin-cgi-html.init --- munin-2.0.37/debian/examples/nginx/munin-cgi-html.init 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/examples/nginx/munin-cgi-html.init 2019-03-01 00:01:25.000000000 +0000 @@ -21,8 +21,8 @@ PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin NAME=munin-cgi-html -PID_FILE="/var/run/munin/$NAME.pid" -SOCK_FILE="/var/run/munin/$NAME.socket" +PID_FILE="/run/munin/$NAME.pid" +SOCK_FILE="/run/munin/$NAME.socket" CGI_SCRIPT="/usr/lib/munin/cgi/$NAME" DAEMON=/usr/bin/spawn-fcgi DAEMON_OPTS="-s $SOCK_FILE -U www-data -u munin -g munin -P $PID_FILE -- $CGI_SCRIPT" diff -Nru munin-2.0.37/debian/examples/nginx/munin.nginx.conf munin-2.0.47/debian/examples/nginx/munin.nginx.conf --- munin-2.0.37/debian/examples/nginx/munin.nginx.conf 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/examples/nginx/munin.nginx.conf 2019-03-01 00:01:25.000000000 +0000 @@ -34,14 +34,14 @@ location /munin/ { fastcgi_split_path_info ^(/munin)(.*); fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_pass unix:/var/run/munin/munin-cgi-html.socket; + fastcgi_pass unix:/run/munin/munin-cgi-html.socket; include fastcgi_params; } location ^~ /munin-cgi/munin-cgi-graph/ { fastcgi_split_path_info ^(/munin-cgi/munin-cgi-graph)(.*); fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_pass unix:/var/run/munin/munin-cgi-graph.socket; + fastcgi_pass unix:/run/munin/munin-cgi-graph.socket; include fastcgi_params; } } diff -Nru munin-2.0.37/debian/Makefile.config munin-2.0.47/debian/Makefile.config --- munin-2.0.37/debian/Makefile.config 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/Makefile.config 2019-03-01 00:01:24.000000000 +0000 @@ -24,5 +24,5 @@ CHMOD = \# CHGRP = \# -# Distiction between a Linux and FreeBSD kernel +# Distinction between a Linux and FreeBSD kernel OSTYPE := $(shell debian/ostype_helper) diff -Nru munin-2.0.37/debian/munin.apache24.conf munin-2.0.47/debian/munin.apache24.conf --- munin-2.0.37/debian/munin.apache24.conf 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin.apache24.conf 2019-03-01 00:01:24.000000000 +0000 @@ -1,16 +1,38 @@ -Alias /munin /var/cache/munin/www +# Munin configuration for apache2 +# +# Apache can serve munin's files that are either statically generated +# (in a cron job) or generated on demand (via cgi). +# The relevant munin settings are "html_strategy" and "graph_strategy". +# The related apache settings can be adjusted at the end of this file. +# +# See /usr/share/doc/munin/README.Debian for details. + + +# ***** COMMON SETTINGS FOR ALL STRATEGIES ***** + +ScriptAlias /munin-cgi/munin-cgi-graph /usr/lib/munin/cgi/munin-cgi-graph +Alias /munin/static/ /var/cache/munin/www/static/ + - Require local - Options None + Require local + Options None -ScriptAlias /munin-cgi/munin-cgi-graph /usr/lib/munin/cgi/munin-cgi-graph - - Require local - - SetHandler fcgid-script - - - SetHandler cgi-script - - + + Require local + + SetHandler fcgid-script + + + SetHandler cgi-script + + + + +# ***** SETTINGS FOR CGI/CRON STRATEGIES ***** + +# pick _one_ of the following lines depending on your "html_strategy" +# html_strategy: cron (default) +Alias /munin /var/cache/munin/www +# html_strategy: cgi (requires the apache module "cgid" or "fcgid") +#ScriptAlias /munin /usr/lib/munin/cgi/munin-cgi-html diff -Nru munin-2.0.37/debian/munin.apache.conf munin-2.0.47/debian/munin.apache.conf --- munin-2.0.37/debian/munin.apache.conf 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin.apache.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -# Enable this for template generation -Alias /munin /var/cache/munin/www - -# Enable this for cgi-based templates -#Alias /munin-cgi/static /var/cache/munin/www/static -#ScriptAlias /munin-cgi /usr/lib/munin/cgi/munin-cgi-html -# -# Order allow,deny -# Allow from localhost 127.0.0.0/8 ::1 -# AuthUserFile /etc/munin/munin-htpasswd -# AuthName "Munin" -# AuthType Basic -# require valid-user -# - - - Order allow,deny - Allow from localhost 127.0.0.0/8 ::1 - Options None - - # This file can be used as a .htaccess file, or a part of your apache - # config file. - # - # For the .htaccess file option to work the munin www directory - # (/var/cache/munin/www) must have "AllowOverride all" or something - # close to that set. - # - - # AuthUserFile /etc/munin/munin-htpasswd - # AuthName "Munin" - # AuthType Basic - # require valid-user - - # This next part requires mod_expires to be enabled. - # - - # Set the default expiration time for files to 5 minutes 10 seconds from - # their creation (modification) time. There are probably new files by - # that time. - # - - - ExpiresActive On - ExpiresDefault M310 - - - - -# Enables fastcgi for munin-cgi-html if present -# -# -# SetHandler fastcgi-script -# -# - -# -# SetHandler None -# - -# Enables fastcgi for munin-cgi-graph if present -ScriptAlias /munin-cgi/munin-cgi-graph /usr/lib/munin/cgi/munin-cgi-graph - - Order allow,deny - Allow from localhost 127.0.0.0/8 ::1 - # AuthUserFile /etc/munin/munin-htpasswd - # AuthName "Munin" - # AuthType Basic - # require valid-user - - SetHandler fcgid-script - - - SetHandler cgi-script - - - -ScriptAlias /munin-cgi/munin-cgi-html /usr/lib/munin/cgi/munin-cgi-html - - Order allow,deny - Allow from localhost 127.0.0.0/8 ::1 - # AuthUserFile /etc/munin/munin-htpasswd - # AuthName "Munin" - # AuthType Basic - # require valid-user - - SetHandler fcgid-script - - - SetHandler cgi-script - - - diff -Nru munin-2.0.37/debian/munin-async.init munin-2.0.47/debian/munin-async.init --- munin-2.0.37/debian/munin-async.init 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin-async.init 2019-03-01 00:01:24.000000000 +0000 @@ -20,7 +20,7 @@ DAEMON=/usr/share/munin/$NAME DAEMON_ARGS="" DAEMON_USER="munin-async" -PIDFILE=/var/run/munin/$NAME.pid +PIDFILE=/run/munin/$NAME.pid SCRIPTNAME=/etc/init.d/munin-async # Exit if the package is not installed diff -Nru munin-2.0.37/debian/munin-async.postinst munin-2.0.47/debian/munin-async.postinst --- munin-2.0.37/debian/munin-async.postinst 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin-async.postinst 2019-04-12 19:31:44.000000000 +0000 @@ -8,10 +8,10 @@ if ! getent passwd munin-async >/dev/null; then adduser --group --system --home /var/lib/munin-async --shell /bin/bash munin-async fi - # workaround bug (#531021) in xen-tools + # workaround bug (#531021) in xen-tools (user exists, but group is missing) if ! getent group munin-async >/dev/null; then addgroup --system munin-async - adduser --shell /bin/bash munin-async + adduser munin-async munin-async fi } diff -Nru munin-2.0.37/debian/munin-async.postrm munin-2.0.47/debian/munin-async.postrm --- munin-2.0.37/debian/munin-async.postrm 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin-async.postrm 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -#! /bin/sh - -set -e - -prevver="$2" - -del_munin_async_user() { - if getent passwd munin-async >/dev/null; then - userdel -r munin-async - fi -} - -case "$1" in - purge) - del_munin_async_user - ;; - *) - ;; -esac - -#DEBHELPER# diff -Nru munin-2.0.37/debian/munin-common.manpages munin-2.0.47/debian/munin-common.manpages --- munin-2.0.37/debian/munin-common.manpages 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/debian/munin-common.manpages 2019-02-28 14:50:42.000000000 +0000 @@ -0,0 +1 @@ +build/doc/munin.8 diff -Nru munin-2.0.37/debian/munin.cron.d munin-2.0.47/debian/munin.cron.d --- munin-2.0.37/debian/munin.cron.d 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin.cron.d 2019-03-01 00:01:25.000000000 +0000 @@ -6,3 +6,7 @@ */5 * * * * munin if [ -x /usr/bin/munin-cron ]; then /usr/bin/munin-cron; fi 14 10 * * * munin if [ -x /usr/share/munin/munin-limits ]; then /usr/share/munin/munin-limits --force --contact nagios --contact old-nagios; fi + +# remove stale generated html and graph files (e.g. disabled plugins or fields with volatile names) +27 03 * * * munin if [ -d /var/cache/munin/www ]; then find /var/cache/munin/www/ -type f -name "*.html" -mtime +30 -delete; find /var/cache/munin/www/ -mindepth 1 -type d -empty -delete; fi +32 03 * * * www-data if [ -d /var/lib/munin/cgi-tmp ]; then find /var/lib/munin/cgi-tmp/ -type f -mtime +1 -delete; find /var/lib/munin/cgi-tmp/ -mindepth 1 -type d -empty -delete; fi diff -Nru munin-2.0.37/debian/munin-doc.manpages munin-2.0.47/debian/munin-doc.manpages --- munin-2.0.37/debian/munin-doc.manpages 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin-doc.manpages 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -build/doc/munin-cron.8 -build/doc/munin-html.8 -build/doc/munin-limits.8 -build/doc/munin-update.8 -build/doc/munin-check.8 -build/doc/munin.conf.5 -build/doc/munin.8 -build/doc/munin-node.conf.5 -node/blib/bindoc/munin-run.1p -node/blib/bindoc/munindoc.1p -node/blib/bindoc/munin-node.1p -node/blib/bindoc/munin-node-configure.1p diff -Nru munin-2.0.37/debian/munin.init munin-2.0.47/debian/munin.init --- munin-2.0.37/debian/munin.init 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin.init 2019-03-01 00:01:24.000000000 +0000 @@ -6,16 +6,21 @@ # Required-Stop: $network $named $local_fs $remote_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 -# Short-Description: Create /var/run/munin on boot -# Description: Create /var/run/munin on boot. Munin itself runs as CGI and has no extra startscript... +# Short-Description: Create /run/munin on boot +# Description: Create /run/munin on boot. Munin itself runs as CGI and has no extra startscript... ### END INIT INFO + +# systemd creates the necessary directories (see /usr/lib/tmpfiles.d/munin-common.conf) +test -d /run/systemd/system && exit 0 + + . /lib/lsb/init-functions case "$1" in start|restart|force-reload) # Create various dirs - mkdir -p /var/run/munin && chown munin /var/run/munin + mkdir -p /run/munin && chown munin /run/munin exit $? ;; stop) diff -Nru munin-2.0.37/debian/munin.links munin-2.0.47/debian/munin.links --- munin-2.0.37/debian/munin.links 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin.links 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -dev/null lib/systemd/system/munin.service diff -Nru munin-2.0.37/debian/munin.lintian-overrides munin-2.0.47/debian/munin.lintian-overrides --- munin-2.0.37/debian/munin.lintian-overrides 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin.lintian-overrides 2019-03-01 00:01:25.000000000 +0000 @@ -1,6 +1,3 @@ -munin binary: binary-without-manpage usr/bin/munin-check -munin binary: binary-without-manpage usr/bin/munin-cron - -# lintian error, service file can be a link to /dev/null to mask it. -munin binary: service-file-is-not-a-file lib/systemd/system/munin.service -munin binary: service-file-is-not-a-file lib/systemd/system/munin.service +# The munin init script only creates /run/munin. +# This is covered by debian/munin.tmpfiles for systemd. Thus there is no need for a service. +missing-systemd-service-for-init.d-script munin diff -Nru munin-2.0.37/debian/munin.manpages munin-2.0.47/debian/munin.manpages --- munin-2.0.37/debian/munin.manpages 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/debian/munin.manpages 2019-02-28 14:50:43.000000000 +0000 @@ -0,0 +1,7 @@ +build/doc/munin.conf.5 +build/doc/munin-check.8 +build/doc/munin-cron.8 +build/doc/munin-graph.8 +build/doc/munin-html.8 +build/doc/munin-limits.8 +build/doc/munin-update.8 diff -Nru munin-2.0.37/debian/munin.NEWS munin-2.0.47/debian/munin.NEWS --- munin-2.0.37/debian/munin.NEWS 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin.NEWS 2019-03-01 00:01:24.000000000 +0000 @@ -104,7 +104,7 @@ could not be accomplished without introducing a risk of losing historical data after upgrades. Or more precisely: no data will be lost, but the exact name of the RRD file will change, so that the update process will - start collecting data into a new, emtpy, file, which in turn will be read + start collecting data into a new, empty, file, which in turn will be read by munin-graph, and the final result is that the graph will appear to have lost all data. The historical data will still be present in the old graph. @@ -183,7 +183,7 @@ longer than 18 characters be truncated, removing any excessive characters from the start of the field name. This led to a nasty bug; if a plugin reported values for two fields, who both had long names where the last 18 - charaters were the same, only one RRD file would be generated, and its + characters were the same, only one RRD file would be generated, and its contents would be unpredictable. The 1.2.x series do not exhibit this behaviour, and will store the entire field name as part of the RRD file name. As this leads to the fact that a new, empty, file will be created @@ -278,7 +278,7 @@ See http://munin-monitoring.org/wiki/CgiHowto2 for more information. The munin-node package now only provides the actual node, plugins are - provided in seperate munin-plugins* packages. munin-async is a new feature + provided in separate munin-plugins* packages. munin-async is a new feature in 2.0 The documentation for munin has been moved to the new "munin-doc" package. diff -Nru munin-2.0.37/debian/munin-node.cron.d munin-2.0.47/debian/munin-node.cron.d --- munin-2.0.37/debian/munin-node.cron.d 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin-node.cron.d 2019-03-01 00:01:24.000000000 +0000 @@ -5,7 +5,7 @@ MAILTO=root # If the APT plugin is enabled, update packages databases approx. once -# an hour (12 invokations an hour, 1 in 12 chance that the update will +# an hour (12 invocations an hour, 1 in 12 chance that the update will # happen), but ensure that there will never be more than two hour (7200 # seconds) interval between updates.. */5 * * * * root if [ -x /etc/munin/plugins/apt_all ]; then /etc/munin/plugins/apt_all update 7200 12 >/dev/null; elif [ -x /etc/munin/plugins/apt ]; then /etc/munin/plugins/apt update 7200 12 >/dev/null; fi diff -Nru munin-2.0.37/debian/munin-node.docs munin-2.0.47/debian/munin-node.docs --- munin-2.0.37/debian/munin-node.docs 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin-node.docs 2019-03-01 00:01:25.000000000 +0000 @@ -1,3 +1 @@ -build/doc/munin-faq.* -build/doc/munin-doc.* debian/README.PluginConfiguration diff -Nru munin-2.0.37/debian/munin-node.init munin-2.0.47/debian/munin-node.init --- munin-2.0.37/debian/munin-node.init 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin-node.init 2019-03-01 00:01:24.000000000 +0000 @@ -12,7 +12,7 @@ PATH=/sbin:/bin:/usr/sbin:/usr/bin DAEMON=/usr/sbin/munin-node -PIDFILE=/var/run/munin/munin-node.pid +PIDFILE=/run/munin/munin-node.pid CONFFILE=/etc/munin/munin-node.conf DAEMON_ARGS= @@ -48,10 +48,10 @@ start() { log_daemon_msg "Starting Munin-Node" - mkdir -p /var/run/munin /var/log/munin - chown munin:root /var/run/munin - chown munin:www-data /var/log/munin - chmod 0755 /var/run/munin + mkdir -p /run/munin /var/log/munin + chown munin:root /run/munin + chown munin:adm /var/log/munin + chmod 0755 /run/munin chmod 0755 /var/log/munin if pidofproc -p $PIDFILE $DAEMON >/dev/null; then log_progress_msg "started beforehand" diff -Nru munin-2.0.37/debian/munin-node.lintian-overrides munin-2.0.47/debian/munin-node.lintian-overrides --- munin-2.0.37/debian/munin-node.lintian-overrides 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin-node.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -munin-node binary: binary-without-manpage usr/sbin/munin-node -munin-node binary: binary-without-manpage usr/sbin/munin-node-configure -munin-node binary: binary-without-manpage usr/sbin/munin-run -munin-node binary: binary-without-manpage usr/sbin/munin-sched -munin-node binary: binary-without-manpage usr/bin/munindoc -munin-node binary: dependency-on-python-version-marked-for-end-of-life (Suggests: python) diff -Nru munin-2.0.37/debian/munin-node.manpages munin-2.0.47/debian/munin-node.manpages --- munin-2.0.37/debian/munin-node.manpages 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/debian/munin-node.manpages 2019-02-28 14:50:42.000000000 +0000 @@ -0,0 +1,5 @@ +build/doc/munin-node.conf.5 +node/blib/bindoc/munindoc.1p +node/blib/bindoc/munin-node.1p +node/blib/bindoc/munin-node-configure.1p +node/blib/bindoc/munin-run.1p diff -Nru munin-2.0.37/debian/munin-node.NEWS munin-2.0.47/debian/munin-node.NEWS --- munin-2.0.37/debian/munin-node.NEWS 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin-node.NEWS 2019-03-01 00:01:24.000000000 +0000 @@ -1,3 +1,17 @@ +munin-node (2.0.42-1) unstable; urgency=low + + The mysql_* plugins no longer use the "debian-sys-maint" account for + accessing the mysql database, but use "root" instead. This is based + on authentication via unix socket (introduced in mariadb v10.0). + You may need to override the munin plugin configuration for "mysql_*" + (e.g. in /etc/munin/plugin-conf.d/foo) if your mariadb server was + upgraded from a mysql server package and thus does not support unix + socket based authentication. This situation can be tested by running + "mysql -u root" without providing a password. No action is required, + if this works for you. + + -- Lars Kruse Sun, 05 Aug 2018 03:03:58 +0200 + munin-node (1.4.0-1) unstable; urgency=low munin-node-configure-snmp command is no longer available, use @@ -16,7 +30,7 @@ could not be accomplished without introducing a risk of losing historical data after upgrades. Or more precisely: no data will be lost, but the exact name of the RRD file will change, so that the update process will - start collecting data into a new, emtpy, file, which in turn will be read + start collecting data into a new, empty, file, which in turn will be read by munin-graph, and the final result is that the graph will appear to have lost all data. The historical data will still be present in the old graph. @@ -95,7 +109,7 @@ longer than 18 characters be truncated, removing any excessive characters from the start of the field name. This led to a nasty bug; if a plugin reported values for two fields, who both had long names where the last 18 - charaters were the same, only one RRD file would be generated, and its + characters were the same, only one RRD file would be generated, and its contents would be unpredictable. The 1.2.x series do not exhibit this behaviour, and will store the entire field name as part of the RRD file name. As this leads to the fact that a new, empty, file will be created diff -Nru munin-2.0.37/debian/munin-node.README.Debian munin-2.0.47/debian/munin-node.README.Debian --- munin-2.0.37/debian/munin-node.README.Debian 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin-node.README.Debian 2019-03-01 00:01:24.000000000 +0000 @@ -11,12 +11,13 @@ You'll find more plugins in /usr/share/munin/plugins, which you can enable by creating symlinks into /etc/munin/plugins as appropriate. - Creating your own plugins is very easy. Read the rest of the included - documents, take a look at the provided plugins, and write your own. - Please use Latin-1 as file encoding since munin expects only Latin-1 - characters. Place it in /etc/munin/plugins/, and restart the client. - The core process will automatically notice the new service, and start - graphing it. + Creating your own plugins is very easy. + See + and enjoy the simplicity of the design. + Place your custom plugin in /etc/munin/plugins/, test their behaviour + with "munin-run PLUGIN_NAME" and restart the munin-node service. + The munin master process will automatically notice the new plugin and + start graphing it. Locally modified plugins ------------------------ @@ -24,17 +25,26 @@ If you wish to change the behaviour of the provided plugins, you are strongly encouraged to make a copy of the plugin as installed in /usr/share/munin/plugins/, and place it in /etc/munin/plugins/. Then, - make your modifications in the copy. I strenously stress that it is - discouraged to make local modifications directly in plugins found in the - /usr/share/munin/plugin/ directories, as these files are managed by - dpkg - changes may very well be overwritten on upgrades. Also, such - changes will likely break intrusion detection systems which relies - on dpkg's database for reference. + make your modifications in the copy. - It is worth noting that many things can be overridden in the core process' + It is worth noting that many things can be overridden in the munin master configuration file, so it is quite possible that a modification is not necessary. + Systemd, munin-node and plugins + ------------------------------- + + The systemd service specification for munin-node imposes a few + restrictions on the context of plugin execution. + This may cause confusion, as the plugins' behaviour will depend on + whether they are executed manually in "munin-run" (for debugging) or + indirectly via "munin-node" (when being queried by the munin master). + For example plugins are not allowed to read /home (may be relevant for + the "df*" plugins) and they use a private /tmp directory. + See /lib/systemd/system/munin-node.service for the default settings of + the munin-node service. All settings can be overridden permanently + via "systemctl edit munin-node". + Suggestions? Impressions? Questions? Fanmail? Love letters? Murder threats? --------------------------------------------------------------------------- @@ -50,7 +60,7 @@ Find the upstream source ------------------------ This Debian package uses the upstream tarball located here: - http://sourceforge.net/projects/munin . + http://downloads.munin-monitoring.org/ . It also uses quilt to apply some debian specific patches located in ./debian/patches/ diff -Nru munin-2.0.37/debian/munin-node.service munin-2.0.47/debian/munin-node.service --- munin-2.0.37/debian/munin-node.service 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin-node.service 2019-03-01 00:01:24.000000000 +0000 @@ -9,6 +9,12 @@ Restart=always ExecStart=/usr/sbin/munin-node $DAEMON_ARGS PIDFile=/run/munin/munin-node.pid +# Plugins like "smart_" require access to devices +PrivateDevices=false +PrivateTmp=true +ProtectHome=true +# "full" (instead of "strict") still allows write access to the state files +ProtectSystem=full [Install] WantedBy=multi-user.target diff -Nru munin-2.0.37/debian/munin-node.tmpfile munin-2.0.47/debian/munin-node.tmpfile --- munin-2.0.37/debian/munin-node.tmpfile 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/debian/munin-node.tmpfile 2019-02-28 14:50:42.000000000 +0000 @@ -0,0 +1,3 @@ +# keep in sync with debian/munin.munin-node.init (non-systemd) +# /run/munin is handled by the dependent package "munin-common" (see debian/munin-common.tmpfile) +d /var/log/munin 0755 munin adm diff -Nru munin-2.0.37/debian/munin-plugins-core.lintian-overrides munin-2.0.47/debian/munin-plugins-core.lintian-overrides --- munin-2.0.37/debian/munin-plugins-core.lintian-overrides 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin-plugins-core.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -munin-plugins-core binary: dependency-on-python-version-marked-for-end-of-life (Suggests: python) diff -Nru munin-2.0.37/debian/munin-plugins-extra.lintian-overrides munin-2.0.47/debian/munin-plugins-extra.lintian-overrides --- munin-2.0.37/debian/munin-plugins-extra.lintian-overrides 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin-plugins-extra.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -munin-plugins-extra binary: dependency-on-python-version-marked-for-end-of-life (Suggests: python) diff -Nru munin-2.0.37/debian/munin.postinst munin-2.0.47/debian/munin.postinst --- munin-2.0.37/debian/munin.postinst 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin.postinst 2019-03-01 00:01:25.000000000 +0000 @@ -30,24 +30,8 @@ } apache_install() { - # if you add more webservers here, dont forget to also remove them in postrm + # if you add more webservers here, don't forget to also remove them in postrm webserver=apache2 - webserver_init_script="/etc/init.d/$webserver" - if [ -d /etc/$webserver/conf.d ] && [ ! -e /etc/$webserver/conf.d/munin ]; then - if [ -z "$prevver" ] ; then - # only create link on new installs - ln -s ../../munin/apache.conf /etc/$webserver/conf.d/munin - fi - if [ -f $webserver_init_script ];then - if [ -x $webserver_init_script ]; then - invoke-rc.d $webserver reload 3>/dev/null || true - else - echo "munin: $webserver_init_script is not executable."\ - "Could not reload $webserver" - fi - fi - fi - # installing configuration for Apache 2.4 # link config to conf-available if [ -d /etc/$webserver/conf-available ] && [ ! -e /etc/$webserver/conf-available/munin.conf ]; then @@ -67,7 +51,7 @@ configure) if [ -z "$2" ] ; then initperms - apache_install $@ + apache_install "$@" fi ;; abort-upgrade|abort-deconfigure|abort-remove) diff -Nru munin-2.0.37/debian/munin.postrm munin-2.0.47/debian/munin.postrm --- munin-2.0.37/debian/munin.postrm 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin.postrm 2019-03-01 00:01:24.000000000 +0000 @@ -35,15 +35,6 @@ delete_dir_if_empty /etc/munin webserver=apache2 - if [ -L /etc/$webserver/conf.d/munin ]; then - # delete the link - rm -f /etc/$webserver/conf.d/munin - # apache2-maintscript-helper will restart apache anyway - if [ ! -e /usr/share/apache2/apache2-maintscript-helper ] ; then - invoke-rc.d $webserver reload 3>/dev/null || true - fi - fi - # Disable configuration with Apache 2.4 if [ -e /usr/share/apache2/apache2-maintscript-helper ] ; then . /usr/share/apache2/apache2-maintscript-helper diff -Nru munin-2.0.37/debian/munin.README.Debian munin-2.0.47/debian/munin.README.Debian --- munin-2.0.37/debian/munin.README.Debian 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/munin.README.Debian 2019-03-01 00:01:24.000000000 +0000 @@ -11,21 +11,54 @@ On the master system point your browser to http://localhost/munin - to customize edit /etc/munin/apache.conf if you are using apache2. - On the nodes, /etc/munin/munin-node.conf needs to be edited to allow - access from the master node. - - Plugins reside in /usr/share/munin/plugins/, their usage is activated - by linking them to /etc/munin/plugins/. Plugin configuration is best - done in /etc/munin/plugin-conf.d/ + On the nodes, /etc/munin/munin-node.conf needs to be edited to allow + access from the master node. Restart munin-node after any configuration + change. + + Plugins reside in /usr/share/munin/plugins/, their usage is activated + by linking them to /etc/munin/plugins/ (restart munin-node afterwards). + Plugin configuration is best done in /etc/munin/plugin-conf.d/ Further reading: http://guide.munin-monitoring.org/ + + Allow non-local access to web interface + --------------------------------------- + + By default access to the munin web interface is restricted to + local requests. + If you need to access the web interface remotely, you should replace + all occurrences of "Require local" with "Require all granted" in + /etc/apache2/conf-enabled/munin.conf and restart apache2. + + + Performance considerations: generate visualization on-demand or via cron + ------------------------------------------------------------------------ + + By default munin generates its HTML output and its graphs periodically + (via cron). This is suitable for small installations. + + If performance is an issue (e.g. if one master is collecting data from + dozens or hundreds of nodes), the visualization can also be configured + to be generated on demand. + The following steps are required for this change: + * set "html_strategy" and/or "graph_strategy" to "cgi" + (see /etc/munin/munin.conf and /etc/munin/munin-conf.d/) + * adjust the apache configuration for munin + (see the end of /etc/apache2/conf-enabled/munin.conf) + * enable one of the CGI handlers for apache: + * cgi: "a2enmod cgid" + * fcgid: "apt install libapache2-mod-fcgid && a2enmod fcgid" + * restart apache2 and visit http://localhost/munin/ + + Find the upstream source ------------------------ + This Debian package uses the upstream tarball located here: - http://sourceforge.net/projects/munin/ . + http://downloads.munin-monitoring.org/ - It also uses quilt to apply some debian specific patches located in + It also uses quilt to apply some debian specific patches located in ./debian/patches/ @@ -35,10 +68,10 @@ We've got a mailing list. You'll find subscription information at . All feedback are welcome. - + If you feel like sending us things that can't be represented in binary (for example beautiful people fluent in assembly, bacillus anthracis, cash, explosives, and so on), take contact off-list, and we'll find a way of arranging the logistics. - + Enjoy! :-) diff -Nru munin-2.0.37/debian/ostype_helper munin-2.0.47/debian/ostype_helper --- munin-2.0.37/debian/ostype_helper 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/ostype_helper 2019-03-01 00:01:25.000000000 +0000 @@ -1,14 +1,15 @@ #! /bin/sh # Helper shell to give the OSTYPE +set -eu + UNAME=$(uname) -if [ "$UNAME" = "Linux" ]; -then +if [ "$UNAME" = "Linux" ]; then echo linux -fi - -if [ "$UNAME" = "GNU/kFreeBSD" ]; -then +elif [ "$UNAME" = "GNU/kFreeBSD" ]; then echo freebsd +else + echo >&2 "Failed to determine OSTYPE based on 'uname': $UNAME" + exit 1 fi diff -Nru munin-2.0.37/debian/patches/0001-Pass-I.-to-Build-so-that-it-will-work-without-.-in-I.patch munin-2.0.47/debian/patches/0001-Pass-I.-to-Build-so-that-it-will-work-without-.-in-I.patch --- munin-2.0.37/debian/patches/0001-Pass-I.-to-Build-so-that-it-will-work-without-.-in-I.patch 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/patches/0001-Pass-I.-to-Build-so-that-it-will-work-without-.-in-I.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -From 8fde7928f0d883adf8f27b0958d0e452a0bd57a1 Mon Sep 17 00:00:00 2001 -From: Dominic Hargreaves -Date: Tue, 23 Aug 2016 13:07:24 +0100 -Subject: [PATCH] Pass -I. to Build.PL so that it will work without '.' in @INC - ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -Index: munin/Makefile -=================================================================== ---- munin.orig/Makefile -+++ munin/Makefile -@@ -449,7 +449,7 @@ t/install: - - # This builds */Build from Build.PL - %/Build: %/Build.PL -- cd $* && $(PERL) Build.PL -+ cd $* && $(PERL) -I. Build.PL - - build-%: %/Build - cd $* && $(PERL) Build diff -Nru munin-2.0.37/debian/patches/series munin-2.0.47/debian/patches/series --- munin-2.0.37/debian/patches/series 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -0001-Pass-I.-to-Build-so-that-it-will-work-without-.-in-I.patch diff -Nru munin-2.0.37/debian/plugins.conf munin-2.0.47/debian/plugins.conf --- munin-2.0.37/debian/plugins.conf 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/plugins.conf 2019-03-01 00:01:25.000000000 +0000 @@ -73,7 +73,7 @@ [mysql*] user root env.mysqlopts --defaults-file=/etc/mysql/debian.cnf -env.mysqluser debian-sys-maint +env.mysqluser root env.mysqlconnection DBI:mysql:mysql;mysql_read_default_file=/etc/mysql/debian.cnf [postfix_mailqueue] @@ -100,11 +100,6 @@ env.statuses available away chat xa env.days 1 7 30 -[dhcpd3] -user root -env.leasefile /var/lib/dhcp3/dhcpd.leases -env.configfile /etc/dhcp3/dhcpd.conf - [jmx_*] env.ip 127.0.0.1 env.port 5400 diff -Nru munin-2.0.37/debian/plugins-dhcpd3.conf munin-2.0.47/debian/plugins-dhcpd3.conf --- munin-2.0.37/debian/plugins-dhcpd3.conf 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/debian/plugins-dhcpd3.conf 2019-02-28 14:50:43.000000000 +0000 @@ -0,0 +1,3 @@ +[dhcpd3] +env.configfile /etc/dhcp/dhcpd.conf +env.leasefile /var/lib/dhcp/dhcpd.leases diff -Nru munin-2.0.37/debian/plugins.README munin-2.0.47/debian/plugins.README --- munin-2.0.37/debian/plugins.README 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/debian/plugins.README 2019-02-28 14:50:43.000000000 +0000 @@ -0,0 +1,13 @@ +# Plugin configuration files below /etc/munin/plugins.d/ are processed in +# alphabetical order. The last files processed can override earlier +# configuration directives. +# +# You are advised to add local customization of plugin configurations to a +# separate file ("zzz-FOO") in order to guarantee the expected order of +# processing. +# +# Source: +# http://guide.munin-monitoring.org/en/latest/plugin/use.html#configuring +# +# Please note: this README file is also parsed. Thus please avoid confusing +# yourself and do not add valid configuration directives here. diff -Nru munin-2.0.37/debian/plugins-spamstats.conf munin-2.0.47/debian/plugins-spamstats.conf --- munin-2.0.37/debian/plugins-spamstats.conf 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/debian/plugins-spamstats.conf 2019-02-28 14:50:43.000000000 +0000 @@ -0,0 +1,3 @@ +[spamstats] +group adm +env.logfile mail.log diff -Nru munin-2.0.37/debian/README.PluginConfiguration munin-2.0.47/debian/README.PluginConfiguration --- munin-2.0.37/debian/README.PluginConfiguration 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/README.PluginConfiguration 2019-03-01 00:01:24.000000000 +0000 @@ -5,9 +5,12 @@ /etc/munin/plugin-conf.d/. Since files in this directory may contain passwords or other sensitive information, the directory is not world readable. -A plugin configuration file contain one or more sections. Each section starts +Configuration files are read only once during the startup of "munin-node". +Thus a restart of this service is necessary for changes to take effect. + +A plugin configuration file contains one or more sections. Each section starts with a label (between '[' and ']'), and contains an optional "user" statement, -an optional "grop" statement, and zero or more lines beginning with "env.": +an optional "group" statement, and zero or more lines beginning with "env.": Example: @@ -54,5 +57,6 @@ To check if plugin configuration is applied, run munin-run with "-d" to enable debugging, as root, (like "sudo munin-run -d someplugin") and check the output. -If you do not run the plugin as root, you may not be able to read the plugin -configuration files, and debugging your plugins may be harder than necessary +If you do not execute "munin-run" as root, you may not be able to read the +plugin configuration files, and debugging your plugins may be harder than +necessary. diff -Nru munin-2.0.37/debian/README.source munin-2.0.47/debian/README.source --- munin-2.0.37/debian/README.source 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/README.source 2019-03-01 00:01:24.000000000 +0000 @@ -40,7 +40,7 @@ branch is one (hopefully small) file containing the differences between a tarball and a release tag. -If we have relases in «experimental», a pair of branches is used for +If we have releases in «experimental», a pair of branches is used for that: * debian-experimental - packaging branch for experimental releases. diff -Nru munin-2.0.37/debian/rules munin-2.0.47/debian/rules --- munin-2.0.37/debian/rules 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/rules 2019-03-01 00:01:24.000000000 +0000 @@ -1,6 +1,11 @@ #! /usr/bin/make -f +# for DEB_VERSION_UPSTREAM +include /usr/share/dpkg/pkg-info.mk + export DH_VERBOSE=1 +# Build.PL relies on the munin modules to be found locally +export PERL5LIB=. MAKEOPTS = CONFIG=debian/Makefile.config INSTALL_PLUGINS="auto manual snmpauto contrib" @@ -8,12 +13,11 @@ # --no-parallel was introduced with debhelper compat level 10 # (else it would fail to build) - this will probably also # "fix" #839233 - dh $@ --with systemd --no-parallel + dh $@ --no-parallel override_dh_auto_build: # ./getversion reads RELEASE if it exists - dpkg-parsechangelog | sed -n 's/^Version: //p' > RELEASE - chmod 755 debian/ostype_helper + echo "$(DEB_VERSION_UPSTREAM)" >RELEASE dh_auto_build -- $(MAKEOPTS) override_dh_auto_install: @@ -33,10 +37,17 @@ $(MAKE) install-node-prime $(MAKEOPTS) \ MANDIR=$(CURDIR)/debian/munin-doc/usr/share/man \ DESTDIR=$(CURDIR)/debian/munin-node - - # workaround bug in upstream Makefile - mkdir -p $(CURDIR)/debian/munin-async/var/lib - mv $(CURDIR)/debian/munin-node/var/lib/munin-async $(CURDIR)/debian/munin-async/var/lib/munin-async + # Do not install the program manpages in the munin-doc tree + # Instead: remove them here and rely on dh_installman. + # We cannot split the MANDIR target for manpages and module documentation. Thus the + # separation has to be done manually. + rm -f debian/munin-doc/usr/share/man/man1/munin-node.1p \ + debian/munin-doc/usr/share/man/man1/munin-node-configure.1p \ + debian/munin-doc/usr/share/man/man1/munin-run.1p \ + debian/munin-doc/usr/share/man/man1/munindoc.1p + rmdir debian/munin-doc/usr/share/man/man1 + # we do not expect other manpages in munin-doc (except for perl module documentation) + [ -z "$(shell find debian/munin-doc/usr/share/man/ -type f | grep -v 'man3/')" ] $(MAKE) install-plugins-prime $(MAKEOPTS) \ MANDIR=$(CURDIR)/debian/munin-doc/usr/share/man \ @@ -46,10 +57,6 @@ MANDIR=$(CURDIR)/debian/munin-doc/usr/share/man \ DESTDIR=$(CURDIR)/debian/munin-plugins-java - # Install apache configuration - install -D -m0644 debian/munin.apache.conf \ - $(CURDIR)/debian/munin/etc/munin/apache.conf - # Install apache 2.4 configuration install -D -m0644 debian/munin.apache24.conf \ $(CURDIR)/debian/munin/etc/munin/apache24.conf @@ -58,12 +65,12 @@ # in the default apache2/conf.d/munin configuration rm -v $(CURDIR)/debian/munin/var/cache/munin/www/.htaccess - # Remove bundled VeraMono.ttf, debian gets this font from + # Remove bundled VeraMono.ttf, debian gets this font from # the fonts-dejavu-core package. http://bugs.debian.org/548508 rm -v $(CURDIR)/debian/munin/usr/share/munin/DejaVuSans*.ttf # Munin::Plugins & plugins.sh go into munin-common. - # They are used for munin-plugins-* and we don't want a whole + # They are used for munin-plugins-* and we don't want a whole # dedicated new package (munin-plugins-common) for that. yet. for file in usr/share/perl5/Munin/Plugin.pm usr/share/munin/plugins/plugin.sh; do \ mkdir -p $(CURDIR)/debian/munin-common/$$(dirname $$file) ;\ @@ -74,6 +81,12 @@ # Install debian provided plugin configuration install -D -m0644 debian/plugins.conf \ $(CURDIR)/debian/munin-node/etc/munin/plugin-conf.d/munin-node + install -D -m0644 debian/plugins.README \ + $(CURDIR)/debian/munin-node/etc/munin/plugin-conf.d/README + install -D -m0644 debian/plugins-spamstats.conf \ + $(CURDIR)/debian/munin-plugins-extra/etc/munin/plugin-conf.d/spamstats + install -D -m0644 debian/plugins-dhcpd3.conf \ + $(CURDIR)/debian/munin-plugins-extra/etc/munin/plugin-conf.d/dhcpd3 # Move plugins not marked "auto" "manual" or "snmpauto" to the # "munin-plugins-extra" package. @@ -85,14 +98,31 @@ fi; \ done + # The upstream Makefile creates /var/lib/munin-async (also known as "SPOOLDIR") during + # "make install-pre" (referenced by "install-master-prime" and "install-node-prime"). + # This directory is used by the package "munin-async" as the home directory for the + # "munin-async" user. Thus it should not really exist before the installation of that + # package. Otherwise a warning is emitted when the user is created. + # But since "munin-sched" (being part of the "munin-node" package) requires the SPOOLDIR to + # exist, this directory needs to be shipped with "munin-node". Since "munin-async" depends + # on "munin-node", the above warning caused by munin-async's postinst script is inevitable + # under the current circumstances. + # TODO: "munin-sched" was removed by upstream. Maybe the above complexity can be reduced. + # Thus we can remove the directory from the package "munin", but we need to continue + # shipping it as part of "munin-node" in order to ensure that "munin-sched" works. + # The warning "directory already exists" in munin-async's postinst script is annoying, but + # can be safely ignored. + # Hint: munin-sched's use-case is quite exotic and the program is removed for munin 3.0. + # Thus there does not seem to be real need to fix this mess. + rmdir $(CURDIR)/debian/munin/var/lib/munin-async + rmdir $(CURDIR)/debian/munin/var/run/munin + rmdir $(CURDIR)/debian/munin/var/run rmdir $(CURDIR)/debian/munin-node/var/run/munin + rmdir $(CURDIR)/debian/munin-node/var/run # "make clean" is being clever. Work around that. ;) override_dh_auto_clean: dh_auto_clean -- $(MAKEOPTS) clean-node clean-master clean-plugins clean-common clean find plugins/javalib -name '*.class' -print0 | xargs -0 -r rm -v rm RELEASE -f - -# Disable build tests for now -override_dh_auto_test: diff -Nru munin-2.0.37/debian/tests/01.munin-node.t munin-2.0.47/debian/tests/01.munin-node.t --- munin-2.0.37/debian/tests/01.munin-node.t 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/tests/01.munin-node.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -#!/bin/sh - -test_description="munin-node service" - -. ./sharness.sh - -test_expect_success "status (should be started by default)" " - service munin-node status -" - -test_expect_success "restart" " - service munin-node restart -" - -test_expect_success "status (after restart)" " - service munin-node status -" - -test_expect_success "stop" " - service munin-node stop -" - -test_expect_success "status (after stop)" " - test_expect_code 3 service munin-node status -" - -test_expect_success "start" " - service munin-node start -" - -test_expect_success "status (after start)" " - service munin-node status -" - -check_port() { - while ! nc -z localhost 4949; do - a=$(expr $a + 1) - if [ $a = 10 ]; then - return 1 - fi - sleep 1; - done -} - -test_expect_success "munin node port listening" " - check_port -" - -test_done diff -Nru munin-2.0.37/debian/tests/02.munin-cron.t munin-2.0.47/debian/tests/02.munin-cron.t --- munin-2.0.37/debian/tests/02.munin-cron.t 2018-05-11 06:49:23.000000000 +0000 +++ munin-2.0.47/debian/tests/02.munin-cron.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -#!/bin/sh - -test_description="munin run (cron strategy)" - -. ./sharness.sh - -setup() { - temp_conf_file=$(mktemp /etc/munin/munin-conf.d/autopkgtest.XXXXXXXX.conf) - chmod 0644 $temp_conf_file - trap "rm $temp_conf_file" EXIT - - cat >> $temp_conf_file <"$temp_conf_file" </dev/null + echo "Rebooting into SysV init..." + /tmp/autopkgtest-reboot into-sysv +fi diff -Nru munin-2.0.37/debian/tests/master-systemd-cgi munin-2.0.47/debian/tests/master-systemd-cgi --- munin-2.0.37/debian/tests/master-systemd-cgi 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/debian/tests/master-systemd-cgi 2019-02-28 14:50:43.000000000 +0000 @@ -0,0 +1,5 @@ +#!/bin/sh + +. debian/tests/enable_cgi_strategy.inc + +verbose=t prove -v debian/tests/munin-master/*.t diff -Nru munin-2.0.37/debian/tests/master-systemd-cron munin-2.0.47/debian/tests/master-systemd-cron --- munin-2.0.37/debian/tests/master-systemd-cron 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/debian/tests/master-systemd-cron 2019-02-28 14:50:43.000000000 +0000 @@ -0,0 +1,3 @@ +#!/bin/sh + +verbose=t prove -v debian/tests/munin-master/*.t diff -Nru munin-2.0.37/debian/tests/master-sysvinit-cgi munin-2.0.47/debian/tests/master-sysvinit-cgi --- munin-2.0.37/debian/tests/master-sysvinit-cgi 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/debian/tests/master-sysvinit-cgi 2019-02-28 14:50:43.000000000 +0000 @@ -0,0 +1,6 @@ +#!/bin/sh + +. debian/tests/enable_sysvinit.inc +. debian/tests/enable_cgi_strategy.inc + +verbose=t prove -v debian/tests/munin-master/*.t diff -Nru munin-2.0.37/debian/tests/master-sysvinit-cron munin-2.0.47/debian/tests/master-sysvinit-cron --- munin-2.0.37/debian/tests/master-sysvinit-cron 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/debian/tests/master-sysvinit-cron 2019-02-28 14:50:43.000000000 +0000 @@ -0,0 +1,5 @@ +#!/bin/sh + +. debian/tests/enable_sysvinit.inc + +verbose=t prove -v debian/tests/munin-master/*.t File /tmp/tmpiLtDuq/GVNcpuqza8/munin-2.0.37/debian/tests/munin-master is a regular file while file /tmp/tmpiLtDuq/_GgDgKr0d8/munin-2.0.47/debian/tests/munin-master is a directory diff -Nru munin-2.0.37/debian/tests/munin-node/01.service.t munin-2.0.47/debian/tests/munin-node/01.service.t --- munin-2.0.37/debian/tests/munin-node/01.service.t 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/debian/tests/munin-node/01.service.t 2019-02-28 14:50:43.000000000 +0000 @@ -0,0 +1,43 @@ +#!/bin/sh +# +# verify that munin-node can be started and stopped +# + +test_description="munin-node service" + +. /usr/share/sharness/sharness.sh + + +test_expect_success "status (should be started by default)" ' + service munin-node status +' + +test_expect_success "restart" ' + service munin-node restart +' + +test_expect_success "status (after restart)" ' + service munin-node status +' + +test_expect_success "stop" ' + service munin-node stop +' + +test_expect_success "status (after stop)" ' + test_expect_code 3 service munin-node status +' + +test_expect_success "start" ' + service munin-node start +' + +test_expect_success "status (after start)" ' + service munin-node status +' + +test_expect_success "munin node port listening" ' + echo quit | nc localhost 4949 +' + +test_done diff -Nru munin-2.0.37/debian/tests/munin-node/02.plugins.t munin-2.0.47/debian/tests/munin-node/02.plugins.t --- munin-2.0.37/debian/tests/munin-node/02.plugins.t 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/debian/tests/munin-node/02.plugins.t 2019-02-28 14:50:43.000000000 +0000 @@ -0,0 +1,77 @@ +#!/bin/sh +# +# verify that plugins are installed and published by munin-node +# + +test_description="munin-node plugins" + +. /usr/share/sharness/sharness.sh + + +test_expect_success "request list of configured plugins" ' + # Retrieve all plugins (a single line with space separated names) and split it into multiple + # lines, each containing one plugin name. + printf "%s\\n" list quit | nc localhost munin | grep -v "^#" | xargs -n 1 echo | sort >all_plugins + # ignore non-predictable names (e.g. related to the network interfaces of the environment) + grep -v "^if_" all_plugins | sort >all_without_network_interfaces + { + # most plugins work without requirements - we can assume they are available + cat </dev/null || true)" ]; then + echo acpi + fi + if [ -e "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state" ] || [ -e "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" ]; then + echo cpuspeed + fi + if [ -x /usr/sbin/conntrack ] || [ -e /proc/net/nf_conntrack ] || [ -e /proc/net/ip_conntrack ]; then + echo fw_conntrack + echo fw_forwarded_local + fi + } | sort >expected_plugins + test_cmp expected_plugins all_without_network_interfaces +' + +test_expect_success "plugins are executed as 'nobody' by default" ' + cat >/etc/munin/plugins/test-id <&1 || true +EOF + chmod +x /etc/munin/plugins/test-id + service munin-node restart + # give munin-node time to get ready for answering requests + sleep 5 + printf "%s\\n" "fetch test-id" quit | nc localhost munin | grep -v "^#" >real_id_output + cat >expected_id_output </dev/null 2>&1 && - tput setaf 1 >/dev/null 2>&1 && - tput sgr0 >/dev/null 2>&1 - ) && - color=t - -while test "$#" -ne 0; do - case "$1" in - -d|--d|--de|--deb|--debu|--debug) - debug=t; shift ;; - -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate) - immediate=t; shift ;; - -l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests) - TEST_LONG=t; export TEST_LONG; shift ;; - -h|--h|--he|--hel|--help) - help=t; shift ;; - -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose) - verbose=t; shift ;; - -q|--q|--qu|--qui|--quie|--quiet) - # Ignore --quiet under a TAP::Harness. Saying how many tests - # passed without the ok/not ok details is always an error. - test -z "$HARNESS_ACTIVE" && quiet=t; shift ;; - --no-color) - color=; shift ;; - --root=*) - root=$(expr "z$1" : 'z[^=]*=\(.*\)') - shift ;; - *) - echo "error: unknown test option '$1'" >&2; exit 1 ;; - esac -done - -if test -n "$color"; then - say_color() { - ( - TERM=$ORIGINAL_TERM - export TERM - case "$1" in - error) - tput bold; tput setaf 1;; # bold red - skip) - tput setaf 4;; # blue - warn) - tput setaf 3;; # brown/yellow - pass) - tput setaf 2;; # green - info) - tput setaf 6;; # cyan - *) - test -n "$quiet" && return;; - esac - shift - printf "%s" "$*" - tput sgr0 - echo - ) - } -else - say_color() { - test -z "$1" && test -n "$quiet" && return - shift - printf "%s\n" "$*" - } -fi - -error() { - say_color error "error: $*" - EXIT_OK=t - exit 1 -} - -say() { - say_color info "$*" -} - -test -n "$test_description" || error "Test script did not set test_description." - -if test "$help" = "t"; then - echo "$test_description" - exit 0 -fi - -exec 5>&1 -exec 6<&0 -if test "$verbose" = "t"; then - exec 4>&2 3>&1 -else - exec 4>/dev/null 3>/dev/null -fi - -test_failure=0 -test_count=0 -test_fixed=0 -test_broken=0 -test_success=0 - -die() { - code=$? - if test -n "$EXIT_OK"; then - exit $code - else - echo >&5 "FATAL: Unexpected exit with code $code" - exit 1 - fi -} - -EXIT_OK= -trap 'die' EXIT - -# Public: Define that a test prerequisite is available. -# -# The prerequisite can later be checked explicitly using test_have_prereq or -# implicitly by specifying the prerequisite name in calls to test_expect_success -# or test_expect_failure. -# -# $1 - Name of prerequiste (a simple word, in all capital letters by convention) -# -# Examples -# -# # Set PYTHON prerequisite if interpreter is available. -# command -v python >/dev/null && test_set_prereq PYTHON -# -# # Set prerequisite depending on some variable. -# test -z "$NO_GETTEXT" && test_set_prereq GETTEXT -# -# Returns nothing. -test_set_prereq() { - satisfied_prereq="$satisfied_prereq$1 " -} -satisfied_prereq=" " - -# Public: Check if one or more test prerequisites are defined. -# -# The prerequisites must have previously been set with test_set_prereq. -# The most common use of this is to skip all the tests if some essential -# prerequisite is missing. -# -# $1 - Comma-separated list of test prerequisites. -# -# Examples -# -# # Skip all remaining tests if prerequisite is not set. -# if ! test_have_prereq PERL; then -# skip_all='skipping perl interface tests, perl not available' -# test_done -# fi -# -# Returns 0 if all prerequisites are defined or 1 otherwise. -test_have_prereq() { - # prerequisites can be concatenated with ',' - save_IFS=$IFS - IFS=, - set -- $* - IFS=$save_IFS - - total_prereq=0 - ok_prereq=0 - missing_prereq= - - for prerequisite; do - case "$prerequisite" in - !*) - negative_prereq=t - prerequisite=${prerequisite#!} - ;; - *) - negative_prereq= - esac - - total_prereq=$(($total_prereq + 1)) - case "$satisfied_prereq" in - *" $prerequisite "*) - satisfied_this_prereq=t - ;; - *) - satisfied_this_prereq= - esac - - case "$satisfied_this_prereq,$negative_prereq" in - t,|,t) - ok_prereq=$(($ok_prereq + 1)) - ;; - *) - # Keep a list of missing prerequisites; restore - # the negative marker if necessary. - prerequisite=${negative_prereq:+!}$prerequisite - if test -z "$missing_prereq"; then - missing_prereq=$prerequisite - else - missing_prereq="$prerequisite,$missing_prereq" - fi - esac - done - - test $total_prereq = $ok_prereq -} - -# You are not expected to call test_ok_ and test_failure_ directly, use -# the text_expect_* functions instead. - -test_ok_() { - test_success=$(($test_success + 1)) - say_color "" "ok $test_count - $@" -} - -test_failure_() { - test_failure=$(($test_failure + 1)) - say_color error "not ok $test_count - $1" - shift - echo "$@" | sed -e 's/^/# /' - test "$immediate" = "" || { EXIT_OK=t; exit 1; } -} - -test_known_broken_ok_() { - test_fixed=$(($test_fixed + 1)) - say_color error "ok $test_count - $@ # TODO known breakage vanished" -} - -test_known_broken_failure_() { - test_broken=$(($test_broken + 1)) - say_color warn "not ok $test_count - $@ # TODO known breakage" -} - -# Public: Execute commands in debug mode. -# -# Takes a single argument and evaluates it only when the test script is started -# with --debug. This is primarily meant for use during the development of test -# scripts. -# -# $1 - Commands to be executed. -# -# Examples -# -# test_debug "cat some_log_file" -# -# Returns the exit code of the last command executed in debug mode or 0 -# otherwise. -test_debug() { - test "$debug" = "" || eval "$1" -} - -test_eval_() { - # This is a separate function because some tests use - # "return" to end a test_expect_success block early. - eval &3 2>&4 "$*" -} - -test_run_() { - test_cleanup=: - expecting_failure=$2 - test_eval_ "$1" - eval_ret=$? - - if test -z "$immediate" || test $eval_ret = 0 || test -n "$expecting_failure"; then - test_eval_ "$test_cleanup" - fi - if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then - echo "" - fi - return "$eval_ret" -} - -test_skip_() { - test_count=$(($test_count + 1)) - to_skip= - for skp in $SKIP_TESTS; do - case $this_test.$test_count in - $skp) - to_skip=t - break - esac - done - if test -z "$to_skip" && test -n "$test_prereq" && ! test_have_prereq "$test_prereq"; then - to_skip=t - fi - case "$to_skip" in - t) - of_prereq= - if test "$missing_prereq" != "$test_prereq"; then - of_prereq=" of $test_prereq" - fi - - say_color skip >&3 "skipping test: $@" - say_color skip "ok $test_count # skip $1 (missing $missing_prereq${of_prereq})" - : true - ;; - *) - false - ;; - esac -} - -# Public: Run test commands and expect them to succeed. -# -# When the test passed, an "ok" message is printed and the number of successful -# tests is incremented. When it failed, a "not ok" message is printed and the -# number of failed tests is incremented. -# -# With --immediate, exit test immediately upon the first failed test. -# -# Usually takes two arguments: -# $1 - Test description -# $2 - Commands to be executed. -# -# With three arguments, the first will be taken to be a prerequisite: -# $1 - Comma-separated list of test prerequisites. The test will be skipped if -# not all of the given prerequisites are set. To negate a prerequisite, -# put a "!" in front of it. -# $2 - Test description -# $3 - Commands to be executed. -# -# Examples -# -# test_expect_success \ -# 'git-write-tree should be able to write an empty tree.' \ -# 'tree=$(git-write-tree)' -# -# # Test depending on one prerequisite. -# test_expect_success TTY 'git --paginate rev-list uses a pager' \ -# ' ... ' -# -# # Multiple prerequisites are separated by a comma. -# test_expect_success PERL,PYTHON 'yo dawg' \ -# ' test $(perl -E 'print eval "1 +" . qx[python -c "print 2"]') == "4" ' -# -# Returns nothing. -test_expect_success() { - test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq= - test "$#" = 2 || error "bug in the test script: not 2 or 3 parameters to test_expect_success" - export test_prereq - if ! test_skip_ "$@"; then - say >&3 "expecting success: $2" - if test_run_ "$2"; then - test_ok_ "$1" - else - test_failure_ "$@" - fi - fi - echo >&3 "" -} - -# Public: Run test commands and expect them to fail. Used to demonstrate a known -# breakage. -# -# This is NOT the opposite of test_expect_success, but rather used to mark a -# test that demonstrates a known breakage. -# -# When the test passed, an "ok" message is printed and the number of fixed tests -# is incremented. When it failed, a "not ok" message is printed and the number -# of tests still broken is incremented. -# -# Failures from these tests won't cause --immediate to stop. -# -# Usually takes two arguments: -# $1 - Test description -# $2 - Commands to be executed. -# -# With three arguments, the first will be taken to be a prerequisite: -# $1 - Comma-separated list of test prerequisites. The test will be skipped if -# not all of the given prerequisites are set. To negate a prerequisite, -# put a "!" in front of it. -# $2 - Test description -# $3 - Commands to be executed. -# -# Returns nothing. -test_expect_failure() { - test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq= - test "$#" = 2 || error "bug in the test script: not 2 or 3 parameters to test_expect_failure" - export test_prereq - if ! test_skip_ "$@"; then - say >&3 "checking known breakage: $2" - if test_run_ "$2" expecting_failure; then - test_known_broken_ok_ "$1" - else - test_known_broken_failure_ "$1" - fi - fi - echo >&3 "" -} - -# Public: Run command and ensure that it fails in a controlled way. -# -# Use it instead of "! ". For example, when dies due to a -# segfault, test_must_fail diagnoses it as an error, while "! " would -# mistakenly be treated as just another expected failure. -# -# This is one of the prefix functions to be used inside test_expect_success or -# test_expect_failure. -# -# $1.. - Command to be executed. -# -# Examples -# -# test_expect_success 'complain and die' ' -# do something && -# do something else && -# test_must_fail git checkout ../outerspace -# ' -# -# Returns 1 if the command succeeded (exit code 0). -# Returns 1 if the command died by signal (exit codes 130-192) -# Returns 1 if the command could not be found (exit code 127). -# Returns 0 otherwise. -test_must_fail() { - "$@" - exit_code=$? - if test $exit_code = 0; then - echo >&2 "test_must_fail: command succeeded: $*" - return 1 - elif test $exit_code -gt 129 -a $exit_code -le 192; then - echo >&2 "test_must_fail: died by signal: $*" - return 1 - elif test $exit_code = 127; then - echo >&2 "test_must_fail: command not found: $*" - return 1 - fi - return 0 -} - -# Public: Run command and ensure that it succeeds or fails in a controlled way. -# -# Similar to test_must_fail, but tolerates success too. Use it instead of -# " || :" to catch failures caused by a segfault, for instance. -# -# This is one of the prefix functions to be used inside test_expect_success or -# test_expect_failure. -# -# $1.. - Command to be executed. -# -# Examples -# -# test_expect_success 'some command works without configuration' ' -# test_might_fail git config --unset all.configuration && -# do something -# ' -# -# Returns 1 if the command died by signal (exit codes 130-192) -# Returns 1 if the command could not be found (exit code 127). -# Returns 0 otherwise. -test_might_fail() { - "$@" - exit_code=$? - if test $exit_code -gt 129 -a $exit_code -le 192; then - echo >&2 "test_might_fail: died by signal: $*" - return 1 - elif test $exit_code = 127; then - echo >&2 "test_might_fail: command not found: $*" - return 1 - fi - return 0 -} - -# Public: Run command and ensure it exits with a given exit code. -# -# This is one of the prefix functions to be used inside test_expect_success or -# test_expect_failure. -# -# $1 - Expected exit code. -# $2.. - Command to be executed. -# -# Examples -# -# test_expect_success 'Merge with d/f conflicts' ' -# test_expect_code 1 git merge "merge msg" B master -# ' -# -# Returns 0 if the expected exit code is returned or 1 otherwise. -test_expect_code() { - want_code=$1 - shift - "$@" - exit_code=$? - if test $exit_code = $want_code; then - return 0 - fi - - echo >&2 "test_expect_code: command exited with $exit_code, we wanted $want_code $*" - return 1 -} - -# Public: Compare two files to see if expected output matches actual output. -# -# The TEST_CMP variable defines the command used for the comparision; it -# defaults to "diff -u". Only when the test script was started with --verbose, -# will the command's output, the diff, be printed to the standard output. -# -# This is one of the prefix functions to be used inside test_expect_success or -# test_expect_failure. -# -# $1 - Path to file with expected output. -# $2 - Path to file with actual output. -# -# Examples -# -# test_expect_success 'foo works' ' -# echo expected >expected && -# foo >actual && -# test_cmp expected actual -# ' -# -# Returns the exit code of the command set by TEST_CMP. -test_cmp() { - ${TEST_CMP:-diff -u} "$@" -} - -# Public: Schedule cleanup commands to be run unconditionally at the end of a -# test. -# -# If some cleanup command fails, the test will not pass. With --immediate, no -# cleanup is done to help diagnose what went wrong. -# -# This is one of the prefix functions to be used inside test_expect_success or -# test_expect_failure. -# -# $1.. - Commands to prepend to the list of cleanup commands. -# -# Examples -# -# test_expect_success 'test core.capslock' ' -# git config core.capslock true && -# test_when_finished "git config --unset core.capslock" && -# do_something -# ' -# -# Returns the exit code of the last cleanup command executed. -test_when_finished() { - test_cleanup="{ $* - } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup" -} - -# Public: Summarize test results and exit with an appropriate error code. -# -# Must be called at the end of each test script. -# -# Can also be used to stop tests early and skip all remaining tests. For this, -# set skip_all to a string explaining why the tests were skipped before calling -# test_done. -# -# Examples -# -# # Each test script must call test_done at the end. -# test_done -# -# # Skip all remaining tests if prerequisite is not set. -# if ! test_have_prereq PERL; then -# skip_all='skipping perl interface tests, perl not available' -# test_done -# fi -# -# Returns 0 if all tests passed or 1 if there was a failure. -test_done() { - EXIT_OK=t - - if test -z "$HARNESS_ACTIVE"; then - test_results_dir="$SHARNESS_TEST_DIRECTORY/test-results" - mkdir -p "$test_results_dir" - test_results_path="$test_results_dir/${SHARNESS_TEST_FILE%.$SHARNESS_TEST_EXTENSION}.$$.counts" - - cat >>"$test_results_path" <<-EOF - total $test_count - success $test_success - fixed $test_fixed - broken $test_broken - failed $test_failure - - EOF - fi - - if test "$test_fixed" != 0; then - say_color error "# $test_fixed known breakage(s) vanished; please update test(s)" - fi - if test "$test_broken" != 0; then - say_color warn "# still have $test_broken known breakage(s)" - fi - if test "$test_broken" != 0 || test "$test_fixed" != 0; then - test_remaining=$(( $test_count - $test_broken - $test_fixed )) - msg="remaining $test_remaining test(s)" - else - test_remaining=$test_count - msg="$test_count test(s)" - fi - - case "$test_failure" in - 0) - # Maybe print SKIP message - if test -n "$skip_all" && test $test_count -gt 0; then - error "Can't use skip_all after running some tests" - fi - [ -z "$skip_all" ] || skip_all=" # SKIP $skip_all" - - if test $test_remaining -gt 0; then - say_color pass "# passed all $msg" - fi - say "1..$test_count$skip_all" - - test -d "$remove_trash" && - cd "$(dirname "$remove_trash")" && - rm -rf "$(basename "$remove_trash")" - - exit 0 ;; - - *) - say_color error "# failed $test_failure among $msg" - say "1..$test_count" - - exit 1 ;; - - esac -} - -# Public: Root directory containing tests. Tests can override this variable, -# e.g. for testing Sharness itself. -: ${SHARNESS_TEST_DIRECTORY:=$(pwd)} -export SHARNESS_TEST_DIRECTORY - -# Public: Build directory that will be added to PATH. By default, it is set to -# the parent directory of SHARNESS_TEST_DIRECTORY. -: ${SHARNESS_BUILD_DIRECTORY:="$SHARNESS_TEST_DIRECTORY/.."} -PATH="$SHARNESS_BUILD_DIRECTORY:$PATH" -export PATH SHARNESS_BUILD_DIRECTORY - -# Public: Path to test script currently executed. -SHARNESS_TEST_FILE="$0" -export SHARNESS_TEST_FILE - -# Prepare test area. -test_dir="trash directory.$(basename "$SHARNESS_TEST_FILE" ".$SHARNESS_TEST_EXTENSION")" -test -n "$root" && test_dir="$root/$test_dir" -case "$test_dir" in -/*) SHARNESS_TRASH_DIRECTORY="$test_dir" ;; - *) SHARNESS_TRASH_DIRECTORY="$SHARNESS_TEST_DIRECTORY/$test_dir" ;; -esac -test "$debug" = "t" || remove_trash="$SHARNESS_TRASH_DIRECTORY" -rm -rf "$test_dir" || { - EXIT_OK=t - echo >&5 "FATAL: Cannot prepare test area" - exit 1 -} - -# Public: Empty trash directory, the test area, provided for each test. The HOME -# variable is set to that directory too. -export SHARNESS_TRASH_DIRECTORY - -HOME="$SHARNESS_TRASH_DIRECTORY" -export HOME - -mkdir -p "$test_dir" || exit 1 -# Use -P to resolve symlinks in our working directory so that the cwd -# in subprocesses like git equals our $PWD (for pathname comparisons). -cd -P "$test_dir" || exit 1 - -this_test=${SHARNESS_TEST_FILE##*/} -this_test=${this_test%.$SHARNESS_TEST_EXTENSION} -for skp in $SKIP_TESTS; do - case "$this_test" in - $skp) - say_color info >&3 "skipping test $this_test altogether" - skip_all="skip all tests in $this_test" - test_done - esac -done - -# vi: set ts=4 sw=4 noet : diff -Nru munin-2.0.37/debian/upstream/metadata munin-2.0.47/debian/upstream/metadata --- munin-2.0.37/debian/upstream/metadata 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/debian/upstream/metadata 2019-02-28 14:50:43.000000000 +0000 @@ -0,0 +1,10 @@ +Bug-Database: https://github.com/munin-monitoring/munin/issues +Bug-Submit: https://github.com/munin-monitoring/munin/issues/new/choose +Changelog: https://raw.githubusercontent.com/munin-monitoring/munin/stable-2.0/ChangeLog +Contact: irc://irc.oftc.net/ +Documentation: http://guide.munin-monitoring.org/ +FAQ: http://guide.munin-monitoring.org/en/latest/tutorial/troubleshooting.html +Name: Munin +Repository: https://github.com/munin-monitoring/munin.git +Repository-Browse: https://github.com/munin-monitoring/munin +Webservice: http://demo.munin-monitoring.org/ diff -Nru munin-2.0.37/dev_scripts/common.sh munin-2.0.47/dev_scripts/common.sh --- munin-2.0.37/dev_scripts/common.sh 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/dev_scripts/common.sh 2019-02-28 14:43:36.000000000 +0000 @@ -1,9 +1,9 @@ -#!/bin/bash +#!/bin/sh BASEDIR=$(readlink -f -- "$FINDBIN/..") DESTDIR="$BASEDIR/sandbox" -PERLSITELIB=$(perl -V:sitelib | cut -d"'" -f2) +# shellcheck disable=SC2034 +PERLLIB=$DESTDIR$(perl -V:sitelib | cut -d"'" -f2) -cd $BASEDIR - +cd "$BASEDIR" diff -Nru munin-2.0.37/dev_scripts/disable_tls munin-2.0.47/dev_scripts/disable_tls --- munin-2.0.37/dev_scripts/disable_tls 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/dev_scripts/disable_tls 2019-02-28 14:43:36.000000000 +0000 @@ -1,9 +1,7 @@ -#!/bin/bash +#!/bin/sh FINDBIN=$(cd -- "$(dirname "$0")" && pwd) -. $FINDBIN/common.sh +. "$FINDBIN/common.sh" -cd $BASEDIR - -perl -pi -e "s/^tls .*/tls disabled/" $DESTDIR/etc/opt/munin/munin-node.conf -perl -pi -e "s/^tls .*/tls disabled/" $DESTDIR/etc/opt/munin/munin.conf +perl -pi -e "s/^tls .*/tls disabled/" "$DESTDIR/etc/opt/munin/munin-node.conf" +perl -pi -e "s/^tls .*/tls disabled/" "$DESTDIR/etc/opt/munin/munin.conf" diff -Nru munin-2.0.37/dev_scripts/enable_tls munin-2.0.47/dev_scripts/enable_tls --- munin-2.0.37/dev_scripts/enable_tls 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/dev_scripts/enable_tls 2019-02-28 14:43:36.000000000 +0000 @@ -1,9 +1,7 @@ -#!/bin/bash +#!/bin/sh FINDBIN=$(cd -- "$(dirname "$0")" && pwd) -. $FINDBIN/common.sh +. "$FINDBIN/common.sh" -cd $BASEDIR - -perl -pi -e "s/^tls .*/tls paranoid/" $DESTDIR/etc/opt/munin/munin-node.conf -perl -pi -e "s/^tls .*/tls paranoid/" $DESTDIR/etc/opt/munin/munin.conf +perl -pi -e "s/^tls .*/tls paranoid/" "$DESTDIR/etc/opt/munin/munin-node.conf" +perl -pi -e "s/^tls .*/tls paranoid/" "$DESTDIR/etc/opt/munin/munin.conf" diff -Nru munin-2.0.37/dev_scripts/install munin-2.0.47/dev_scripts/install --- munin-2.0.37/dev_scripts/install 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/dev_scripts/install 2019-02-28 14:43:36.000000000 +0000 @@ -1,13 +1,11 @@ -#!/bin/bash +#!/bin/sh FINDBIN=$(cd -- "$(dirname "$0")" && pwd) -. $FINDBIN/common.sh +. "$FINDBIN/common.sh" -cd $BASEDIR -if [ $1 ]; then +if [ $# -ne 0 ]; then ./dev_scripts/stop_munin-node - ./dev_scripts/stop_munin-sched rm -rf sandbox mkdir sandbox @@ -15,17 +13,17 @@ echo "**********************************************************************" fi -make DESTDIR=$DESTDIR HTMLDIR=$DESTDIR/www/munin || exit -fakeroot make install-common-prime install-master-prime install-node-prime install-plugins-prime install-man install-async DESTDIR=$DESTDIR HTMLDIR=$DESTDIR/www/munin || exit +make "DESTDIR=$DESTDIR" "HTMLDIR=$DESTDIR/www/munin" || exit +fakeroot make install-common-prime install-master-prime install-node-prime install-plugins-prime install-man install-async "DESTDIR=$DESTDIR" "HTMLDIR=$DESTDIR/www/munin" || exit -if [ $1 ]; then +if [ $# -ne 0 ]; then echo "**********************************************************************" - fakeroot make install-plugins-prime install-plugins-java DESTDIR=$DESTDIR HTMLDIR=$DESTDIR/www/munin || exit + fakeroot make install-plugins-prime install-plugins-java "DESTDIR=$DESTDIR" "HTMLDIR=$DESTDIR/www/munin" || exit echo "**********************************************************************" perl -pi -e "s/port 4949/port 4948/; - s/user root/user $USER/; - s/group root/group $GROUPS/; + s/user root/user $(id -n -u)/; + s/group root/group $(id -n -g)/; s|^(port .*)|\$1 tls disabled @@ -34,9 +32,9 @@ tls_ca_certificate $BASEDIR/common/t/tls/CA/ca_cert.pem tls_verify_certificate yes tls_verify_depth 5 -|; " $DESTDIR/etc/opt/munin/munin-node.conf +|; " "$DESTDIR/etc/opt/munin/munin-node.conf" - perl -pi -e "s/(address 127\.0\.0\.1)/\$1\n port 4948/; + perl -pi -e "s/(address 127\\.0\\.0\\.1)/\$1\\n port 4948/; s|(# a simple host tree)|tls disabled tls_private_key $BASEDIR/common/t/tls/master_key.pem tls_certificate $BASEDIR/common/t/tls/master_cert.pem @@ -44,9 +42,8 @@ tls_verify_certificate yes tls_verify_depth 5 -\$1|" $DESTDIR/etc/opt/munin/munin.conf +\$1|" "$DESTDIR/etc/opt/munin/munin.conf" echo "**********************************************************************" ./dev_scripts/run munin-node-configure --shell --families=contrib,auto | sh -x fi - diff -Nru munin-2.0.37/dev_scripts/query_munin_node munin-2.0.47/dev_scripts/query_munin_node --- munin-2.0.37/dev_scripts/query_munin_node 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/dev_scripts/query_munin_node 2019-02-28 14:43:36.000000000 +0000 @@ -1,3 +1,3 @@ -#!/bin/bash +#!/bin/sh -echo -e "$*\nquit" | nc localhost 4948 +printf '%s\nquit' "$*" | nc localhost 4948 diff -Nru munin-2.0.37/dev_scripts/restart_munin-node munin-2.0.47/dev_scripts/restart_munin-node --- munin-2.0.37/dev_scripts/restart_munin-node 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/dev_scripts/restart_munin-node 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh ./dev_scripts/stop_munin-node ./dev_scripts/start_munin-node "$@" diff -Nru munin-2.0.37/dev_scripts/restart_munin-sched munin-2.0.47/dev_scripts/restart_munin-sched --- munin-2.0.37/dev_scripts/restart_munin-sched 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/dev_scripts/restart_munin-sched 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -#!/bin/bash - -./dev_scripts/stop_munin-sched -./dev_scripts/start_munin-sched "$@" diff -Nru munin-2.0.37/dev_scripts/run munin-2.0.47/dev_scripts/run --- munin-2.0.37/dev_scripts/run 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/dev_scripts/run 2019-02-28 14:43:36.000000000 +0000 @@ -1,9 +1,7 @@ -#!/bin/bash +#!/bin/sh FINDBIN=$(cd -- "$(dirname "$0")" && pwd) -. $FINDBIN/common.sh - -cd $BASEDIR +. "$FINDBIN/common.sh" usage() { @@ -12,16 +10,16 @@ } -if [ -z "$1" ]; then +if [ $# -eq 0 ]; then usage fi -RUN=$(find $DESTDIR -name $1 -type f -executable) +RUN=$(find "$DESTDIR" -name "$1" -type f -executable) shift if [ -z "$RUN" ]; then usage fi -env PERL5LIB=$DESTDIR$PERLSITELIB $RUN "$@" +env "PERL5LIB=$PERLLIB" "$RUN" "$@" diff -Nru munin-2.0.37/dev_scripts/start_munin-node munin-2.0.47/dev_scripts/start_munin-node --- munin-2.0.37/dev_scripts/start_munin-node 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/dev_scripts/start_munin-node 2019-02-28 14:43:36.000000000 +0000 @@ -1,16 +1,13 @@ #!/bin/bash FINDBIN=$(cd -- "$(dirname "$0")" && pwd) -. $FINDBIN/common.sh +. "$FINDBIN/common.sh" -cd $BASEDIR - -if [ -f $DESTDIR/var/run/munin/munin-node.pid ]; then +if [ -f "$DESTDIR/var/run/munin/munin-node.pid" ]; then echo "Pid file found. Not starting" else - env PERL5LIB=$DESTDIR/$PERLSITELIB $DESTDIR/opt/munin/sbin/munin-node "$@" + env "PERL5LIB=$PERLLIB" "$DESTDIR/opt/munin/sbin/munin-node" "$@" fi -tail -f $DESTDIR/opt/munin/log/munin/munin-node.log - +tail -f "$DESTDIR/opt/munin/log/munin/munin-node.log" diff -Nru munin-2.0.37/dev_scripts/start_munin-sched munin-2.0.47/dev_scripts/start_munin-sched --- munin-2.0.37/dev_scripts/start_munin-sched 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/dev_scripts/start_munin-sched 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -#!/bin/bash - -FINDBIN=$(cd -- "$(dirname "$0")" && pwd) -. $FINDBIN/common.sh - -cd $BASEDIR - - -if [ -f $DESTDIR/var/run/munin/munin-sched.pid ]; then - echo "Pid file found. Not starting" -else - env PERL5LIB=$DESTDIR/$PERLSITELIB $DESTDIR/opt/munin/sbin/munin-sched "$@" -fi - -tail -f $DESTDIR/opt/munin/log/munin/munin-sched.log diff -Nru munin-2.0.37/dev_scripts/stop_munin-node munin-2.0.47/dev_scripts/stop_munin-node --- munin-2.0.37/dev_scripts/stop_munin-node 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/dev_scripts/stop_munin-node 2019-02-28 14:43:36.000000000 +0000 @@ -1,14 +1,11 @@ -#!/bin/bash +#!/bin/sh FINDBIN=$(cd -- "$(dirname "$0")" && pwd) -. $FINDBIN/common.sh +. "$FINDBIN/common.sh" -cd $BASEDIR - -if [ -f $DESTDIR/var/run/munin/munin-node.pid ]; then - cat $DESTDIR/var/run/munin/munin-node.pid | xargs kill +if [ -f "$DESTDIR/var/run/munin/munin-node.pid" ]; then + xargs kill <"$DESTDIR/var/run/munin/munin-node.pid" else echo "Pid file not found. Not stopping" fi - diff -Nru munin-2.0.37/dev_scripts/stop_munin-sched munin-2.0.47/dev_scripts/stop_munin-sched --- munin-2.0.37/dev_scripts/stop_munin-sched 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/dev_scripts/stop_munin-sched 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -#!/bin/bash - -FINDBIN=$(cd -- "$(dirname "$0")" && pwd) -. $FINDBIN/common.sh - -cd $BASEDIR - - -if [ -f $DESTDIR/var/run/munin/munin-sched.pid ]; then - cat $DESTDIR/var/run/munin/munin-sched.pid | xargs kill -else - echo "Pid file not found. Not stopping" -fi diff -Nru munin-2.0.37/.flake8 munin-2.0.47/.flake8 --- munin-2.0.37/.flake8 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/.flake8 2019-02-28 14:43:36.000000000 +0000 @@ -0,0 +1,3 @@ +# settings for the "flake8" (python code style checks) +[flake8] +max-line-length = 99 diff -Nru munin-2.0.37/getversion munin-2.0.47/getversion --- munin-2.0.37/getversion 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/getversion 2019-02-28 14:43:36.000000000 +0000 @@ -6,65 +6,78 @@ # This is in case we're building from a tarball. # # * If we're inside a git tree: -# - For the "master" branch, use "git describe". -# - For "detached" branches (mostly for tag checkouts), also use "git describe". -# - For other branches, use a "$VERSION-$NBCOMMITS-$BRANCH-$DATE-g$COMMIT" -# sortof version. +# - For a current tagged commit, return this tag. +# - For the "master/devel/stable-*" branches, use "git describe". +# - For other branches or detached HEADs, return a +# "$VERSION-$NBCOMMITS-$BRANCH-$DATE-g$COMMIT" version string +# (with "BRANCH=detached" for a detached HEAD) # # * Try to make it up from the directory name (munin-2.0.1 -> 2.0.1) # # * If we're still looking for a version, just fallback to "unknown". +# +# NOTE: please keep this file as portable as possible (more strict than for plugins). +# Probably unexpected portability issues include: +# * '$(...)' is not supported by /bin/sh on Solaris +# +# Override shellcheck warnings due to portability constraints +# shellcheck disable=SC2006 -current_git_branch() { - GB="$(git branch | awk '$1 == "*" {print $2}')" - case $GB in - - # git checkout 402c6d6 - # git branch - # * (detached from 402c6d6) - # devel - # --> This is new with git 1.8+ - "(detached" ) echo "detached";; - - # git checkout 2.0.9 - # git branch - # * (no branch) - # devel - "(no" ) echo;; - * ) echo $GB;; - esac +get_current_git_branch_name() { + # hide stderr (for detached HEADs) + GB=`LANG='' git branch --points-at HEAD 2>/dev/null | awk '$1 == "*" {print $2}'` + if echo "$GB" | grep -q "^("; then + # we are not part of a specific branch (the reason is given in braces) + echo + else + echo "$GB" + fi } + generate_version_string() { - branch="$(current_git_branch)" - case "${branch}" in - ""|master|devel|stable-*) - git describe - ;; - *) - branch=$(echo $branch | sed -e 's/[^0-9A-Za-z\.\-\_]/_/g' ) - # "foo | read VAR" does *not* work - # workaround stolen from http://www.etalabs.net/sh_tricks.html - read VERSION COMMITS HASH </dev/null)" = "true" ]; then +elif [ "`git rev-parse --is-inside-work-tree 2>/dev/null`" = "true" ]; then generate_version_string -elif [ ! -z "$(generate_version_string_from_dir)" ]; then - generate_version_string_from_dir +elif [ -n "`generate_version_string_from_dir`" ]; then + generate_version_string_from_dir else echo "unknown" fi diff -Nru munin-2.0.37/Makefile munin-2.0.47/Makefile --- munin-2.0.37/Makefile 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/Makefile 2019-02-28 14:43:36.000000000 +0000 @@ -4,13 +4,15 @@ # # $Id$ -# Defaults/paths. Allows $(CONFIG) to be overrided by +# Defaults/paths. Allows $(CONFIG) to be overridden by # make command line DEFAULTS = Makefile.config CONFIG = Makefile.config include $(DEFAULTS) -include $(CONFIG) +ifneq ($(DEFAULTS),$(CONFIG)) + include $(CONFIG) +endif ifeq ($(JCVALID),yes) JAVA_BUILD=build-plugins-java @@ -25,17 +27,42 @@ INFILES := $(shell find . -name '*.in' | sed 's/\.\/\(.*\)\.in$$/build\/\1/') INFILES_MASTER := $(shell find master -name '*.in' | sed 's/\(.*\)\.in$$/build\/\1/') CLASSFILES := $(shell find plugins/javalib -name '*.java' | sed 's/\(.*\)\.java$$/build\/\1.class/') -PLUGINS := $(wildcard plugins/node.d.$(OSTYPE)/* plugins/node.d/* $(JAVA_PLUGINS)) +PLUGINS := $(wildcard plugins/node.d.$(OSTYPE)/* plugins/node.d/* $(JAVA_PLUGINS)) MANCENTER := "Munin Documentation" -MAN8 := master/_bin/munin-update master/_bin/munin-limits master/_bin/munin-html master/_bin/munin-graph +MAN8 := master/_bin/munin-update master/_bin/munin-limits master/_bin/munin-html master/_bin/munin-graph PODMAN8 := build/master/doc/munin-cron master/doc/munin master/doc/munin-check PODMAN5 := build/master/doc/munin.conf node/doc/munin-node.conf +PYTHON_LINT_CALL ?= python3 -m flake8 +CONFVAR_SUBSTITUTION_FILES = \ + master/blib/libdoc/Munin\:\:Master\:\:HTMLOld.3pm \ + master/blib/lib/Munin/Master/HTMLOld.pm \ + node/blib/sbin/munin-node-configure \ + node/blib/sbin/munin-node \ + node/blib/sbin/munin-run \ + build/doc/munin-node.conf.5 +MAKEFILES := Makefile $(DEFAULTS) $(CONFIG) + +# TODO: remove this fallback code for "make v3.x" (up to Debian Wheezy / Ubuntu Trusty) as soon as +# the CI supports a more modern distribution +# (see https://docs.travis-ci.com/user/reference/overview/) +# Make v3.x failed to handle colon escaping properly - thus we remove complicated filenames from +# targets and dependencies. This may affect corner cases of dependency handling for the one file +# above containing a colon. But in this case it is just about substituting paths in a +# documentation file - thus we can live with this rare risk of incorrectness. +ifeq ($(firstword $(subst ., ,$(MAKE_VERSION))),3) +# weed out all complicated filenames containing a colon +CONFVAR_SUBSTITUTION_DEP_FILES = $(shell printf '%s\n' $(CONFVAR_SUBSTITUTION_FILES) | grep -v ":") +else +CONFVAR_SUBSTITUTION_DEP_FILES = $(CONFVAR_SUBSTITUTION_FILES) +endif + .PHONY: install install-pre install-master-prime install-node-prime install-node-pre install-common-prime install-doc install-man \ - build build-common-prime build-common-pre build-doc \ - source_dist \ - test clean \ - clean-% test-% build-% install-% \ + build build-common build-common-pre build-doc \ + substitute-build-defaults-inline substitute-confvar-inline \ + source_dist \ + test lint clean \ + clean-% test-% build-% install-% \ tags \ infiles @@ -66,7 +93,7 @@ install: install-master-prime install-common-prime install-node-prime install-plugins-prime $(JAVA_INSTALL) install-man install-async-prime -install-pre: Makefile Makefile.config +install-pre: $(MAKEFILES) @$(CHECKUSER) mkdir -p $(LOGDIR) mkdir -p $(STATEDIR) @@ -126,17 +153,9 @@ # Not ready to be installed yet # $(INSTALL) -m 0755 build/master/_bin/munin-gather $(LIBDIR)/ -# ALWAYS DO THE OS SPECIFIC PLUGINS LAST! THAT WAY THEY OVERWRITE THE -# GENERIC ONES - install-node-plugins: install-plugins-prime -# Some HP-UX plugins needs *.adv support files in LIBDIR -ifneq ($(OSTYPE),hp-ux) -HPUXONLY=true || -endif - -install-plugins-prime: install-plugins build $(PLUGINS) Makefile Makefile.config +install-plugins-prime: install-plugins build $(PLUGINS) $(MAKEFILES) @$(CHECKGROUP) mkdir -p $(CONFDIR)/plugins @@ -148,13 +167,16 @@ $(CHMOD) 0755 $(PLUGSTATE) $(CHMOD) 0755 $(CONFDIR)/plugin-conf.d + @# Process the OS specific plugins at the end. Otherwise they would be overridden by the + @# generic ones. for p in build/plugins/node.d/* build/plugins/node.d.$(OSTYPE)/* ; do \ - if test -f "$$p" ; then \ - echo Installing $$p; \ - $(INSTALL) -m 0755 $$p $(LIBDIR)/plugins/; \ - fi \ + if test -f "$$p"; then \ + echo Installing $$p; \ + $(INSTALL) -m 0755 $$p $(LIBDIR)/plugins/; \ + fi \ done - $(HPUXONLY) mv $(LIBDIR)/plugins/*.adv $(LIBDIR) + @# Some HP-UX plugins need *.adv support files in LIBDIR + if [ "$(OSTYPE)" = "hp-ux" ]; then mv $(LIBDIR)/plugins/*.adv $(LIBDIR); fi $(INSTALL) -m 0644 build/plugins/plugins.history $(LIBDIR)/plugins/ $(INSTALL) -m 0644 build/plugins/plugin.sh $(LIBDIR)/plugins/ @@ -162,11 +184,11 @@ mkdir -p $(JAVALIBDIR) $(INSTALL) -m 0644 build/plugins/javalib/munin-jmx-plugins.jar $(JAVALIBDIR)/ mkdir -p $(LIBDIR)/plugins - for p in build/plugins/node.d.java/*; do \ - if test -f "$$p" ; then \ - echo Installing $$p; \ - $(INSTALL) -m 0755 $$p $(LIBDIR)/plugins/; \ - fi \ + for p in build/plugins/node.d.java/*; do \ + if test -f "$$p"; then \ + echo Installing $$p; \ + $(INSTALL) -m 0755 $$p $(LIBDIR)/plugins/; \ + fi \ done #TODO: @@ -189,7 +211,7 @@ install-common-prime: build-common install-common -install-man: build-man Makefile Makefile.config +install-man: build-man $(MAKEFILES) mkdir -p $(MANDIR)/man1 $(MANDIR)/man5 $(MANDIR)/man8 $(INSTALL) -m 0644 build/doc/munin-node.conf.5 $(MANDIR)/man5/ $(INSTALL) -m 0644 build/doc/munin.conf.5 $(MANDIR)/man5/ @@ -213,141 +235,162 @@ # Dummy rule to enable parallel building infiles: $(INFILES) -build: infiles build-master build-common-prime build-node build-plugins $(JAVA_BUILD) build-man substitute-confvar-inline +build: infiles build-master build-common build-node build-plugins $(JAVA_BUILD) build-man build-confvar-substitution-stamp build/%: %.in @echo "$< -> $@" @mkdir -p build/`dirname $<` - @sed -e 's|@@PREFIX@@|$(PREFIX)|g' \ - -e 's|@@CONFDIR@@|$(CONFDIR)|g' \ - -e 's|@@BINDIR@@|$(BINDIR)|g' \ - -e 's|@@SBINDIR@@|$(SBINDIR)|g' \ - -e 's|@@DOCDIR@@|$(DOCDIR)|g' \ - -e 's|@@LIBDIR@@|$(LIBDIR)|g' \ - -e 's|@@MANDIR@@|$(MANDIR)|g' \ - -e 's|@@LOGDIR@@|$(LOGDIR)|g' \ - -e 's|@@HTMLDIR@@|$(HTMLDIR)|g' \ - -e 's|@@DBDIR@@|$(DBDIR)|g' \ - -e 's|@@STATEDIR@@|$(STATEDIR)|g' \ - -e 's|@@SPOOLDIR@@|$(SPOOLDIR)|g' \ - -e 's|@@PERL@@|$(PERL)|g' \ - -e 's|@@PERLLIB@@|$(PERLLIB)|g' \ - -e 's|@@PYTHON@@|$(PYTHON)|g' \ - -e 's|@@RUBY@@|$(RUBY)|g' \ - -e 's|@@JAVARUN@@|$(JAVARUN)|g' \ - -e 's|@@JAVALIBDIR@@|$(JAVALIBDIR)|g' \ - -e 's|@@OSTYPE@@|$(OSTYPE)|g' \ - -e 's|@@HOSTNAME@@|$(HOSTNAME)|g' \ - -e 's|@@MKTEMP@@|$(MKTEMP)|g' \ - -e 's|@@VERSION@@|$(VERSION)|g' \ - -e 's|@@PLUGSTATE@@|$(PLUGSTATE)|g' \ - -e 's|@@CGIDIR@@|$(CGIDIR)|g' \ - -e 's|@@USER@@|$(USER)|g' \ - -e 's|@@GROUP@@|$(GROUP)|g' \ - -e 's|@@PLUGINUSER@@|$(PLUGINUSER)|g' \ - -e 's|@@GOODSH@@|$(GOODSH)|g' \ - -e 's|@@BASH@@|$(BASH)|g' \ - -e 's|@@HASSETR@@|$(HASSETR)|g' \ - $< > $@; + @sed -e 's|@@PREFIX@@|$(PREFIX)|g' \ + -e 's|@@CONFDIR@@|$(CONFDIR)|g' \ + -e 's|@@BINDIR@@|$(BINDIR)|g' \ + -e 's|@@SBINDIR@@|$(SBINDIR)|g' \ + -e 's|@@DOCDIR@@|$(DOCDIR)|g' \ + -e 's|@@LIBDIR@@|$(LIBDIR)|g' \ + -e 's|@@MANDIR@@|$(MANDIR)|g' \ + -e 's|@@LOGDIR@@|$(LOGDIR)|g' \ + -e 's|@@HTMLDIR@@|$(HTMLDIR)|g' \ + -e 's|@@DBDIR@@|$(DBDIR)|g' \ + -e 's|@@STATEDIR@@|$(STATEDIR)|g' \ + -e 's|@@SPOOLDIR@@|$(SPOOLDIR)|g' \ + -e 's|@@PERL@@|$(PERL)|g' \ + -e 's|@@PERLLIB@@|$(PERLLIB)|g' \ + -e 's|@@PYTHON@@|$(PYTHON)|g' \ + -e 's|@@RUBY@@|$(RUBY)|g' \ + -e 's|@@JAVARUN@@|$(JAVARUN)|g' \ + -e 's|@@JAVALIBDIR@@|$(JAVALIBDIR)|g' \ + -e 's|@@OSTYPE@@|$(OSTYPE)|g' \ + -e 's|@@HOSTNAME@@|$(HOSTNAME)|g' \ + -e 's|@@MKTEMP@@|$(MKTEMP)|g' \ + -e 's|@@VERSION@@|$(VERSION)|g' \ + -e 's|@@PLUGSTATE@@|$(PLUGSTATE)|g' \ + -e 's|@@CGIDIR@@|$(CGIDIR)|g' \ + -e 's|@@CGITMPDIR@@|$(CGITMPDIR)|g' \ + -e 's|@@USER@@|$(USER)|g' \ + -e 's|@@GROUP@@|$(GROUP)|g' \ + -e 's|@@PLUGINUSER@@|$(PLUGINUSER)|g' \ + -e 's|@@GOODSH@@|$(GOODSH)|g' \ + -e 's|@@BASH@@|$(BASH)|g' \ + -e 's|@@HASSETR@@|$(HASSETR)|g' \ + $< > $@; + + +build-confvar-substitution-stamp: $(CONFVAR_SUBSTITUTION_DEP_FILES) + $(MAKE) substitute-confvar-inline + touch build-confvar-substitution-stamp -build-common-prime: build-common-pre common/blib/lib/Munin/Common/Defaults.pm build-common +$(CONFVAR_SUBSTITUTION_DEP_FILES): build-master build-node build-man + substitute-confvar-inline: - @perl -p -i -e 's|\@\@PREFIX\@\@|$(PREFIX)|g;' \ - -e 's|\@\@CONFDIR\@\@|$(CONFDIR)|g;' \ - -e 's|\@\@BINDIR\@\@|$(BINDIR)|g;' \ - -e 's|\@\@SBINDIR\@\@|$(SBINDIR)|g;' \ - -e 's|\@\@DOCDIR\@\@|$(DOCDIR)|g;' \ - -e 's|\@\@LIBDIR\@\@|$(LIBDIR)|g;' \ - -e 's|\@\@MANDIR\@\@|$(MANDIR)|g;' \ - -e 's|\@\@LOGDIR\@\@|$(LOGDIR)|g;' \ - -e 's|\@\@HTMLDIR\@\@|$(HTMLDIR)|g;' \ - -e 's|\@\@DBDIR\@\@|$(DBDIR)|g;' \ - -e 's|\@\@STATEDIR\@\@|$(STATEDIR)|g;' \ - -e 's|\@\@SPOOLDIR\@\@|$(SPOOLDIR)|g;' \ - -e 's|\@\@PERL\@\@|$(PERL)|g;' \ - -e 's|\@\@PERLLIB\@\@|$(PERLLIB)|g;' \ - -e 's|\@\@PYTHON\@\@|$(PYTHON)|g;' \ - -e 's|\@\@RUBY\@\@|$(RUBY)|g;' \ - -e 's|\@\@JAVARUN\@\@|$(JAVARUN)|g;' \ - -e 's|\@\@JAVALIBDIR\@\@|$(JAVALIBDIR)|g;' \ - -e 's|\@\@OSTYPE\@\@|$(OSTYPE)|g;' \ - -e 's|\@\@HOSTNAME\@\@|$(HOSTNAME)|g;' \ - -e 's|\@\@MKTEMP\@\@|$(MKTEMP)|g;' \ - -e 's|\@\@VERSION\@\@|$(VERSION)|g;' \ - -e 's|\@\@PLUGSTATE\@\@|$(PLUGSTATE)|g;' \ - -e 's|\@\@CGIDIR\@\@|$(CGIDIR)|g;' \ - -e 's|\@\@USER\@\@|$(USER)|g;' \ - -e 's|\@\@GROUP\@\@|$(GROUP)|g;' \ - -e 's|\@\@PLUGINUSER\@\@|$(PLUGINUSER)|g;' \ - -e 's|\@\@GOODSH\@\@|$(GOODSH)|g;' \ - -e 's|\@\@BASH\@\@|$(BASH)|g;' \ - -e 's|\@\@HASSETR\@\@|$(HASSETR)|g;' \ - ./master/blib/libdoc/Munin::Master::HTMLOld.3pm \ - ./master/blib/lib/Munin/Master/HTMLOld.pm \ - ./node/blib/sbin/munin-node-configure \ - ./node/blib/sbin/munin-node \ - ./node/blib/sbin/munin-run \ - ./node/blib/sbin/munin-sched \ - ./build/doc/munin-node.conf.5 + perl -p -i -e 's|\@\@PREFIX\@\@|$(PREFIX)|g;' \ + -e 's|\@\@CONFDIR\@\@|$(CONFDIR)|g;' \ + -e 's|\@\@BINDIR\@\@|$(BINDIR)|g;' \ + -e 's|\@\@SBINDIR\@\@|$(SBINDIR)|g;' \ + -e 's|\@\@DOCDIR\@\@|$(DOCDIR)|g;' \ + -e 's|\@\@LIBDIR\@\@|$(LIBDIR)|g;' \ + -e 's|\@\@MANDIR\@\@|$(MANDIR)|g;' \ + -e 's|\@\@LOGDIR\@\@|$(LOGDIR)|g;' \ + -e 's|\@\@HTMLDIR\@\@|$(HTMLDIR)|g;' \ + -e 's|\@\@DBDIR\@\@|$(DBDIR)|g;' \ + -e 's|\@\@STATEDIR\@\@|$(STATEDIR)|g;' \ + -e 's|\@\@SPOOLDIR\@\@|$(SPOOLDIR)|g;' \ + -e 's|\@\@PERL\@\@|$(PERL)|g;' \ + -e 's|\@\@PERLLIB\@\@|$(PERLLIB)|g;' \ + -e 's|\@\@PYTHON\@\@|$(PYTHON)|g;' \ + -e 's|\@\@RUBY\@\@|$(RUBY)|g;' \ + -e 's|\@\@JAVARUN\@\@|$(JAVARUN)|g;' \ + -e 's|\@\@JAVALIBDIR\@\@|$(JAVALIBDIR)|g;' \ + -e 's|\@\@OSTYPE\@\@|$(OSTYPE)|g;' \ + -e 's|\@\@HOSTNAME\@\@|$(HOSTNAME)|g;' \ + -e 's|\@\@MKTEMP\@\@|$(MKTEMP)|g;' \ + -e 's|\@\@VERSION\@\@|$(VERSION)|g;' \ + -e 's|\@\@PLUGSTATE\@\@|$(PLUGSTATE)|g;' \ + -e 's|\@\@CGIDIR\@\@|$(CGIDIR)|g;' \ + -e 's|\@\@USER\@\@|$(USER)|g;' \ + -e 's|\@\@GROUP\@\@|$(GROUP)|g;' \ + -e 's|\@\@PLUGINUSER\@\@|$(PLUGINUSER)|g;' \ + -e 's|\@\@GOODSH\@\@|$(GOODSH)|g;' \ + -e 's|\@\@BASH\@\@|$(BASH)|g;' \ + -e 's|\@\@HASSETR\@\@|$(HASSETR)|g;' \ + $(CONFVAR_SUBSTITUTION_FILES) build-common-pre: common/Build cd common && $(PERL) Build code -common/blib/lib/Munin/Common/Defaults.pm: common/lib/Munin/Common/Defaults.pm build-common-pre + +# The target needs an update, if the latest substitution stamp is older then the generated +# Defaults.pm. This can happen, if: +# * the generated Defaults.pm is missing +# * or "build-common-pre" caused an update of its source file (thus regenerated Defaults.pm) +build-common-defaults-stamp: common/blib/lib/Munin/Common/Defaults.pm + $(MAKE) substitute-build-defaults-inline + @# We need the stamp file, due to the inline nature of this build step. Otherwise it would + @# be run again during "install" - which would mess up the paths substituted in that step. + touch build-common-defaults-stamp + + +# The "build-common-defaults-stamp" needs a way to generate the (non-substituted) defaults file +# during its first run. Afterwards its content is sustituted due to the absence of the +# "build-common-defaults-stamp" file. +common/blib/lib/Munin/Common/Defaults.pm: build-common-pre + + +substitute-build-defaults-inline: rm -f common/blib/lib/Munin/Common/Defaults.pm - $(PERL) -pe 's{(PREFIX \s+=\s).*}{\1q{$(PREFIX)};}x; \ - s{(CONFDIR \s+=\s).*}{\1q{$(CONFDIR)};}x; \ - s{(BINDIR \s+=\s).*}{\1q{$(BINDIR)};}x; \ - s{(SBINDIR \s+=\s).*}{\1q{$(SBINDIR)};}x; \ - s{(DOCDIR \s+=\s).*}{\1q{$(DOCDIR)};}x; \ - s{(LIBDIR \s+=\s).*}{\1q{$(LIBDIR)};}x; \ - s{(MANDIR \s+=\s).*}{\1q{$(MANDIR)};}x; \ - s{(LOGDIR \s+=\s).*}{\1q{$(LOGDIR)};}x; \ - s{(HTMLDIR \s+=\s).*}{\1q{$(HTMLDIR)};}x; \ - s{(DBDIR \s+=\s).*}{\1q{$(DBDIR)};}x; \ - s{(STATEDIR \s+=\s).*}{\1q{$(STATEDIR)};}x; \ - s{(SPOOLDIR \s+=\s).*}{\1q{$(SPOOLDIR)};}x; \ - s{(PERL \s+=\s).*}{\1q{$(PERL)};}x; \ - s{(PERLLIB \s+=\s).*}{\1q{$(PERLLIB)};}x; \ - s{(PYTHON \s+=\s).*}{\1q{$(PYTHON)};}x; \ - s{(RUBY \s+=\s).*}{\1q{$(RUBY)};}x; \ - s{(OSTYPE \s+=\s).*}{\1q{$(OSTYPE)};}x; \ - s{(HOSTNAME \s+=\s).*}{\1q{$(HOSTNAME)};}x; \ - s{(MKTEMP \s+=\s).*}{\1q{$(MKTEMP)};}x; \ - s{(VERSION \s+=\s).*}{\1q{$(VERSION)};}x; \ - s{(PLUGSTATE \s+=\s).*}{\1q{$(PLUGSTATE)};}x; \ - s{(CGIDIR \s+=\s).*}{\1q{$(CGIDIR)};}x; \ - s{(USER \s+=\s).*}{\1q{$(USER)};}x; \ - s{(GROUP \s+=\s).*}{\1q{$(GROUP)};}x; \ - s{(PLUGINUSER \s+=\s).*}{\1q{$(PLUGINUSER)};}x; \ - s{(GOODSH \s+=\s).*}{\1q{$(GOODSH)};}x; \ - s{(BASH \s+=\s).*}{\1q{$(BASH)};}x; \ - s{(HASSETR \s+=\s).*}{\1q{$(HASSETR)};}x;' \ - $< > $@ + $(PERL) -pe 's{(PREFIX\s+=\s).*}{\1q{$(PREFIX)};}x; \ + s{(CONFDIR\s+=\s).*}{\1q{$(CONFDIR)};}x; \ + s{(BINDIR\s+=\s).*}{\1q{$(BINDIR)};}x; \ + s{(SBINDIR\s+=\s).*}{\1q{$(SBINDIR)};}x; \ + s{(DOCDIR\s+=\s).*}{\1q{$(DOCDIR)};}x; \ + s{(LIBDIR\s+=\s).*}{\1q{$(LIBDIR)};}x; \ + s{(MANDIR\s+=\s).*}{\1q{$(MANDIR)};}x; \ + s{(LOGDIR\s+=\s).*}{\1q{$(LOGDIR)};}x; \ + s{(HTMLDIR\s+=\s).*}{\1q{$(HTMLDIR)};}x; \ + s{(DBDIR\s+=\s).*}{\1q{$(DBDIR)};}x; \ + s{(STATEDIR\s+=\s).*}{\1q{$(STATEDIR)};}x; \ + s{(SPOOLDIR\s+=\s).*}{\1q{$(SPOOLDIR)};}x; \ + s{(PERL\s+=\s).*}{\1q{$(PERL)};}x; \ + s{(PERLLIB\s+=\s).*}{\1q{$(PERLLIB)};}x; \ + s{(PYTHON\s+=\s).*}{\1q{$(PYTHON)};}x; \ + s{(RUBY\s+=\s).*}{\1q{$(RUBY)};}x; \ + s{(OSTYPE\s+=\s).*}{\1q{$(OSTYPE)};}x; \ + s{(HOSTNAME\s+=\s).*}{\1q{$(HOSTNAME)};}x; \ + s{(MKTEMP\s+=\s).*}{\1q{$(MKTEMP)};}x; \ + s{(VERSION\s+=\s).*}{\1q{$(VERSION)};}x; \ + s{(PLUGSTATE\s+=\s).*}{\1q{$(PLUGSTATE)};}x; \ + s{(CGIDIR\s+=\s).*}{\1q{$(CGIDIR)};}x; \ + s{(USER\s+=\s).*}{\1q{$(USER)};}x; \ + s{(GROUP\s+=\s).*}{\1q{$(GROUP)};}x; \ + s{(PLUGINUSER\s+=\s).*}{\1q{$(PLUGINUSER)};}x; \ + s{(GOODSH\s+=\s).*}{\1q{$(GOODSH)};}x; \ + s{(BASH\s+=\s).*}{\1q{$(BASH)};}x; \ + s{(HASSETR\s+=\s).*}{\1q{$(HASSETR)};}x;' \ + common/lib/Munin/Common/Defaults.pm >common/blib/lib/Munin/Common/Defaults.pm + -build-doc: build-doc-stamp Makefile Makefile.config +build-doc: build-doc-stamp $(MAKEFILES) build-doc-stamp: touch build-doc-stamp mkdir -p build/doc -build-man: build-man-stamp Makefile Makefile.config +build-man: build-man-stamp $(MAKEFILES) -build-man-stamp: - touch build-man-stamp +build-man-stamp: $(INFILES) mkdir -p build/doc for f in $(MAN8); do \ - pod2man --section=8 --release=$(RELEASE) --center=$(MANCENTER) build/"$$f" > build/doc/`basename $$f`.8; \ + pod2man --section=8 --release=$(RELEASE) --center=$(MANCENTER) build/"$$f" > build/doc/`basename $$f`.8; \ done for f in $(PODMAN8); do \ - pod2man --section=8 --release=$(RELEASE) --center=$(MANCENTER) "$$f".pod > build/doc/`basename $$f .pod`.8; \ + pod2man --section=8 --release=$(RELEASE) --center=$(MANCENTER) "$$f".pod > build/doc/`basename $$f .pod`.8; \ done for f in $(PODMAN5); do \ - pod2man --section=5 --release=$(RELEASE) --center=$(MANCENTER) "$$f".pod > build/doc/`basename $$f .pod`.5; \ + pod2man --section=5 --release=$(RELEASE) --center=$(MANCENTER) "$$f".pod > build/doc/`basename $$f .pod`.5; \ done + touch build-man-stamp + build-plugins-java: build/plugins/javalib/munin-jmx-plugins.jar @@ -364,21 +407,45 @@ ###################################################################### # DIST RULES -tar: - git archive --prefix=munin-$(RELEASE)/ --format=tar --output ../munin-$(RELEASE).tar HEAD - mkdir -p munin-$(RELEASE)/ - echo $(RELEASE) > munin-$(RELEASE)/RELEASE - tar rf ../munin-$(RELEASE).tar --owner=root --group=root munin-$(RELEASE)/RELEASE - rm -rf munin-$(RELEASE) - gzip -f -9 ../munin-$(RELEASE).tar +.PHONY: tar +tar: munin-$(RELEASE).tar.gz.sha256sum + +.PHONY: tar-signed +tar-signed: munin-$(RELEASE).tar.gz.asc + +munin-$(RELEASE).tar.gz: + @# prevent the RELEASE file from misleading the "getversion" script + rm -f RELEASE + tempdir=$$(mktemp -d) \ + && mkdir -p "$$tempdir/munin-$(RELEASE)/" \ + && echo $(RELEASE) > "$$tempdir/munin-$(RELEASE)/RELEASE" \ + && git archive --prefix=munin-$(RELEASE)/ --format=tar --output "$$tempdir/export.tar" HEAD \ + && tar --append --file "$$tempdir/export.tar" --owner=root --group=root -C "$$tempdir" "munin-$(RELEASE)/RELEASE" \ + && gzip -9 <"$$tempdir/export.tar" >"munin-$(RELEASE).tar.gz" \ + && rm -rf "$$tempdir" + +munin-$(RELEASE).tar.gz.sha256sum: munin-$(RELEASE).tar.gz + sha256sum "$<" >"$@" + +munin-$(RELEASE).tar.gz.asc: munin-$(RELEASE).tar.gz + gpg --armor --detach-sign --sign "$<" + +.PHONY: tar-upload +tar-upload: tar tar-signed + @if [ -z "$(UPLOAD_DIR)" ]; then echo "You need to set UPLOAD_DIR (e.g. '/srv/www/downloads.munin-monitoring.org/munin/stable')" >&2; false; fi + @if [ -z "$(UPLOAD_HOST)" ]; then echo "You need to set UPLOAD_HOST" >&2; false; fi + { \ + echo "mkdir $(UPLOAD_DIR)/$(VERSION)"; \ + echo "put munin-$(VERSION).tar.gz* $(UPLOAD_DIR)/$(VERSION)/"; \ + } | sftp -b - "$(UPLOAD_HOST)" suse-pre: (! grep MAINTAINER Makefile.config) - @for file in `find dists/suse/ -type f -name '*.in'`; do \ - destname=`echo $$file | sed 's/.in$$//'`; \ - echo Generating $$destname..; \ - sed -e 's|@@VERSION@@|$(VERSION)|g' \ - $$file > $$destname; \ + @for file in `find dists/suse/ -type f -name '*.in'`; do \ + destname=`echo $$file | sed 's/.in$$//'`; \ + echo Generating $$destname..; \ + sed -e 's|@@VERSION@@|$(VERSION)|g' \ + $$file > $$destname; \ done -cp dists/tarball/plugins.conf . # (cd ..; ln -s munin munin-$(VERSION)) @@ -409,6 +476,8 @@ -rm -f build-doc-stamp -rm -f build-man-stamp -rm -f build-java-stamp + -rm -f build-confvar-substitution-stamp + -rm -f build-common-defaults-stamp -rm -rf t/install -rm -f dists/redhat/munin.spec @@ -449,26 +518,49 @@ # This builds */Build from Build.PL %/Build: %/Build.PL - cd $* && $(PERL) Build.PL + cd $* && $(PERL) -I. Build.PL build-%: %/Build cd $* && $(PERL) Build -build-common: common/Build +build-common: build-common-defaults-stamp # BUG: the Build script writes files under PWD when it does "install" # can't seem to find a way to persuade it to write otherwhere. install-%: %/Build - cd $* && $(PERL) Build install \ - --install_path lib=$(PERLLIB) \ - --install_path bin=$(BINDIR) \ - --install_path script=$(BINDIR) \ - --install_path sbin=$(SBINDIR) \ - --install_path bindoc=$(MANDIR)/man1 \ - --install_path libdoc=$(MANDIR)/man3 \ + cd $* && $(PERL) Build install \ + --install_path lib=$(PERLLIB) \ + --install_path bin=$(BINDIR) \ + --install_path script=$(BINDIR) \ + --install_path sbin=$(SBINDIR) \ + --install_path bindoc=$(MANDIR)/man1 \ + --install_path libdoc=$(MANDIR)/man3 test-%: %/Build - cd $* && $(PERL) Build test --verbose=0 || true + cd $* && $(PERL) Build test --verbose=0 + +lint: + @# SC1008: ignore our weird shebang (substituted later) + @# SC1090: ignore sourcing of files with variable in path + @# SC2009: do not complain about "ps ... | grep" calls (may be platform specific) + @# SC2126: tolerate "grep | wc -l" (simple and widespread) instead of "grep -c" + @# SC2230: do not complain about "which" (instead of "command -v") + # TODO: fix the remaining shellcheck issues for the missing platforms: + # aix, darwin, netbsd, sunos + # (these require tests with their specific shell implementations) + find plugins/node.d/ \ + plugins/node.d.cygwin/ \ + plugins/node.d.debug/ \ + plugins/node.d.linux/ -type f -print0 \ + | xargs -0 grep -l --null "@@GOODSH@@" \ + | xargs -0 shellcheck --exclude=SC1008,SC1090,SC2009,SC2126,SC2230,SC2239 --shell dash + find plugins/ -type f -print0 \ + | xargs -0 grep -l --null "@@BASH@@" \ + | xargs -0 shellcheck --exclude=SC1008,SC1090,SC2009,SC2126,SC2230,SC2239 --shell bash + find plugins/ -type f -print0 \ + | xargs -0 grep -l --null "@@PYTHON@@" \ + | xargs -0 $(PYTHON_LINT_CALL) + # TODO: perl plugins currently fail with perlcritic -clean-%: %/Build common/blib/lib/Munin/Common/Defaults.pm +clean-%: %/Build build-common-defaults-stamp cd $* && $(PERL) Build realclean diff -Nru munin-2.0.37/Makefile.config munin-2.0.47/Makefile.config --- munin-2.0.37/Makefile.config 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/Makefile.config 2019-02-28 14:43:36.000000000 +0000 @@ -66,7 +66,7 @@ PERL := $(shell which perl) # The python interpreter to use (used by some plugins) -PYTHON := /usr/bin/env python +PYTHON := /usr/bin/env python3 # The ruby interpreter to use (used by some plugins) RUBY := /usr/bin/env ruby @@ -95,8 +95,7 @@ BASH := /bin/bash # Server only - Where to install the perl libraries -PERLSITELIB := $(shell $(PERL) -V:sitelib | cut -d"'" -f2) -PERLLIB = $(DESTDIR)$(PERLSITELIB) +PERLLIB = $(DESTDIR)$(shell $(PERL) -V:sitelib | cut -d"'" -f2) # Client only - Install plugins for this architecture # the LANG=C makes tr work as expected, not regarding any locale it @@ -127,31 +126,33 @@ CGIUSER := nobody # Which command to use to check if the USER and GROUP to run Munin as, exists. -# These will work on most modern OSes: -# -GETENT := $(shell which getent || which true 2>/dev/null) -CHECKUSER := $(shell $(GETENT) passwd $(USER) >/dev/null 2>/dev/null || (echo "echo User $(USER) nonexistent. Create the user and retry; exit 2")) -CHECKGROUP := $(shell $(GETENT) group $(GROUP) >/dev/null 2>/dev/null || (echo "echo Group $(GROUP) nonexistent. Create the group and retry; exit 2")) - -# For OSX, comment out the previous two lines and comment in these -# -#CHECKUSER := $(shell nicl . -read /users/$(USER) >/dev/null 2>/dev/null || (echo "echo User $(USER) nonexistent. Create the user and retry; exit 2")) -#CHECKGROUP := $(shell nicl . -read /groups/$(GROUP) >/dev/null 2>/dev/null || (echo "echo Group $(GROUP) nonexistent. Create the group and retry; exit 2")) - -# For OSX 10.5 (Leopard), use the following two lines instead of what's above -# -#CHECKUSER := $(shell dscl . -read /Users/$(USER) >/dev/null 2>/dev/null || (echo "echo User $(USER) nonexistent. Create the user and retry; exit 2")) -#CHECKGROUP := $(shell dscl . -read /Groups/$(GROUP) >/dev/null 2>/dev/null || (echo "echo Group $(GROUP) nonexistent. Create the group and retry; exit 2")) - - -# For HP-UX, use these instead: -# -#CHECKUSER := $(shell pwget -n $(USER) >/dev/null 2>/dev/null || (echo "echo User $(USER) nonexistent. Create the user and retry; exit 2")) -#CHECKGROUP := $(shell grget -n $(GROUP) >/dev/null 2>/dev/null || (echo "echo Group $(GROUP) nonexistent. Create the group and retry; exit 2")) - -# For Cygwin, use these instead: -#CHECKUSER := $(shell id $(USER) >/dev/null 2>/dev/null || (echo "echo User $(USER) nonexistent. Create the user and retry; exit 2")) -#CHECKGROUP := $(shell grep ^$(GROUP): /etc/group >/dev/null 2>/dev/null || (echo "echo Group $(GROUP) nonexistent. Create the group and retry; exit 2")) +ifneq ($(shell which getent),) + # "getent" works on most modern OS + CHECKUSER_COMMAND := getent passwd $(USER) + CHECKGROUP_COMMAND := getent group $(GROUP) +else + ifeq ($(OSTYPE),darwin) + # This should work for OSX 10.5 (Leopard) or later + CHECKUSER_COMMAND := dscl . -read /Users/$(USER) + CHECKGROUP_COMMAND := dscl . -read /Groups/$(GROUP) + else + ifeq ($(OSTYPE),cygwin) + CHECKUSER_COMMAND := id $(USER) + CHECKGROUP_COMMAND := grep ^$(GROUP): /etc/group + else + ifeq ($(OSTYPE),hp-ux) + CHECKUSER_COMMAND := pwget -n $(USER) + CHECKGROUP_COMMAND := grget -n $(GROUP) + else + $(warning Missing test for user existence on this platform. Skipping this check and hoping for the best ...) + CHECKUSER_COMMAND := true + CHECKGROUP_COMMAND := true + endif + endif + endif +endif +CHECKUSER := $(shell $(CHECKUSER_COMMAND) >/dev/null 2>/dev/null || (echo "echo User $(USER) nonexistent. Create the user and retry; exit 2")) +CHECKGROUP := $(shell $(CHECKGROUP_COMMAND) >/dev/null 2>/dev/null || (echo "echo Group $(GROUP) nonexistent. Create the group and retry; exit 2")) CHOWN := chown CHMOD := chmod @@ -159,7 +160,7 @@ # Java compiler stuff - only needed on the buildhost JC := javac -JFLAGS := -g -source 1.5 -target 1.5 -Xlint +JFLAGS := -g -source 1.7 -target 1.7 -Xlint JAR := jar # Check if the java compiler works diff -Nru munin-2.0.37/Makefile.config-maint munin-2.0.47/Makefile.config-maint --- munin-2.0.37/Makefile.config-maint 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/Makefile.config-maint 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +0,0 @@ -# -*- makefile -*- -# -# MAINTAINER VERSION OF Makefile.config -# -# This file is used by the maintainer for testing and only necessarily -# works on the maintainers machines. Please see Makefile.config-dist -# for the user directed Makefile.config as directed in the INSTALL doc. -# -# $Id: Makefile.config 1551 2008-03-06 20:16:51Z janl $ - -# This file specifies where Munin will look for things after you've -# run 'make' in the source directory. Modify it to suit your needs. - -# DESTDIR is meant only for use when making Munin packages. Unless -# you're doing packaging do NOT set it. -# DESTDIR is empty during building, and optionally set to point to -# a shadow tree during make install. - -# Include the default config -include Makefile.config-dist - -# Then override - -PREFIX = $(DESTDIR)/usr -CONFDIR = $(DESTDIR)/etc/munin -DOCDIR = $(PREFIX)/share/doc/munin -MANDIR = $(PREFIX)/share/man - -# Where to put internal binaries and plugin repository -LIBDIR = $(PREFIX)/share/munin - -# Server only - Output directory -HTMLDIR = $(DESTDIR)/var/www/munin -CGIDIR = $(HTMLDIR)/../cgi - -# Client only - Where to put RRD files and other intenal data -DBDIR = $(DESTDIR)/var/lib/munin - -# Client only - Where plugins should put their states. Must be writable by -# group "munin", and should be preserved between reboots -PLUGSTATE = $(DBDIR)/plugin-state - -# Where Munin should place its logs. -LOGDIR = $(DESTDIR)/var/log/munin - -# Location of PID files and other statefiles. On the server, must be -# writable by the user "munin". -STATEDIR = $(DESTDIR)/var/run/munin - -# The perl interpreter to use -PERL := $(shell which perl) - -# The python interpreter to use (used by some plugins) -PYTHON := /usr/bin/env python - -# The ruby interpreter to use (used by some plugins) -RUBY := /usr/bin/env ruby - -# The java runtime to use (used by some plugins) -JAVARUN := /usr/bin/java - -# A modern shell. We're not looking for arrays, but $() and other modern -# stuff is expected. -# Linux: /bin/bash -# SunOS/Solaris: /usr/xpg4/bin/sh or /bin/ksh -# In general: bash or ksh will work -GOODSH := /bin/bash - -# Path of bash for bash specific plugins -BASH := /bin/bash - -# Server only - Where to install the perl libraries -PERLSITELIB := $(shell $(PERL) -V:sitelib | cut -d"'" -f2) -PERLLIB = $(DESTDIR)$(PERLSITELIB) - -# Client only - Install plugins for this architecture -OSTYPE := $(shell uname | tr '[A-Z]' '[a-z]') - -# How to figure out the hostname. (Only used in default configuration -# files) -HOSTNAME := $(shell hostname) - -# What is the safest way to create a tempfile. -# Default is to figure it out by testing various methods. -# Replace this with a known platform-specific method -MKTEMP := $(shell ./test-mktemp) - -# Munin version number. -VERSION := $(shell ./getversion) - -# User to run munin as -USER := munin -GROUP := munin - -# Default user to run the plugins as -PLUGINUSER := nobody - -# Which command to use to check if the USER and GROUP to run Munin as, exists. - -GETENT := $(shell which getent || which true 2>/dev/null) -CHECKUSER := $(shell $(GETENT) passwd $(USER) >/dev/null 2>/dev/null || (echo "echo User $(USER) nonexistent. Create the user and retry; exit 2")) -CHECKGROUP := $(shell $(GETENT) group $(GROUP) >/dev/null 2>/dev/null || (echo "echo Group $(GROUP) nonexistent. Create the group and retry; exit 2")) - -CHOWN := chown -CHMOD := chmod -CHGRP := chgrp - -# Java compiler stuff - only needed on the buildhost -JC := javac -JFLAGS := -g -JAR := jar - -# Check if the java compiler works -JCVALID := $(shell $(JC) -version >/dev/null 2>/dev/null && echo "yes") - diff -Nru munin-2.0.37/master/_bin/munin-cgi-html.in munin-2.0.47/master/_bin/munin-cgi-html.in --- munin-2.0.37/master/_bin/munin-cgi-html.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/_bin/munin-cgi-html.in 2019-02-28 14:43:36.000000000 +0000 @@ -168,7 +168,10 @@ # CGI in perl 5.20 is now seriously broken as it doesn't import into the namespace. # So we have to delegate explicitely. It's easier than prefixing with CGI:: each use. -sub header { return CGI::header(@_); } -sub path_info { return CGI::path_info(@_); } -sub url { return CGI::url(@_); } -sub script_name { return CGI::script_name(@_); } +# This workaround is applied only if "header" is undefined (i.e. for perl >= 5.20). +if(!defined &header){ + *header = sub { return CGI::header(@_); }; + *path_info = sub { return CGI::path_info(@_); }; + *url = sub { return CGI::url(@_); }; + *script_name = sub { return CGI::script_name(@_); }; +} diff -Nru munin-2.0.37/master/_bin/munin-update.in munin-2.0.47/master/_bin/munin-update.in --- munin-2.0.37/master/_bin/munin-update.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/_bin/munin-update.in 2019-02-28 14:43:36.000000000 +0000 @@ -122,7 +122,7 @@ Options: --config_file= Use as configuration file. --[no]debug Enable [or disable] debug messages. [--nodebug] - --[no]fork Query hosts in parallell (--fork), or + --[no]fork Query hosts in parallel (--fork), or sequentially (--nofork). [--fork] --host Limit graphed hosts to . Multiple --host options may be supplied. diff -Nru munin-2.0.37/master/Build.PL munin-2.0.47/master/Build.PL --- munin-2.0.37/master/Build.PL 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/Build.PL 2019-02-28 14:43:36.000000000 +0000 @@ -3,10 +3,13 @@ use warnings; use strict; +my $version = `../getversion`; +chomp($version); + my $build = MasterBuilder->new( dist_name => 'Munin::Master', - dist_version => '0.0.0', - dist_author => 'The Munin Team ', + dist_version => $version, + dist_author => 'The Munin Team ', dist_abstract => 'The Munin Master', license => 'gpl', requires => { diff -Nru munin-2.0.37/master/lib/Munin/Master/GraphOld.pm munin-2.0.47/master/lib/Munin/Master/GraphOld.pm --- munin-2.0.37/master/lib/Munin/Master/GraphOld.pm 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/lib/Munin/Master/GraphOld.pm 2019-02-28 14:43:36.000000000 +0000 @@ -13,7 +13,7 @@ wait until later. Copyright (C) 2002-2010 Jimmy Olsen, Audun Ytterdal, Kjell Magne -Øierud, Nicolai Langfeldt, Linpro AS, Redpill Linpro AS and others. +Øierud, Nicolai Langfeldt, Linpro AS, Redpill Linpro AS and others. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -1169,26 +1169,13 @@ elsif (my $tmpwarn = munin_get($negfield, "warning")) { my ($warn_min, $warn_max) = split(':', $tmpwarn,2); + my $warn_colour = $single_value ? "ff0000" : $colour; if (defined($warn_min) and $warn_min ne '') { - unshift( - @rrd, - "HRULE:" - . $warn_min - . "#" . ( - $single_value - ? "ff0000" - : $COLOUR[($field_count - 1) % @COLOUR])); + unshift(@rrd, "HRULE:$warn_min#$warn_colour"); } if (defined($warn_max) and $warn_max ne '') { - unshift( - @rrd, - "HRULE:" - . $warn_max - . "#" . ( - $single_value - ? "ff0000" - : $COLOUR[($field_count - 1) % @COLOUR])); + unshift(@rrd, "HRULE:$warn_max#$warn_colour"); } } @@ -1793,9 +1780,9 @@ my $fieldname = munin_get_node_name($field); my $rrdname = &orig_to_cdef($service, $fieldname); if ($cdef =~ /\b$fieldname\b/) { - $max =~ s/([,=])$fieldname([,=]|$)/$1a$rrdname$2/g; - $min =~ s/([,=])$fieldname([,=]|$)/$1i$rrdname$2/g; - $avg =~ s/([,=])$fieldname([,=]|$)/$1g$rrdname$2/g; + $max =~ s/(?<=[,=(])$fieldname(?=[,=)]|$)/a$rrdname/g; + $min =~ s/(?<=[,=(])$fieldname(?=[,=)]|$)/i$rrdname/g; + $avg =~ s/(?<=[,=(])$fieldname(?=[,=)]|$)/g$rrdname/g; } } diff -Nru munin-2.0.37/master/lib/Munin/Master/HTMLConfig.pm munin-2.0.47/master/lib/Munin/Master/HTMLConfig.pm --- munin-2.0.37/master/lib/Munin/Master/HTMLConfig.pm 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/lib/Munin/Master/HTMLConfig.pm 2019-02-28 14:43:36.000000000 +0000 @@ -502,11 +502,11 @@ my $start_year = $epoch_now - (3600 * 24 * 400); my $size_x = 800; my $size_y = 400; - my $common_url = "$root_path/static/dynazoom.html?cgiurl_graph=$config->{'cgiurl_graph'}&plugin_name=$path&size_x=$size_x&size_y=$size_y"; - $srv{zoomday} = "$common_url&start_epoch=$start_day&stop_epoch=$epoch_now"; - $srv{zoomweek} = "$common_url&start_epoch=$start_week&stop_epoch=$epoch_now"; - $srv{zoommonth} = "$common_url&start_epoch=$start_month&stop_epoch=$epoch_now"; - $srv{zoomyear} = "$common_url&start_epoch=$start_year&stop_epoch=$epoch_now"; + my $common_url = "$root_path/static/dynazoom.html?cgiurl_graph=$config->{'cgiurl_graph'}&plugin_name=$path&size_x=$size_x&size_y=$size_y"; + $srv{zoomday} = "$common_url&start_epoch=$start_day&stop_epoch=$epoch_now"; + $srv{zoomweek} = "$common_url&start_epoch=$start_week&stop_epoch=$epoch_now"; + $srv{zoommonth} = "$common_url&start_epoch=$start_month&stop_epoch=$epoch_now"; + $srv{zoomyear} = "$common_url&start_epoch=$start_year&stop_epoch=$epoch_now"; } for my $scale (@times) { diff -Nru munin-2.0.37/master/lib/Munin/Master/LimitsOld.pm munin-2.0.47/master/lib/Munin/Master/LimitsOld.pm --- munin-2.0.37/master/lib/Munin/Master/LimitsOld.pm 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/lib/Munin/Master/LimitsOld.pm 2019-02-28 14:43:36.000000000 +0000 @@ -647,6 +647,16 @@ $hash->{'ufields'} = join " ", @{$stats{'unknown'}}; $hash->{'fofields'} = join " ", @{$stats{'foks'}}; $hash->{'ofields'} = join " ", @{$stats{'ok'}}; + # The "fofields" (datasets that changed state from "failed" to "OK") can be empty under certain + # legitimate circumstances (e.g. "munin-limits --force" sends messages also for unchanged "OK" + # states). But we may never allow the fourth output field for NSCA to be empty - otherwise the + # recipient (nagios/icinga) cannot determine, which fields are affected (and thus which test + # succeeded). Thus we need to make sure, that "fofields" is always defined (since our + # self-made trivial template language does not support expressions like "fofields || ofields"). + # Here "ofields" is a reasonable fallback value: it contains all datasets with status "OK". + if ($hash->{'fofields'} eq '') { + $hash->{'fofields'} = $hash->{'ofields'}; + } $hash->{'numcfields'} = scalar @{$stats{'critical'}}; $hash->{'numwfields'} = scalar @{$stats{'warning'}}; $hash->{'numufields'} = scalar @{$stats{'unknown'}}; diff -Nru munin-2.0.37/master/lib/Munin/Master/ProcessManager.pm munin-2.0.47/master/lib/Munin/Master/ProcessManager.pm --- munin-2.0.37/master/lib/Munin/Master/ProcessManager.pm 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/lib/Munin/Master/ProcessManager.pm 2019-02-28 14:43:36.000000000 +0000 @@ -263,6 +263,7 @@ } }; if ($EVAL_ERROR) { + $EVAL_ERROR =~ s/\R//; ERROR "[ERROR] $worker died with '$EVAL_ERROR'"; $res = undef; $retval = $E_DIED; diff -Nru munin-2.0.37/master/static/dynazoom.html munin-2.0.47/master/static/dynazoom.html --- munin-2.0.37/master/static/dynazoom.html 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/static/dynazoom.html 2019-02-28 14:43:36.000000000 +0000 @@ -1,11 +1,24 @@ + - - + + Munin: dynamic graph zoom + + + +
- + Dynamically zoomable graph
@@ -16,30 +29,30 @@ Zooming is very easy, it's done in 3 clicks (regular clicks, no drag&drop): -
    -
  • First click to define the start of zoom. -
  • Second click to define the ending of zoom. -
  • Third click inside the defined zone to zoom, outside to cancel the zone. -
- +
    +
  1. First click to define the start of zoom.
  2. +
  3. Second click to define the ending of zoom.
  4. +
  5. Third click inside the defined zone to zoom, outside to cancel the zone.
  6. +
+ -
+ - + - + @@ -48,7 +61,7 @@ @@ -58,18 +71,19 @@
Plugin Name (domain/hostname/plugin_name) :
Start/Stop of the graph
(format:2005-08-15T15:52:01+0000)
(epoch) :
Start/Stop of the graph
(format:2005-08-15T15:52:01+0000)
(epoch) :
- /
+ /
- ( / ) + ( / )
Limit low/high : - / + /
Graph size (w/o legend) (pixels): - / + /
- - - +

+ + + +

- - - - - - + + diff -Nru munin-2.0.37/master/t/munin_master_config.t munin-2.0.47/master/t/munin_master_config.t --- munin-2.0.37/master/t/munin_master_config.t 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/t/munin_master_config.t 2019-02-28 14:43:36.000000000 +0000 @@ -29,6 +29,7 @@ debug => 0, fork => 1, graph_data_size => 'normal', + graph_strategy => 'cron', groups => { marvin => { hosts => { @@ -51,6 +52,8 @@ logdir => '/opt/munin/sandbox/var/log/munin', max_processes => 16, rundir => '/opt/munin/sandbox/var/run/munin', + ssh_command => "ssh", + ssh_options => "-o ChallengeResponseAuthentication=no -o StrictHostKeyChecking=no", timeout => 180, tls => 'disabled', tls_ca_certificate => '/opt/munin/common/t/tls/CA/ca_cert.pem', diff -Nru munin-2.0.37/master/t/munin_master_node.t munin-2.0.47/master/t/munin_master_node.t --- munin-2.0.37/master/t/munin_master_node.t 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/t/munin_master_node.t 2019-02-28 14:43:36.000000000 +0000 @@ -54,10 +54,19 @@ ### _extract_name_from_greeting { + sub _extract_name_from_greeting { + my ($greeting) = @_; + if ($greeting && ($greeting =~ /\#.*(?:lrrd|munin) (?:client|node) at (\S+)/i)) { + return $1; + } else { + return ""; + } + } + my $node = Munin::Master::Node->new(); - is($node->_extract_name_from_greeting('# munin node at foo.example.com'), + is(_extract_name_from_greeting('# munin node at foo.example.com'), 'foo.example.com', 'Node name from new greeting'); - is($node->_extract_name_from_greeting('# lrrd client at foo.example.com'), + is(_extract_name_from_greeting('# lrrd client at foo.example.com'), 'foo.example.com', 'Node name from old greeting'); } @@ -210,7 +219,10 @@ fun => [ [qw( foo bar )], [qw( zap gabonk )], - [ 'graph_order', 'zip baz' ], + # The internal "graph_order" implementation changed in 53f22440a and now + # includes the list of data field appearances after the explicitly configured + # graph_order. + [ 'graph_order', 'zip baz baz zip' ], ], }, data_source => { diff -Nru munin-2.0.37/master/t/munin_master_plugin_config.t munin-2.0.47/master/t/munin_master_plugin_config.t --- munin-2.0.37/master/t/munin_master_plugin_config.t 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/t/munin_master_plugin_config.t 2019-02-28 14:43:36.000000000 +0000 @@ -121,7 +121,10 @@ ], [ 'graph_order', - 'system user nice idle iowait irq softirq' + # Since 53f22440a the internal "graph_order" implementation + # includes the list of data field appearances after the + # explicitly configured graph_order. + 'system user nice idle iowait irq softirq system user' ], [ 'graph_args', diff -Nru munin-2.0.37/master/t/munin_master_processmanager.t munin-2.0.47/master/t/munin_master_processmanager.t --- munin-2.0.37/master/t/munin_master_processmanager.t 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/t/munin_master_processmanager.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -use warnings; -use strict; - -use Test::More tests => 17; -use Time::HiRes qw(sleep); -use File::Temp qw( tempdir ); - -use_ok('Munin::Master::ProcessManager'); - -use Munin::Master::Config; -my $config = Munin::Master::Config->instance()->{config}; -$config->{rundir} = tempdir(CLEANUP => 1); - -### Uncomment to see log messages -# -#use Munin::Master::Logger; -#logger_debug(); -#$config->{debug} = 1; - - -# -# Define some test workers -# -package Test::Worker; -use base q(Munin::Master::Worker); - -sub do_work { - my ($self) = @_; - - 1 for (0 .. rand 1_000_000); # sleep and alarm does not mix ... - return $self->{ID}; -} - - -package Test::NastyWorker; -use base q(Munin::Master::Worker); - -use Carp; - -sub do_work { - croak "I'm nasty!"; -} - -package Test::SpinningWorker; -use base q(Munin::Master::Worker); - -sub do_work { - 1 while (1); -} - -package main; - -# -# The tests -# - -sub result_callback { - my ($res) = @_; - - ok($res->[0] == 1 || $res->[0] == 2 || $res->[0] == 3, "$res->[0] in 1,2,3"); - is_deeply($res, [$res->[0], $res->[0]], "\$res == [X,X], X <- $res->[0]"); -} - - -{ - my $pm = Munin::Master::ProcessManager->new(\&result_callback); - isa_ok($pm, 'Munin::Master::ProcessManager'); - - $pm->add_workers( - Test::Worker->new(1), - Test::Worker->new(2), - Test::Worker->new(3), - ); - - $pm->start_work(); -} - - -{ - my $pm = Munin::Master::ProcessManager->new(\&result_callback); - - $pm->{max_concurrent} = 1; - - $pm->add_workers( - Test::Worker->new(1), - Test::Worker->new(2), - Test::Worker->new(3), - ); - - $pm->start_work(); -} - - -sub result_callback2 { - my ($res) = @_; - - is($res->[1], 1, "Got 1"); -} - - -sub error_callback2 { - my ($worker_id, $msg) = @_; - - ok($msg eq 'Timed out' || $msg eq 'Died', "Got error msg $msg"); -} - - -{ - my $pm = Munin::Master::ProcessManager->new(\&result_callback2, \&error_callback2); - - $pm->{worker_timeout} = 1; - - $pm->add_workers( - Test::NastyWorker->new(), - Test::SpinningWorker->new(), - Test::Worker->new(1), - ); - - $pm->start_work(); -} diff -Nru munin-2.0.37/master/t/munin_master_update.t munin-2.0.47/master/t/munin_master_update.t --- munin-2.0.37/master/t/munin_master_update.t 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/t/munin_master_update.t 2019-02-28 14:43:36.000000000 +0000 @@ -67,6 +67,7 @@ open my $fh, '>', \$result or die $OS_ERROR; $update->_write_new_service_configs($fh); + no warnings 'once'; my $expected = "version $Munin::Common::Defaults::MUNIN_VERSION\n" . remove_indentation(q{ g1;host1:service1.graph_title service1 diff -Nru munin-2.0.37/master/t/munin_master_utils.t munin-2.0.47/master/t/munin_master_utils.t --- munin-2.0.37/master/t/munin_master_utils.t 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/t/munin_master_utils.t 2019-02-28 14:43:36.000000000 +0000 @@ -11,7 +11,10 @@ # munin_mkdir_p { ok(munin_mkdir_p("./mkdirt", oct(444)), "Creating valid dir"); - ok(!munin_mkdir_p("./mkdirt/bad", oct(444)), "Creating invalid dir"); + SKIP: { + skip "Directory permission cannot be tested by root", 1 if $REAL_USER_ID == 0; + ok(!munin_mkdir_p("./mkdirt/bad", oct(444)), "Creating invalid dir"); + } eval { rmdir("./mkdirt") }; diff -Nru munin-2.0.37/master/www/munin-dynazoom.tmpl munin-2.0.47/master/www/munin-dynazoom.tmpl --- munin-2.0.37/master/www/munin-dynazoom.tmpl 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/www/munin-dynazoom.tmpl 2019-02-28 14:43:36.000000000 +0000 @@ -20,11 +20,11 @@ Zooming is easy, it's done in 3 clicks (regular clicks, no drag&drop):
    -
  1. First click to define the start of zoom. -
  2. Second click to define the ending of zoom. -
  3. Third click inside the defined zone to zoom, outside to cancel the zone. +
  4. First click to define the start of zoom.
  5. +
  6. Second click to define the ending of zoom.
  7. +
  8. Third click inside the defined zone to zoom, outside to cancel the zone.
- + @@ -33,16 +33,16 @@ Plugin Name (domain/hostname/plugin_name) : - + - Start/Stop of the graph
(format:2005-08-15T15:52:01+0000)
(epoch) : + Start/Stop of the graph
(format:2005-08-15T15:52:01+0000)
(epoch) : - /
+ /
- ( / ) + ( / ) @@ -51,7 +51,7 @@ Limit low/high : - / + / @@ -61,12 +61,14 @@ Graph size (w/o legend) (pixels): - / + / +

+

diff -Nru munin-2.0.37/master/www/munin-problemview.tmpl munin-2.0.47/master/www/munin-problemview.tmpl --- munin-2.0.37/master/www/munin-problemview.tmpl 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/www/munin-problemview.tmpl 2019-02-28 14:43:36.000000000 +0000 @@ -7,6 +7,7 @@

Problem Overview

diff -Nru munin-2.0.37/master/www/munin-serviceview.tmpl munin-2.0.47/master/www/munin-serviceview.tmpl --- munin-2.0.37/master/www/munin-serviceview.tmpl 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/master/www/munin-serviceview.tmpl 2019-02-28 14:43:36.000000000 +0000 @@ -66,7 +66,7 @@

Note: This service is in CRITICAL state because one of the values reported is outside the allowed range. Please see further down for information about the ranges and the graph for the values.

-

Note: This service is in UNKNOWN state, because something bad happened. Please check your network, the munin-node, and the plugin. +

Note: This service is in UNKNOWN state, because something bad happened. Please check your network, the munin-node, and the plugin.

@@ -83,13 +83,13 @@ - - + + oddrowevenrow"> - diff -Nru munin-2.0.37/node/bin/munindoc munin-2.0.47/node/bin/munindoc --- munin-2.0.37/node/bin/munindoc 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/bin/munindoc 2019-02-28 14:43:36.000000000 +0000 @@ -57,8 +57,11 @@ # print "Found: ",join(", ",@found),"\n"; # exit 0; +die "munindoc: Could not find plugin\n" if (scalar(@found) == 0); + +# pick only the first match # -F Arguments are file names, not modules -push(@ARGV,'-F',@found); +push(@ARGV, '-F', $found[0]); exit( Pod::Perldoc->run() ); diff -Nru munin-2.0.37/node/_bin/munin-asyncd.in munin-2.0.47/node/_bin/munin-asyncd.in --- munin-2.0.37/node/_bin/munin-asyncd.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/_bin/munin-asyncd.in 2019-02-28 14:43:36.000000000 +0000 @@ -73,10 +73,20 @@ or die ("Cannot create '$SPOOLDIR': $!"); } +my $process_name = "main"; + my $sock = new IO::Socket::INET( PeerAddr => "$host", Proto => 'tcp' -) || die "Error creating socket: $!"; +); +if (!$sock) { + print STDERR "[$$][$process_name] Failed to connect to munin-node - trying again in a few seconds ...\n" if $verbose; + sleep 20; + $sock = new IO::Socket::INET( + PeerAddr => "$host", + Proto => 'tcp' + ) || die "Error connecting to munin node ($host): $!"; +} my $nodeheader = <$sock>; print $sock "quit\n"; close ($sock); @@ -91,8 +101,6 @@ ); $0 = "munin-asyncd [$metahostname] [idle]"; -my $process_name = "main"; - my @plugins; { print STDERR "[$$][$process_name] Reading config from $host\n" if $verbose; @@ -143,7 +151,13 @@ MAIN: while($keepgoing) { my $when = time; - my $when_next = $when + $timeout; # wake up at least every $timeout sec + # start the next run close to the end of a munin-node update operation + # (i.e. try to avoid overlapping activities) + my $when_next = int((int($when / $minrate) + 0.75) * $minrate); + while ($when_next <= $when) { + $when_next = $when_next + $minrate; + } + my $sock; PLUGIN: foreach my $plugin (@plugins) { # See if this plugin should be updated @@ -155,7 +169,6 @@ # Should update it $last_updated{$plugin} = $when; - $when_next = min($when_next, $when + max($plugin_rate, $minrate)); if ($do_fork && fork()) { # parent, return directly @@ -169,8 +182,12 @@ ); unless ($sock) { - warn "Error creating socket: $!, moving to next plugin to try again"; - next; + if ($do_fork) { + die "Error creating socket: $!"; + } else { + warn "Error creating socket: $!, moving to next plugin to try again"; + next; + } } <$sock>; # skip header diff -Nru munin-2.0.37/node/Build.PL munin-2.0.47/node/Build.PL --- munin-2.0.37/node/Build.PL 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/Build.PL 2019-02-28 14:43:36.000000000 +0000 @@ -3,10 +3,13 @@ use warnings; use strict; +my $version = `../getversion`; +chomp($version); + my $build = NodeBuilder->new( dist_name => 'Munin::Node', - dist_version => '0.0.0', - dist_author => 'The Munin Team ', + dist_version => $version, + dist_author => 'The Munin Team ', dist_abstract => 'The Munin Node', license => 'gpl', requires => { diff -Nru munin-2.0.37/node/extras/munin-node-sched munin-2.0.47/node/extras/munin-node-sched --- munin-2.0.37/node/extras/munin-node-sched 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/extras/munin-node-sched 1970-01-01 00:00:00.000000000 +0000 @@ -1,374 +0,0 @@ -#!/usr/bin/perl -w - -use strict; -use Data::Dumper; -use POSIX ":sys_wait_h"; -use Carp; - -# Peder swears that it has been in core since 5.004. -use IPC::Open3; - -# Standard from 5.8 - But does everyone have it? Allows for much higher -# resolution wall clock measures of plugin execution. -# use Time::HiRes; - -# munin-node-sched -# -# Prototype munin node scheduler as proposed in -# http://munin-monitoring.org/wiki/protocol-spool -# -# Goal: -# Run munin plugins and collect the results. Run intervals could be -# as short as every second. -# -# Design considerations: -# - We cannot expect to be scheduled exactly every second (esp. if the host -# is loaded). Therefore use >= and <= and never = for time-stamp -# comparisons. -# - An upshot of such a high load situation is that some plugins with very -# short run intervals (say 1 second) may not be run every second. -# - Collect runtime statistics for plugins to be able to override too -# short intervals with something more realistic -- hopefuly we can -# communicate this problem to the central node in time and make the -# graph red as well as pasting in a message on the plugin/graph page. -# - Never execute a plugin for a given host more thay one at a time. -# - The number of plugins*nodes is expected to be low and running only -# once a second allows some list sorting and searching without getting -# bogged down. -# - Run a given plugin every time $secssinceepoch mod $interval == 0. -# This time the process can be stopped and restarted (host reboot) and -# the plugin execution will just continue as appropriate for the time -# of restart. This allows us to not save state which is probably a -# good thing. The state would have to include the last time of -# execution for a plugin. ... state could be reconstructed from the -# spool files - or simply be stored in a tie or something like that. -# -# Possible metrics that could be replayed along with the spooled output: -# (label it multigraph munin-node and get pretty graphs for free) -# Maximum slow queue depth -# Maximum fast queue depth -# Total number of scheduled executions (lifetime total) -# Total number of started executions (ditto) -# Total number of completed executions (ditto) -# Average plugin execution time -# Longest plugin execution time (lifetime) -# Longest plugin execution time last 5 minutes -# -# Plugin magic markers associated with this extention: -# #%# supportedintervals= -# Value syntax: Single: , range: , enumeration: -# Or combinations of the above. Postfixes m(inutes),h(ours) -# The loadavg plugin might be tagged #%# supportedintervals=1m,5m,15m -# A mail thruput plugin might be tagged 1m-1h. -# -# #%# defaultinterval= -# Override in the node configuration. Any plugin executed more -# often than every 5 minutes will simply be forked and executed -# without reservations about resource use ('fast' queue). Plugins -# with execution intervals of 5 minutes or more will be executed -# one at a time ('slow' queue). If no interval is given 5 minutes -# is assumed --- to match the current behaviour. -# -# #%# veryslow -# Use on plugins that us in excess of 10 seconds to execute. They -# will be executed in such a way as to not hold up the 'slow' -# queue. That is to say they will be executed and then the next -# 'slow' plugin will be executed one second later while the -# veryslow one still runs. You can have execution intervals for -# veryslow jobs shorter than 5 minutes since the 'fast' queue is -# not exclusive, but this assumes that the thing the plugin -# measures can take the stress of all the fast plugins executing -# at the same time and at once. -# -# NOTE: The same plugin for the same node will not be executed more -# than once at a time no matter what queue it is in or what the -# execution interval is. Never announce a supported interval shorter -# than (or equal to) the typical execution time of the plugin. - -# Job-description: -# pluginname => $ -# hostname => $ -# lastrun => $ (seconds since epoch) -# interval => $ (seconds) -# runtimes => @ (wallclock seconds) -# avgruntime => $ -# maxruntime => $ -# minruntime => $ -# -# If after 5 runs avgruntime is larger than interval the interval will be -# forcibly adjusted. - -# Job-record: -# pluginname => $ -# hostname => $ -# output => $ -# starttime => $ (seconds since epoch) -# - -my @alljobs; - -@alljobs = ( - { pluginname => 'exim_mailqueue', - hostname => 'localhost', - lastrun => 0, - interval => 5, - runtimes => [], - avgruntime => undef, - maxruntime => undef, - minruntime => undef }, - { pluginname => 'exim_mailstats', - hostname => 'localhost', - lastrun => 0, - interval => 30, - runtimes => [], - avgruntime => undef, - maxruntime => undef, - minruntime => undef }, - ); - -# print Dumper \@alljobs; - -my %bypluginhost; - -my $i=0; -foreach my $j (@alljobs) { -#print Dumper $j; - $bypluginhost{($j->{'pluginname'}).'/'.($j->{'hostname'})}=$i; - $i++; -} - -# Hash of the last execution time of each interval value: -my %lastexec; -# E.g., -# { 1 => 1148745002, -# 5 => 1148745000, -# 30 => 1148745000, -# 60 => 1148745000, -# 300 => 1148745000, -# 3600 => 1148742000 } - -# Hash of the next execution time of each interval value -my %nextexec; - -# The time we use for calculations at this time. Only reset after -# waking up for a new turn through the main loop. -my $thistime; -my $lasttime=0; - -# pid => plugin/hostname lookup -my %child; - -# plugin/hostname lock hash to prevent concurrent executions -my %lock; - -# Start of execution by pid -my %start; - -# Exit statuses by plugin/hostname -my %exitstatus; - -# The output of running plugins -my %outputs; - -# The log files of running plugins -my %plugins; - -# plugin/hostname is from slowboat or not? Used to determine if the -# another slow job can be executed. DELETE unused elements! -my %isslow; - -# Execution queues -my @fastlane; # Jobs listed here are just executed at once and damn the - # concequences. -my @slowboat; # Jobs listed here are executed one at a time. - - - -sub REAPER { - # Collect our children in a orderly manner. - - # See perlipc: - # - # If a second child dies while in the signal handler caused by the - # first death, we won$B!G(Bt get another signal. So must loop here - # else we will leave the unreaped child as a zombie. And the next - # time two children die we get another zombie. And so on. - - my $childpid; # Pid - my $childjob; # plugin/hostname - my $job; # Job description hash - - while (($childpid = waitpid(-1,WNOHANG)) > 0) { - warn "<--Reaping child: $childpid\n"; - if (exists($child{$childpid})) { - $childjob = $child{$childpid}; - warn "Child is: $childjob\n"; - # print Dumper \%lock; - $lock{$childjob} -= 1; - $exitstatus{$childjob} = $?; - warn "Child terminated: $childjob, pid $childpid, $?\n"; - $job=$alljobs[$bypluginhost{$childjob}]; - # Collect statistics - push(@{$job->{'runtimes'}},(time - $start{$childpid})); - if (exists($isslow{$childjob})) { - delete $isslow{$childjob}; - } - } else { - # Some other non-interesting child - } - } - $SIG{CHLD} = \&REAPER; -} - -$SIG{CHLD} = \&REAPER; - -sub initexectimes { - # Calculate the initial next execution times for each interval. - my $interval; - my $j; - foreach $j (@alljobs) { - $interval = $j->{'interval'}; - next if defined($nextexec{$interval}); - $nextexec{$interval} = int($thistime/$interval)*$interval; - # Increment by one interval if nextexec is in the past - # (it will usually be unless it's $now). - $nextexec{$interval} += $interval if $thistime>$nextexec{$interval}; - - print "Now is $thistime, interval is $interval, ne: ",$nextexec{$interval},"\n"; - } -} - -sub execute_plugin ($$) { - # Just execute them. Do associated book-keeping and return the pid. - - my ($job, # Job hash - $class)=@_; # job class ('slow', 'fast') - - # Debug support - if (!defined($job->{'pluginname'})) { - print STDERR Dumper $job; - croak("Undefined job"); - } - - my $childpid; - my $jobname = ($job->{'pluginname'}).'/'.($job->{'hostname'}); - - if ($lock{$jobname}) { - warn "Plugin $jobname already running. Skipping.\n"; - return; - } - - $childpid=fork; - - if (!defined($childpid)) { - die "Fork failed: $?"; - } - - if ($childpid) { - # Parent - # ... nothing more to do. Just return - warn "Pid of $jobname is $childpid\n"; - $child{$childpid}=$jobname; - $start{$childpid}=time; - $lock{$jobname} = 1; - $exitstatus{$jobname} = undef; - if ($class eq 'slow') { - $isslow{$jobname}=1; - } - return $childpid; - } else { - # Child - warn "-->exec(/etc/munin/plugins/".$job->{'pluginname'}.")\n"; - exec("/etc/munin/plugins/".$job->{'pluginname'}); - # HUH? - die "Yikes! Returned from execing ".$job->{'pluginname'}.": $?"; - } -} - - -sub exec_fastlane { - # Just execute everything at once. - while (my $j = pop(@fastlane)) { - execute_plugin($j,'fast'); - } -} - - -sub exec_slowboat { - # Execute one at a time - if (scalar(@slowboat) > 0 and scalar(keys %isslow) == 0) { - # FIXME: Very pseudo code: - # if ($plugin_is_veryslow($plugin)) { - # execute_plugin(pop(slowboat),'fast'); - # } else { - - execute_plugin(pop(@slowboat),'slow'); - # } - } -} - - -sub munin_run ($) { - # Well, actually, we don't run jobs here, we just queue them. - my ($job)=@_; - my $childpid; - my $jobname = $job->{'pluginname'}.'/'.$job->{'hostname'}; - - my $thejob = $alljobs[$bypluginhost{$jobname}]; - - # If the job execution interval is less than 5 minutes put it in the - # fast lane. - if ($thejob->{'interval'}<300) { - push(@fastlane,$thejob); - } else { - push(@slowboat,$thejob); - } -} - - -sub find_interval_plugins ($) { - # Execute all plugins with the given execution interval - - my($interval)=@_; - - foreach my $j (@alljobs) { - if ($j->{'interval'} == $interval) { - munin_run($j); - } - } -} - - -sub find_due_plugins { - # Execute plugins that got due since the last time. - my $i; - foreach $i (sort {$a <=> $b} keys %nextexec) { - if ($nextexec{$i} <= time) { - warn "Time to execute $i second jobs\n"; - find_interval_plugins($i); - $nextexec{$i} += $i; - } - } -} - -$thistime=time; - -initexectimes; - -while (1) { - if ($thistime != $lasttime) { - warn "Looking for due plugins\n"; - find_due_plugins; - exec_fastlane; - } - exec_slowboat; - - $lasttime=$thistime; - - sleep 1; - # Note, this sleep may be interrupted by children exiting. In that - # case it may be time for another slowboat execution, but not much - # more. - $thistime=time; - warn "Awake! Time now is ".time."\n"; -} diff -Nru munin-2.0.37/node/lib/Munin/Node/Configure/Plugin.pm munin-2.0.47/node/lib/Munin/Node/Configure/Plugin.pm --- munin-2.0.37/node/lib/Munin/Node/Configure/Plugin.pm 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/lib/Munin/Node/Configure/Plugin.pm 2019-02-28 14:43:36.000000000 +0000 @@ -76,6 +76,15 @@ # Report why it's not being used $msg = " [$self->{defaultreason}]"; } + elsif (! $self->{capabilities}->{autoconf} && ! $self->{capabilities}->{suggest}) { + $msg = " [[[ plugin has neither autoconf not suggest support ]]]"; + } + elsif ( scalar @{$self->{errors}} != 0 ) { + $msg = " [[[ plugin has errors, see below ]]]"; + } + else { + $msg = " [[[ plugin gave no reason why ]]]"; + } return $self->{default} . $msg; } @@ -135,7 +144,7 @@ { my ($self) = @_; - # no suggestions if the plugin shouldn't be installed + # no suggestions if the plugin shouldn't be installed return [] if $self->{default} ne 'yes'; if ($self->is_wildcard or $self->is_snmp) { @@ -219,8 +228,8 @@ my ($self, @response) = @_; unless (scalar(@response) == 1) { - # FIXME: not a good message - $self->log_error('Wrong amount of autoconf'); + $self->log_error('Wrong amount of autoconf: expected 1 line, got ' . scalar(@response) . ' lines:'); + $self->log_error('[start]' . join("[newline]", @response) . '[end]'); return; } @@ -229,7 +238,7 @@ unless ($line =~ /^(yes)$/ or $line =~ /^(no)(?:\s+\((.*)\))?\s*$/) { - $self->log_error("Junk printed to stdout"); + $self->log_error("Junk printed to stdout: '$line'"); return; } @@ -251,15 +260,10 @@ $self->add_suggestions($line); } else { - $self->log_error("\tBad suggestion: $line"); + $self->log_error("\tBad suggestion: '$line'"); } } - unless (@{ $self->{suggestions} }) { - $self->log_error("No valid suggestions"); - return; - } - return; } @@ -406,7 +410,7 @@ =item B Returns a string detailing whether or not autoconf considers that the plugin -should be installed. The string may also report the reason why the plugin +should be installed. The string may also report the reason why the plugin declined to be installed, or the list of suggestions it provided, if this information is available. diff -Nru munin-2.0.37/node/lib/Munin/Node/OS.pm munin-2.0.47/node/lib/Munin/Node/OS.pm --- munin-2.0.37/node/lib/Munin/Node/OS.pm 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/lib/Munin/Node/OS.pm 2019-02-28 14:43:36.000000000 +0000 @@ -247,7 +247,11 @@ } -sub set_umask { umask(0002) or croak "Unable to set umask: $!\n"; } +sub set_umask { + my $old_umask = umask(0002); + croak "Unable to set umask: $!\n" unless (defined $old_umask) and ($old_umask or ($old_umask == 0)); +} + sub mkdir_subdir { my ($class, $path, $uid) = @_; diff -Nru munin-2.0.37/node/lib/Munin/Node/ProxySpooler.pm munin-2.0.47/node/lib/Munin/Node/ProxySpooler.pm --- munin-2.0.37/node/lib/Munin/Node/ProxySpooler.pm 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/lib/Munin/Node/ProxySpooler.pm 1970-01-01 00:00:00.000000000 +0000 @@ -1,451 +0,0 @@ -package Munin::Node::ProxySpooler; - -# $Id$ - -use strict; -use warnings; - -use Net::Server::Daemonize qw( daemonize safe_fork unlink_pid_file ); -use IO::Socket; -use List::MoreUtils qw( any ); -use Time::HiRes qw( ualarm gettimeofday ); -use Carp; - -use Munin::Common::Defaults; -use Munin::Node::Logger; -use Munin::Node::SpoolWriter; - -use Munin::Node::Config; -my $config = Munin::Node::Config->instance; - - -sub new -{ - my ($class, %args) = @_; - - $args{spooldir} ||= $Munin::Common::Defaults::MUNIN_SPOOLDIR; - - $args{spool} = Munin::Node::SpoolWriter->new(spooldir => $args{spooldir}); - - # don't want to run as root unless absolutely necessary. but only root can - # change user - $args{user} = $< || $Munin::Common::Defaults::MUNIN_PLUGINUSER; - $args{group} = $( || $Munin::Common::Defaults::MUNIN_GROUP; - - $args{host} ||= 'localhost'; - $args{port} ||= '4949'; - - return bless \%args, $class; -} - - -sub run -{ - my ($class, %args) = @_; - - my $self = __PACKAGE__->new(%args); - - croak "No pidfile specified" unless $args{pid_file}; - - # Daemonzises, and runs for cover. - daemonize($self->{user}, $self->{group}, $self->{pid_file}); - $self->{have_pid_file}++; - - open STDERR, '>>', "$Munin::Common::Defaults::MUNIN_LOGDIR/munin-sched.log"; - STDERR->autoflush(1); - # FIXME: reopen logfile on SIGHUP - - logger('Spooler starting up'); - - # Indiscriminately kill every process in the group with SIGTERM when asked - # to quit. this is just the list of signals the Perl Cookbook suggests - # trapping. - # - # FIXME: might be better if this was implemented with sigtrap pragma. - # - # !!!NOTE!!! this should always be the same list as the one down there in - # _launch_single_poller() - $SIG{INT} = $SIG{TERM} = $SIG{HUP} = sub { - logger("Spooler caught SIG$_[0]. Shutting down"); - kill -15 => $$; - - if ($self->{have_pid_file}) { - logger('Removing pidfile') if $config->{DEBUG}; - unlink_pid_file($self->{pid_file}); - } - - exit 0; - }; - - $self->_launch_pollers(); - - logger('Spooler going to sleep'); - - # Reap any dead pollers - while (my $deceased = wait) { - if ($deceased < 0) { - last if $!{ECHILD}; # all the children are dead! - - logger("wait() error: $!"); - next; - } - - $self->_restart_poller($deceased); - } - - logger('Spooler shutting down'); - exit 0; -} - - -### SETUP ###################################################################### - -# queries the node for a list of services, and works out how often each one -# should be checked -sub _get_intervals -{ - my ($self) = @_; - - my %intervals; - - $self->_open_node_connection; - - my @services = $self->_get_service_list() or die "No services\n"; - - foreach my $service (@services) { - if (my $interval = $config->{sconf}{$service}{update_rate}) { - logger("Setting interval for service '$service' from config") - if $config->{DEBUG}; - $intervals{$service} = $interval; - next; - } - else { - logger("Fetching interval for service '$service' from node") - if $config->{DEBUG}; - $intervals{$service} = $self->_service_interval( - $self->_talk_to_node("config $service") - ); - } - logger("Interval is $intervals{$service} seconds") if $config->{DEBUG}; - } - - $self->_close_node_connection; - - $self->{intervals} = \%intervals; - - return \%intervals; -} - - -# gets a list of all the nodes served by that node -sub _get_node_list { return (shift)->_talk_to_node('nodes'); } - - -# gets a list of every service on every node -sub _get_service_list -{ - my ($self) = @_; - my @services; - - my @nodes = $self->_get_node_list() or die "No nodes\n"; - - foreach my $node (@nodes) { - logger("Fetching services for node $node") if $config->{DEBUG}; - my $service_list = $self->_talk_to_node("list $node"); - - if ($service_list) { - logger("Got services $service_list") if $config->{DEBUG}; - push @services, split / /, $service_list; - } - else { - logger("No services for $node") if $config->{DEBUG}; - } - } - - return @services; -} - - -# takes the config response for the service, and returns the correct interval -sub _service_interval { /^update_rate (\d+)/ && return $1 foreach @_; return 300; } - - -#### GATHER DATA ############################################################### - -# forks off a child for each process on the node, and sets them to work. -sub _launch_pollers -{ - my ($self) = @_; - - my %pollers; - - my $intervals = $self->_get_intervals(); - - while (my ($service, $interval) = each %$intervals) { - my $poller_pid = $self->_launch_single_poller($service, $interval); - } - - return; -} - - -sub _launch_single_poller -{ - my ($self, $service, $interval) = @_; - - logger("Launching poller for '$service' with an interval of ${interval}s") - if $config->{DEBUG}; - - if (my $poller_pid = safe_fork()) { - logger("Poller for '$service' running with pid $poller_pid") - if $config->{DEBUG}; - - $self->{pollers}{$poller_pid} = $service; - - return; - } - - # don't want the pollers to have the kill-all-the-process-group handler - # installed. !!!NOTE!!! this should always be the same list as the one up - # there in run() - delete @SIG{qw( INT TERM HUP )}; - - $0 .= " [$service]"; - - # Fetch data - _poller_loop($interval, sub { - logger(sprintf "%s: %d %d", $service, gettimeofday); # FIXME: for testing timing accuracy - - my @result = $self->_fetch_service($service); - logger("Read " . scalar @result . " lines from $service") - if $config->{DEBUG}; - - $self->{spool}->write(time, $service, \@result); - }); - - exit 0; -} - - -# calls coderef $code every $interval seconds. -sub _poller_loop -{ - my ($interval, $code) = @_; - - $interval *= 1e6; # it uses microseconds. - - # sleep a random amount. should help spread the load up a bit. - # then run $code every $interval seconds. - # - # FIXME: this will interact really really badly with any code that uses - # sleep(). - $SIG{ALRM} = $code; - ualarm(rand($interval), $interval); - - while (1) { sleep; } - - ualarm(0); - - return; -} - - -# connect to the node, fetch data, write it out to the spooldir. -sub _fetch_service -{ - my ($self, $service) = @_; - - $self->_open_node_connection; - - my @config = $self->_talk_to_node("config $service"); - push @config, $self->_talk_to_node("fetch $service") - unless any {/\.value /} @config; - - $self->_close_node_connection; - - if (any { m{# (?:Timed out|Unknown service|Bad exit)} } @config) { - return (); - } - - return @config; -} - - -# takes the PID of a dead poller, and respawns it. -sub _restart_poller -{ - my ($self, $pid) = @_; - - my $service = delete $self->{pollers}{$pid}; - - my $exit = ($? >> 8); - my $signal = ($? & 127); - logger("Poller $pid ($service) exited with $exit/$signal"); - - # avoid restarting the poller if it was last restarted too recently. - if (time - ($self->{poller_restarted}{$service} || 0) < 10) { - logger("Poller for '$service' last restarted at $self->{poller_restarted}{$service}. Giving up."); - return; - } - - # Respawn the poller - logger("Respawning poller for '$service'"); - $self->_launch_single_poller($service, $self->{intervals}{$service}); - $self->{poller_restarted}{$service} = time; - - return; -} - -### NODE INTERACTION ########################################################### - -# returns an open IO::Socket to the node, ready for reading. -sub _open_node_connection -{ - my ($self) = @_; - - logger("Opening connection to $self->{host}:$self->{port}") - if $config->{DEBUG}; - - $self->{socket} = IO::Socket::INET->new( - PeerAddr => $self->{host}, - PeerPort => $self->{port}, - Proto => 'tcp', - ) or die "Failed to connect to node on $self->{host}:$self->{port}: $!\n"; - - my $line = $self->_read_line or die "Failed to read banner\n"; - - die "Service is not a Munin node (responded with '$line')\n" - unless ($line =~ /^# munin node at /); - - # report capabilities to unlock all the special services - $line = $self->_talk_to_node('cap multigraph dirtyconfig') - or die "Failed to read node capabilities\n"; - - return; -} - - -# closes the socket, and deletes it from the instance hash. -sub _close_node_connection { (delete $_[0]->{socket})->close; } - - -# prints $command to the node on $socket, and returns the response. -sub _talk_to_node -{ - my ($self, $command) = @_; - - my $multiline = ($command =~ m{^(?:nodes|config|fetch)}); - - croak "multiline means scalar context" if $multiline and not wantarray; - - my $socket = $self->{socket}; - - $self->_write_line($command); - my @response = ($multiline) ? $self->_read_multiline() : $self->_read_line(); - - return wantarray ? @response : shift @response; -} - - -# write a single line to the node -sub _write_line -{ - my ($self, $command) = @_; - - logger("DEBUG: > $command") if $config->{DEBUG}; - $self->{socket}->print($command, "\n") or die "Write error to socket: $!\n"; - - return; -} - - -# read a single line from the node -sub _read_line -{ - my ($self) = @_; - - my $line = $self->{socket}->getline; - defined($line) or die "Read error from socket: $!\n"; - chomp $line; - logger("DEBUG: < $line") if $config->{DEBUG}; - - return $line; -} - - -# read a multiline response from the node (ie. up to but not including the -# '.' line at the end. -sub _read_multiline -{ - my ($self) = @_; - my ($line, @response); - - push @response, $line until ($line = $self->_read_line) eq '.'; - - return @response; -} - - -1; - -__END__ - -=head1 NAME - -Munin::Node::ProxySpooler - Daemon to gather spool information by querying a -munin-node instance. - -=head1 SYNOPSIS - - Munin::Node::ProxySpooler->run(spooldir => '/var/spool/munin'); - # never returns. - - # meanwhile, in another process - my $spoolreader = Munin::Node::Spoolreader->new( - spooldir => '/var/spool/munin', - ); - print $spoolreader->fetch(123456789); - -=head1 METHODS - -=over 4 - -=item B - - Munin::Node::ProxySpooler->new(%args); - -Constructor. It is called automatically by the C method, so probably -isn't of much use otherwise. - -=item B - - Munin::Node::ProxySpooler->run(%args); - -Daemonises the current process, and starts fetching data from a Munin node. - -Never returns. The process will clean up and exit(0) upon receipt of SIGINT, -SIGTERM or SIGHUP. - -=over 8 - -=item C - -The directory to write results to. Optional. - -=item C, C - -The host and port the spooler will gather results from. Defaults to -C and C<4949> respectively, which should be acceptable for most -purposes. - -=item C - -The pidfile to use. Required. - -=back - -=back - -=cut - -# vim: sw=4 : ts=4 : et diff -Nru munin-2.0.37/node/lib/Munin/Node/Server.pm munin-2.0.47/node/lib/Munin/Node/Server.pm --- munin-2.0.37/node/lib/Munin/Node/Server.pm 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/lib/Munin/Node/Server.pm 2019-02-28 14:43:36.000000000 +0000 @@ -153,6 +153,15 @@ } +# This method is used by Net::Server for retrieving default values (in case they are not specified +# in the given "conf_file"). +sub default_values { + return { + port => 4949, + }; +} + + sub _process_command_line { my ($session, $cmd_line) = @_; diff -Nru munin-2.0.37/node/lib/Munin/Node/Service.pm munin-2.0.47/node/lib/Munin/Node/Service.pm --- munin-2.0.37/node/lib/Munin/Node/Service.pm 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/lib/Munin/Node/Service.pm 2019-02-28 14:43:36.000000000 +0000 @@ -24,8 +24,8 @@ # Set defaults $args{servicedir} ||= "$Munin::Common::Defaults::MUNIN_CONFDIR/plugins"; - $args{defuser} ||= getpwnam $Munin::Common::Defaults::MUNIN_PLUGINUSER; - $args{defgroup} ||= getgrnam $Munin::Common::Defaults::MUNIN_GROUP; + $args{defuser} = getpwnam $Munin::Common::Defaults::MUNIN_PLUGINUSER unless defined($args{defuser}); + $args{defgroup} = getgrnam $Munin::Common::Defaults::MUNIN_GROUP unless defined($args{defgroup}); $args{timeout} ||= 60; # Default transaction timeout : 1 min $args{pidebug} ||= 0; @@ -98,6 +98,12 @@ # LC_ALL should be enough, but some plugins don't follow specs (#1014) $ENV{LANG} = 'C'; + # Force UTF-8 encoding for stdout in Python3. This is only relevant for + # Python3 before 3.7 (which will use UTF-8 anyway, if possible). + # This override allows python3-based plugins as well as any indrectly + # executed python3-based commands to output UTF-8 characters. + $ENV{PYTHONIOENCODING} = 'utf8:replace'; + # PATH should be *very* sane by default. Can be overrided via # config file if needed (Closes #863 and #1128). $ENV{PATH} = '/usr/sbin:/usr/bin:/sbin:/bin'; diff -Nru munin-2.0.37/node/lib/Munin/Node/SNMPConfig.pm munin-2.0.47/node/lib/Munin/Node/SNMPConfig.pm --- munin-2.0.37/node/lib/Munin/Node/SNMPConfig.pm 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/lib/Munin/Node/SNMPConfig.pm 2019-02-28 14:43:36.000000000 +0000 @@ -23,6 +23,7 @@ my $version = $opts{version} || '2c'; my $port = $opts{port} || 161; + my $domain = $opts{domain} || 'udp'; if ($version eq '3') { # Privacy @@ -58,6 +59,7 @@ hosts => $hosts, port => $port, version => $version, + domain => $domain, sec_args => \%sec_args, ); @@ -88,6 +90,7 @@ -hostname => $host, -port => $self->{port}, -version => $self->{version}, + -domain => $self->{domain}, %{$self->{sec_args}}, @@ -295,6 +298,12 @@ The community string to use for SNMP version 1 or 2c. Default is 'public'. +=item domain + +The Transport Domain to use for exchanging SNMP messages. The default +is UDP/IPv4. Possible values: 'udp', 'udp4', 'udp/ipv4'; 'udp6', +'udp/ipv6'; 'tcp', 'tcp4', 'tcp/ipv4'; 'tcp6', 'tcp/ipv6'. + =item username The SNMPv3 username to use. diff -Nru munin-2.0.37/node/sbin/munin-node-configure munin-2.0.47/node/sbin/munin-node-configure --- munin-2.0.37/node/sbin/munin-node-configure 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/sbin/munin-node-configure 2019-02-28 14:43:36.000000000 +0000 @@ -84,9 +84,8 @@ my $debug = 0; my $pidebug = 0; my ($suggest, $shell, $removes, $newer); - my $exit_not_error = 1; my @families; - my (@snmp_hosts, $snmpver, $snmpcomm, $snmpport); + my (@snmp_hosts, $snmpver, $snmpcomm, $snmpport, $snmpdomain); my ($snmp3username, $snmp3authpass, $snmp3authproto, $snmp3privpass, $snmp3privproto); print_usage_and_exit() unless GetOptions( @@ -94,7 +93,6 @@ 'version' => \&print_version_and_exit, 'suggest!' => \$suggest, - 'exitnoterror!' => \$exit_not_error, 'newer=s' => \$newer, 'shell!' => \$shell, @@ -114,6 +112,7 @@ 'snmp=s' => \@snmp_hosts, 'snmpversion=s' => \$snmpver, 'snmpport=i' => \$snmpport, + 'snmpdomain=s' => \$snmpdomain, # SNMPv1/2c 'snmpcommunity=s' => \$snmpcomm, # SNMPv3 @@ -142,6 +141,7 @@ hosts => \@snmp_hosts, version => $snmpver, port => $snmpport, + domain => $snmpdomain, community => $snmpcomm, @@ -165,7 +165,6 @@ $config->reinitialize({ %$config, - exit_not_error => $exit_not_error, suggest => $suggest, shell => $shell, @@ -351,13 +350,8 @@ } elsif ($plugin_exit) { $plugin->log_error("Non-zero exit during $mode ($plugin_exit)"); + return; - # Verboten according to the specification, but lots of plugins - # still exit(1) it during autoconf. So making it a non-fatal error - # for the time being - return unless ($mode eq 'autoconf' - and $plugin_exit == 1 - and $config->{exit_not_error}); } } @@ -369,8 +363,9 @@ } # Ignore debug output - my @response = grep !/^#/, @{ $res->{stdout} }; - $plugin->log_error('Nothing printed to stdout') unless (scalar @response); + my @response = grep !/^#/, @{ $res->{stdout} }; + # Error out on empty response except in suggest mode + $plugin->log_error('Nothing printed to stdout') unless (scalar @response || $mode eq 'suggest'); return @response; } @@ -465,7 +460,7 @@ to install the plugins. -=head1 GENERAL OPTIONS +=head1 OPTIONS =over 4 @@ -584,6 +579,12 @@ The SNMP port to use [161] +=item B<< --snmpdomain >> + +The Transport Domain to use for exchanging SNMP messages. The default +is UDP/IPv4. Possible values: 'udp', 'udp4', 'udp/ipv4'; 'udp6', +'udp/ipv6'; 'tcp', 'tcp4', 'tcp/ipv4'; 'tcp6', 'tcp/ipv6'. + =item B SNMP versions 1 and 2c use a "community string" for authentication. This is diff -Nru munin-2.0.37/node/sbin/munin-sched munin-2.0.47/node/sbin/munin-sched --- munin-2.0.37/node/sbin/munin-sched 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/sbin/munin-sched 1970-01-01 00:00:00.000000000 +0000 @@ -1,230 +0,0 @@ -#!/usr/bin/perl -wT -# -*- cperl -*- -# -# Copyright (C) 2002-2010 Audun Ytterdal, Jimmy Olsen, Tore Anderson, -# Nicolai Langfeldt, Matthew Boyle -# -# This program 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; version 2 dated June, -# 1991. -# -# This program 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 program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# $Id$ -# - -use strict; -use warnings; - -# Trust PERL5LIB from environment -use lib map { /(.*)/ } split(/:/, ($ENV{PERL5LIB} || '')); - -use Getopt::Long; - -use Munin::Common::Defaults; -use Munin::Node::Config; -use Munin::Node::ProxySpooler; - -my $servicedir; -my $sconfdir = "$Munin::Common::Defaults::MUNIN_CONFDIR/plugin-conf.d"; -my $conffile = "$Munin::Common::Defaults::MUNIN_CONFDIR/munin-node.conf"; -my $spooldir = $Munin::Common::Defaults::MUNIN_SPOOLDIR; - -my ($host, $port); - -my $DEBUG = 0; -my $paranoia = 0; - - -sub main -{ - chdir ("/"); - - # "Clean" environment to disable taint-checking on the environment. We _know_ - # that the environment is insecure, but we want to let admins shoot themselves - # in the foot with it, if they want to. - foreach my $key (keys %ENV) { - $ENV{$key} =~ /^(.*)$/; - $ENV{$key} = $1; - } - - $0 =~ /^(.*)$/; - $0 = $1; - - parse_args(); - - my $config = Munin::Node::Config->instance(); - $config->parse_config_from_file($conffile); - - $paranoia = $config->{paranoia} if defined $config->{paranoia}; - - $host ||= $config->{sconf}{host} unless ($config->{sconf}{host} eq '*'); - $port ||= $config->{sconf}{port} if $config->{sconf}{port}; - - $config->reinitialize({ - DEBUG => $DEBUG, - paranoia => $paranoia, - }); - - Munin::Node::ProxySpooler->run( - spooldir => $spooldir, - host => $host, - port => $port, - - syslog_ident => 'munin-sched', - conf_file => $conffile, - pid_file => "$Munin::Common::Defaults::MUNIN_STATEDIR/munin-sched.pid" - ); - - return 0; -} - - -sub parse_args -{ - my @ORIG_ARGV = @ARGV; - - print_usage_and_exit() unless GetOptions( - 'host=s' => \$host, - 'port=i' => \$port, - - "config=s" => \$conffile, - - "debug!" => \$DEBUG, - "paranoia!" => \$paranoia, - - "version" => \&print_version_and_exit, - "help" => \&print_usage_and_exit, - ); - - ($host) = ($host =~ m{([-\w.]+)}) if $host; - ($port) = ($port =~ m{(\d+)}) if $port; - - # Reset ARGV (for HUPing) - @ARGV = @ORIG_ARGV; - - return; -} - - -sub print_usage_and_exit -{ - require Pod::Usage; - Pod::Usage::pod2usage(-verbose => 1); -} - - -sub print_version_and_exit -{ - require Pod::Usage; - Pod::Usage::pod2usage( - -verbose => 99, - -sections => 'VERSION|COPYRIGHT', - ); -} - - -exit main() unless caller; - - -1; - -__END__ - -=head1 NAME - -munin-sched - A daemon to gather information in cooperation with the main -Munin program - -=head1 SYNOPSIS - -munin-sched [--options] - -=head1 DESCRIPTION - -munin-sched is a daemon for reporting statistics on system performance. - -It doesn't produce these itself, but instead relies on a number of plugins -which are responsible for gathering the data they require, and -describing how this should be graphed. In fact, it does little more than -fielding requests from the Munin master, running the appropriate plugins, -and returning the output they produce. - -=head1 OPTIONS - -=over 5 - -=item B<< --config >> - -Use EfileE as configuration file. [@@CONFDIR@@/munin-node.conf] - -=item B< --[no]paranoia > - -Only run plugins owned by root. Check permissions as well. [--noparanoia] - -=item B< --help > - -View this help message. - -=item B< --debug > - -View debug messages. This can be very verbose. - -=back - -=head1 FILES - - @@CONFDIR@@/munin-node.conf - @@CONFDIR@@/plugins/* - @@CONFDIR@@/plugin-conf.d/* - @@STATEDIR@@/munin-sched.pid - @@LOGDIR@@/munin-sched.log - -=head1 VERSION - -This is munin-sched v@@VERSION@@ - -$Id$ - -=head1 AUTHORS - -Audun Ytterdal, Jimmy Olsen, and Tore Anderson. - -=head1 BUGS - -Please see L. - -=head1 COPYRIGHT - -Copyright (C) 2002-2006 Audun Ytterdal, Jimmy Olsen, and Tore Anderson / Linpro AS. - -This is free software; see the source for copying conditions. There is -NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. - -This program is released under the GNU General Public License - -=head1 SEE ALSO - -For information on configuration options, please refer to the man page for -F. - -Many plugins can report whether or not they can reasonably be used on the -node. C can use this information to help manage -installed plugins. - -The network protocol is documented at -L - - -=cut - -# vim: sw=4 : ts=4 : expandtab diff -Nru munin-2.0.37/node/t/munin_node_configure_hostenumeration.t munin-2.0.47/node/t/munin_node_configure_hostenumeration.t --- munin-2.0.37/node/t/munin_node_configure_hostenumeration.t 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/t/munin_node_configure_hostenumeration.t 2019-02-28 14:43:36.000000000 +0000 @@ -13,9 +13,9 @@ ### resolve { my @tests = ( - [ 'munin-monitoring.org', 'Resolve IPv4 hostname' ], + [ 'localhost', 'Resolve IPv4 hostname' ], [ '127.0.0.1', 'Resolve IPv4 numeric address' ], -# [ 'ipv6.google.com', 'Resolve IPv6 hostname' ], +# [ 'ip6-localhost', 'Resolve IPv6 hostname' ], # [ '::1', 'Resolve IPv6 numeric address' ], ); diff -Nru munin-2.0.37/node/t/munin_node_configure_plugin.t munin-2.0.47/node/t/munin_node_configure_plugin.t --- munin-2.0.37/node/t/munin_node_configure_plugin.t 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/t/munin_node_configure_plugin.t 2019-02-28 14:43:36.000000000 +0000 @@ -238,7 +238,7 @@ $p->parse_autoconf_response('no'); is( $p->suggestion_string, - 'no', + 'no [[[ plugin has neither autoconf not suggest support ]]]', 'Suggestion string - no' ); } @@ -268,7 +268,7 @@ $p->parse_autoconf_response('no'); is( $p->suggestion_string, - 'no', + 'no [[[ plugin has neither autoconf not suggest support ]]]', 'Suggestion string - no' ); } diff -Nru munin-2.0.37/node/t/munin_node_os.t munin-2.0.47/node/t/munin_node_os.t --- munin-2.0.37/node/t/munin_node_os.t 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/t/munin_node_os.t 2019-02-28 14:43:36.000000000 +0000 @@ -1,7 +1,7 @@ use warnings; use strict; -use Test::More tests => 29; +use Test::More tests => 28; use Test::LongString; use Config; # for signal numbers and names @@ -40,10 +40,8 @@ ### get_fq_hostname -{ - ok($os->get_fq_hostname, 'Was able to establish the FQDN'); - isnt(index($os->get_fq_hostname, '.'), -1, 'FQDN contains at least one dot'); -} +# probably there is no good way to test it, since we cannot expect a certain host setup +# (e.g. "test for a dot in the FQDN" fails in the Debian reproducibility test environment) ### check_perms_if_paranoid @@ -129,10 +127,19 @@ ### possible_to_signal_process { ok( $os->possible_to_signal_process($$), 'can send a signal to ourselves'); - ok(! $os->possible_to_signal_process(1), 'cannot signal to init'); ok(! $os->possible_to_signal_process(999999), 'cannot signal non-existant process'); } +SKIP: { + skip "Test assumes that the user is not root", 1 if $REAL_USER_ID == 0; + ok(! $os->possible_to_signal_process(1), 'cannot signal to init'); +} + +SKIP: { + skip "Test assumes that the user is root", 1 if $REAL_USER_ID != 0; + ok($os->possible_to_signal_process(1), 'can signal to init'); +} + ### set_effective_user_id ### set_real_user_id ### set_effective_group_id @@ -140,8 +147,8 @@ SKIP: { skip "Need to be run with sudo", 2 if $REAL_USER_ID != 0; - my $login = getpwnam $ENV{SUDO_USER}; - die "Test assumes that the user logged in on the controlling terminal is not root" if $login == 0; + my $login = defined($ENV{SUDO_USER}) ? getpwnam $ENV{SUDO_USER} : 0; + skip "Test assumes that the user logged in on the controlling terminal is not root", 2 if $login == 0; $os->set_effective_user_id($login); is($EFFECTIVE_USER_ID, $login, "Changed effective UID"); diff -Nru munin-2.0.37/node/t/munin_node_proxyspooler.t munin-2.0.47/node/t/munin_node_proxyspooler.t --- munin-2.0.37/node/t/munin_node_proxyspooler.t 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/t/munin_node_proxyspooler.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,388 +0,0 @@ -# vim: sw=4 : ts=4 : et -use warnings; -use strict; - -use Test::More tests => 32; -use Test::Differences; -use Test::Deep; - -use IO::Scalar; -use POSIX (); -use Data::Dumper; -use Time::HiRes qw( tv_interval gettimeofday ualarm ); -use File::Temp qw( tempdir ); - -use Munin::Node::ProxySpooler; - -$Munin::Common::Defaults::MUNIN_SPOOLDIR = tempdir(CLEANUP => 1); - -# the hostname and port of a node to test against. -my ($host, $port) = @ENV{qw( MUNIN_HOST MUNIN_PORT )}; - - -### new -{ - my $spooler = new_ok 'Munin::Node::ProxySpooler' => [ ], 'no arguments' or next; - cmp_deeply([ keys %$spooler ], superbagof(qw( spooldir spool user group port )), 'constructor sets defaults'); - isa_ok($spooler->{spool}, 'Munin::Node::SpoolWriter', 'SpoolWriter object was created'); -} -{ - my $spooldir = POSIX::getcwd(); - - my $spooler = new_ok 'Munin::Node::ProxySpooler' => [ - spooldir => $spooldir, - ], 'spooldir provided' or next; - - is($spooler->{spooldir}, $spooldir, 'custom spooldir is being used'); - isa_ok($spooler->{spool}, 'Munin::Node::SpoolWriter', 'SpoolWriter object was created'); - is($spooler->{spool}->{spooldir}, $spooldir, 'SpoolWriter object is using the spooldir'); -} - - -### NODE INTERACTION ########################################################### - -### _open_node_connection -### _close_node_connection -SKIP: { - skip 'Set MUNIN_HOST and MUNIN_PORT environment variables to the hostname and port of a node to test against', 2 - unless $host and $port; - - my $spooler = Munin::Node::ProxySpooler->new( - host => $host, - port => $port, - ) or next; - - $spooler->_open_node_connection; - - my $socket = $spooler->{socket}; - - print $socket "version\n"; - like(scalar(<$socket>), qr{version}, 'was able to read the version string'); - - $spooler->_close_node_connection; - ok(! exists($spooler->{socket}), 'Socket was deleted'); -} - - -### _talk_to_node -SKIP: { - skip 'Set MUNIN_HOST and MUNIN_PORT environment variables to the hostname and port of a node to test against', 1 - unless $host and $port; - - my $spooler = Munin::Node::ProxySpooler->new( - host => $host, - port => $port, - ) or next; - - $spooler->_open_node_connection; - - eval { my $scalar = $spooler->_talk_to_node('nodes') }; - like($@, qr{scalar}, 'error if expecting a multiline response, but called in a scalar context'); -} -SKIP: { - skip 'Set MUNIN_HOST and MUNIN_PORT environment variables to the hostname and port of a node to test against', 1 - unless $host and $port; - - my $spooler = Munin::Node::ProxySpooler->new( - host => $host, - port => $port, - ) or next; - - $spooler->_open_node_connection; - - my $socket = $spooler->{socket}; - - like($spooler->_talk_to_node('version'), qr{version}, 'was able to read the version string'); -} - - -### _write_line -{ - my $spooler = Munin::Node::ProxySpooler->new() or next; - - $spooler->{socket} = IO::Scalar->new(\(my $sent)); - - $spooler->_write_line('line of text to write'); - is($sent, "line of text to write\n", 'Line was written to the socket, with a newline on the end'); -} - - -### _read_line -{ - my $spooler = Munin::Node::ProxySpooler->new() or next; - - $spooler->{socket} = IO::Scalar->new(\"line of text to read\n"); - - eq_or_diff( - [ $spooler->_read_line() ], - [ 'line of text to read' ], - 'read a single line from the socket, which was chomped' - ); -} - - -### _read_multiline -{ - my $spooler = Munin::Node::ProxySpooler->new() or next; - - $spooler->{socket} = IO::Scalar->new(\<_read_multiline() ], - [ qw( - node1.example.com - node2.example.com - ) ], - 'read a multiline response from the socket, but not the . that marks the end' - ); -} - - -### SETUP ###################################################################### - -### _service_interval -{ - my @config = ( - 'graph_title CPU usage', - 'graph_order system user nice idle iowait irq softirq', - 'graph_args --base 1000 -r --lower-limit 0 --upper-limit 200', - 'system.label system', - ); - is(Munin::Node::ProxySpooler::_service_interval(@config), 300, 'Default interval is 5 minutes'); -} -{ - my @config = ( - 'graph_title CPU usage', - 'graph_order system user nice idle iowait irq softirq', - 'graph_args --base 1000 -r --lower-limit 0 --upper-limit 200', - - 'update_rate 86400', - - 'system.label system', - ); - is(Munin::Node::ProxySpooler::_service_interval(@config), 86400, 'Can override the default interval'); -} - - -### _get_node_list -SKIP: { - skip 'Set MUNIN_HOST and MUNIN_PORT environment variables to the hostname and port of a node to test against', 1 - unless $host and $port; - - my $spooler = Munin::Node::ProxySpooler->new( - host => $host, - port => $port, - ) or next; - - $spooler->_open_node_connection; - - cmp_deeply([ $spooler->_get_node_list ], array_each(re('^[-\w.:]+$')), 'all the node names look reasonable'); -} - - -### _get_service_list -SKIP: { - skip 'Set MUNIN_HOST and MUNIN_PORT environment variables to the hostname and port of a node to test against', 2 - unless $host and $port; - - my $spooler = Munin::Node::ProxySpooler->new( - host => $host, - port => $port, - ) or next; - - $spooler->_open_node_connection; - - my @services = $spooler->_get_service_list(); - ok(\@services, 'Got a list of services from the node') or next; - - cmp_deeply(\@services, array_each(re('^[-\w.:]+$')), 'all the services look reasonable'); -} - - -### _get_intervals -SKIP: { - skip 'Set MUNIN_HOST and MUNIN_PORT environment variables to the hostname and port of a node to test against', 2 - unless $host and $port; - - my $spooler = Munin::Node::ProxySpooler->new( - host => $host, - port => $port, - ) or next; - - my $intervals = $spooler->_get_intervals() or next; - - cmp_deeply([ keys %$intervals ], array_each(re('^[-\w.:]+$')), 'all the keys look like services'); - cmp_deeply([ values %$intervals ], array_each(re('^\d+$')), 'all the values look like times'); -} -{ - my $spooler = Munin::Node::ProxySpooler->new(); - - my $config = Munin::Node::Config->instance(); - $config->reinitialize({ sconf => { fnord => { update_rate => 100 } } }); - - no warnings; - local *Munin::Node::ProxySpooler::_open_node_connection = sub {}; - local *Munin::Node::ProxySpooler::_close_node_connection = sub {}; - - local *Munin::Node::ProxySpooler::_get_service_list = sub { 'fnord' }; - use warnings; - - is_deeply($spooler->_get_intervals, { fnord => 100 }, 'Can override the interval through the config'); -} - - -### GATHER DATA ################################################################ - - -### _poller_loop -{ - my $ii = 10; - my @times; - my $poller = sub { - if ($ii-- < 0) { - ualarm(0); - die; - } - push @times, [gettimeofday]; - }; - - eval { Munin::Node::ProxySpooler::_poller_loop(0.01, $poller) }; - - my $last = shift @times; - my @intervals = map { my $interval = tv_interval($last, $_), $last = $_; $interval } @times; - - cmp_deeply(\@intervals, array_each(num(0.01, 0.005)), 'Callback takes less long than the interval'); -} -{ - my $ii = 10; - my @times; - - my $poller = sub { - if ($ii-- < 0) { - ualarm(0); - die; - } - push @times, [gettimeofday]; - select(undef, undef, undef, 0.5); # sleep without sleep()ing. - }; - - eval { Munin::Node::ProxySpooler::_poller_loop(0.3, $poller) }; - - my $last = shift @times; - my @intervals = map { my $interval = tv_interval($last, $_), $last = $_; $interval } @times; - - cmp_deeply(\@intervals, array_each( - any( - num(0.5, 0.005), - num(0.5 + 0.3, 0.005), - ) - ), 'Callback takes longer than the interval'); -} -{ - my $ii = 10; - my @times; - - my $poller = sub { - if ($ii-- < 0) { - ualarm(0); - die; - } - push @times, [gettimeofday]; - select(undef, undef, undef, 0.1); # sleep without sleep()ing. - }; - - eval { Munin::Node::ProxySpooler::_poller_loop(0.1, $poller) }; - - my $last = shift @times; - my @intervals = map { my $interval = tv_interval($last, $_), $last = $_; $interval } @times; - - cmp_deeply(\@intervals, array_each( - any( - num(0.1, 0.005), - num(0.1 + 0.1, 0.005), - ) - ), 'Callback takes about the same time as interval'); -} - - -### _fetch_service -{ - my @config = ( - 'graph_title Load average', - 'graph_category system', - 'load.label load', - ); - my @fetch = ( - 'load.value 0.25', - ); - my @timeout = ( - '# Timed out', - ); - my @unknown = ( - '# Unknown service', - ); - my @badexit = ( - '# Bad exit', - ); - - no warnings; - local *Munin::Node::ProxySpooler::_open_node_connection = sub {}; - local *Munin::Node::ProxySpooler::_close_node_connection = sub {}; - - local *Munin::Node::ProxySpooler::_talk_to_node = sub { - return $_[1] eq 'config normal' ? @config - : $_[1] eq 'fetch normal' ? @fetch - - : $_[1] eq 'config dirty' ? (@config, @fetch) - : $_[1] eq 'fetch dirty' ? ('no need to fetch a dirty plugin') - - : $_[1] eq 'config timeout' ? @timeout - : $_[1] eq 'fetch timeout' ? ('should not fetch a plugin that timed out') - - : $_[1] eq 'config timeout2' ? @config - : $_[1] eq 'fetch timeout2' ? @timeout - - : $_[1] eq 'config unknown' ? @unknown - : $_[1] eq 'fetch unknown' ? ('should not fetch a plugin that does not exist') - - : $_[1] eq 'config badexit' ? @badexit - : $_[1] eq 'fetch badexit' ? ('should not fetch a plugin that fell over during config') - - : $_[1] eq 'config badexit2' ? @config - : $_[1] eq 'fetch badexit2' ? @badexit - - : die "unknown command $_[1]\n"; - }; - use warnings; - - my @tests = ( - # name, expected, message - [ 'normal', [ @config, @fetch ], 'normal service' ], - - [ 'dirty', [ @config, @fetch ], 'dirty service' ], - - [ 'timeout', [], 'timed out during config' ], - [ 'timeout2', [], 'timed out during fetch' ], - - [ 'unknown', [], 'unknown service' ], - - [ 'badexit', [], 'bad exit from service during config' ], - [ 'badexit2', [], 'bad exit during fetch' ], - ); - - foreach my $test (@tests) { - my ($name, $expected, $msg) = @$test; - - my $spooler = Munin::Node::ProxySpooler->new() - or fail('Could not create a new ProxySpooler'); - - my @response = $spooler->_fetch_service($name); - eq_or_diff(\@response, $expected, $msg); - } -} - - diff -Nru munin-2.0.37/node/t/munin_node_snmpconfig.t munin-2.0.47/node/t/munin_node_snmpconfig.t --- munin-2.0.37/node/t/munin_node_snmpconfig.t 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/node/t/munin_node_snmpconfig.t 2019-02-28 14:43:36.000000000 +0000 @@ -23,6 +23,7 @@ hosts => \@hosts, port => '161', version => '2c', + domain => 'udp', sec_args => { -community => 'public', }, @@ -36,12 +37,13 @@ hosts => \@hosts, version => '1', port => '162', - + domain => 'udp', community => 'fnord', ), { hosts => \@hosts, port => '162', + domain => 'udp', version => '1', sec_args => { -community => 'fnord', @@ -56,12 +58,13 @@ hosts => \@hosts, version => '2c', port => '161', - + domain => 'udp', community => 'fnord', ), { hosts => \@hosts, port => '161', + domain => 'udp', version => '2c', sec_args => { -community => 'fnord', @@ -76,12 +79,13 @@ hosts => \@hosts, version => '3', port => '162', - + domain => 'udp', username => 'jeff', ), { hosts => \@hosts, port => '162', + domain => 'udp', version => '3', sec_args => { -username => 'jeff', @@ -96,13 +100,14 @@ hosts => \@hosts, version => '3', port => '162', - + domain => 'udp', username => 'jeff', authpassword => 'swordfish', ), { hosts => \@hosts, port => '162', + domain => 'udp', version => '3', sec_args => { -username => 'jeff', @@ -117,7 +122,7 @@ hosts => \@hosts, version => '3', port => '162', - + domain => 'udp', username => 'jeff', authpassword => 'swordfish', authprotocol => 'sha', @@ -125,6 +130,7 @@ { hosts => \@hosts, port => '162', + domain => 'udp', version => '3', sec_args => { -username => 'jeff', @@ -141,12 +147,14 @@ hosts => \@hosts, version => '3', port => '162', + domain => 'udp', username => 'jeff', privpassword => 'swordfish', ), { hosts => \@hosts, port => '162', + domain => 'udp', version => '3', sec_args => { -username => 'jeff', @@ -165,6 +173,7 @@ hosts => \@hosts, version => '3', port => '162', + domain => 'udp', username => 'jeff', authpassword => 'swordfish', privpassword => 'hedgerows', @@ -173,6 +182,7 @@ { hosts => \@hosts, port => '162', + domain => 'udp', version => '3', sec_args => { -username => 'jeff', diff -Nru munin-2.0.37/plugins/Build.PL munin-2.0.47/plugins/Build.PL --- munin-2.0.37/plugins/Build.PL 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/Build.PL 2019-02-28 14:43:36.000000000 +0000 @@ -3,11 +3,14 @@ use warnings; use strict; +my $version = `../getversion`; +chomp($version); + my $build = PluginsBuilder->new( dist_name => 'Munin::Plugins', - dist_version => '0.0.0', - dist_author => 'The Munin Team ', - dist_abstract => 'The Munin Node', + dist_version => $version, + dist_author => 'The Munin Team ', + dist_abstract => 'The Munin Plugin module', license => 'gpl', requires => { perl => '5', diff -Nru munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/AbstractAnnotationGraphsProvider.java munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/AbstractAnnotationGraphsProvider.java --- munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/AbstractAnnotationGraphsProvider.java 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/AbstractAnnotationGraphsProvider.java 2019-02-28 14:43:36.000000000 +0000 @@ -14,7 +14,7 @@ public abstract class AbstractAnnotationGraphsProvider extends AbstractGraphsProvider { - + protected AbstractAnnotationGraphsProvider(final Config config) { super(config); } diff -Nru munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/AbstractMemoryPoolProvider.java munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/AbstractMemoryPoolProvider.java --- munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/AbstractMemoryPoolProvider.java 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/AbstractMemoryPoolProvider.java 2019-02-28 14:43:36.000000000 +0000 @@ -56,7 +56,7 @@ * While that's an improvement it's still fundamentally broken, as pool * names and even their existence is undefined and implementation- as well * as configuration-dependent. - * + * * A fully correct solution would dynamically create graphs for each pool * encountered and not make any assumption. {@link MultigraphMemory} is such * a fully dynamic implementation and should be preferred. diff -Nru munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/AbstractMemoryUsageProvider.java munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/AbstractMemoryUsageProvider.java --- munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/AbstractMemoryUsageProvider.java 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/AbstractMemoryUsageProvider.java 2019-02-28 14:43:36.000000000 +0000 @@ -5,7 +5,7 @@ public abstract class AbstractMemoryUsageProvider extends AbstractAnnotationGraphsProvider { - + protected MemoryUsage memoryUsage; protected AbstractMemoryUsageProvider(Config config) { diff -Nru munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/AbstractMultiGraphsProvider.java munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/AbstractMultiGraphsProvider.java --- munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/AbstractMultiGraphsProvider.java 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/AbstractMultiGraphsProvider.java 2019-02-28 14:43:36.000000000 +0000 @@ -65,7 +65,7 @@ * Utility method that adds a specified provider to the providers * Map multiple times: Once as a non-graphing data graph and * any number of times as alias graphs. - * + * * @param providers * the Map of providers to add to * @param provider @@ -74,7 +74,7 @@ * the name of the non-graphing instance * @param aliases * the names of the alias instances. - * + * * @see #noGraph(AbstractGraphsProvider) * @see #aliasFor(AbstractGraphsProvider, String) */ @@ -134,7 +134,7 @@ /** * Creates an alias for the specified provider. - * + * * @param provider * provider to alias * @param origName @@ -154,7 +154,7 @@ /** * Creates an alias for the specified provider. - * + * * @param provider * provider to alias * @param origName diff -Nru munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/ClassesLoadedTotal.java munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/ClassesLoadedTotal.java --- munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/ClassesLoadedTotal.java 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/ClassesLoadedTotal.java 2019-02-28 14:43:36.000000000 +0000 @@ -21,7 +21,7 @@ ClassLoadingMXBean.class); return classmxbean.getTotalLoadedClassCount(); } - + public static void main(String[] args) { runGraph(args); } diff -Nru munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/Config.java munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/Config.java --- munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/Config.java 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/Config.java 2019-02-28 14:43:36.000000000 +0000 @@ -39,7 +39,7 @@ category = categoryEnv; } if (prefix == null || prefix.length() == 0) { - this.prefix = "jmx"; + this.prefix = "jmx"; } else { this.prefix = prefix; } @@ -64,11 +64,11 @@ public String getPassword() { return password; } - + public String getPrefix() { return prefix; } - + public boolean isDirtyConfg() { return System.getenv("MUNIN_CAP_DIRTYCONFIG") != null; } diff -Nru munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/GCTimeGet.java munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/GCTimeGet.java --- munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/GCTimeGet.java 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/GCTimeGet.java 2019-02-28 14:43:36.000000000 +0000 @@ -43,7 +43,7 @@ for (GarbageCollectorMXBean gc : gcmbeans) { GCresult[i++] = gc.getCollectionTime(); } - + return GCresult; } } diff -Nru munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/GCTime.java munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/GCTime.java --- munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/GCTime.java 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/GCTime.java 2019-02-28 14:43:36.000000000 +0000 @@ -5,7 +5,7 @@ @Graph(title="GarbageCollectionTime", vlabel="ms", info="The Sun JVM defines garbage collection in two modes: Minor copy collections and Major Mark-Sweep-Compact collections. A minor collection runs relatively quickly and involves moving live data around the heap in the presence of running threads. A major collection is a much more intrusive garbage collection that suspends all execution threads while it completes its task. In terms of performance tuning the heap, the primary goal is to reduce the frequency and duration of major garbage collections.") public class GCTime extends AbstractAnnotationGraphsProvider { - + public GCTime(Config config) { super(config); } @@ -17,17 +17,17 @@ GCTimeGet collector = new GCTimeGet(getConnection()); times = collector.GC(); } - + @Field(label="MinorTime", info="The approximate accumulated collection elapsed time in milliseconds. This method returns -1 if the collection elapsed time is undefined for this collector.", type="DERIVE", min=0) public long copyTime() { return times[0]; } - + @Field(label="MajorTime", info="The approximate accumulated collection elapsed time in milliseconds. This method returns -1 if the collection elapsed time is undefined for this collector.", type="DERIVE", min=0) public long markSweepCompactTime() { return times[1]; } - + public static void main(String[] args) { runGraph(args); } diff -Nru munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/LegacyPool.java munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/LegacyPool.java --- munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/LegacyPool.java 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/LegacyPool.java 2019-02-28 14:43:36.000000000 +0000 @@ -5,7 +5,7 @@ * 1.4-era JMX Pluginwas hard-coded to those names and expected them at a * specific location in the returned MBeans (which is not portable and has lead * to several mis-represented values at best). - * + * * Generally speaking pool names hsould not be hard-coded at all in the JMX * plugins, as they are not specified and can vary between JVMs, JVM versions * and even based on the settings used to run the JVM (ConcurrentMarkSweep vs. diff -Nru munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/MemoryPoolUsageProvider.java munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/MemoryPoolUsageProvider.java --- munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/MemoryPoolUsageProvider.java 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/MemoryPoolUsageProvider.java 2019-02-28 14:43:36.000000000 +0000 @@ -37,7 +37,7 @@ String graphVlabel = "bytes"; String graphArgs = "--base 1024 -l 0"; String graphInfo = usagePhrase + "memory usage of the " + name + " memory pool"; - + printGraphConfig(out, graphTitle, graphVlabel, graphInfo, graphArgs, true, true); } diff -Nru munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/ThreadsDaemon.java munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/ThreadsDaemon.java --- munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/ThreadsDaemon.java 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/ThreadsDaemon.java 2019-02-28 14:43:36.000000000 +0000 @@ -13,7 +13,7 @@ public class ThreadsDaemon extends AbstractAnnotationGraphsProvider { private ThreadMXBean threadMXBean; - + public ThreadsDaemon(Config config) { super(config); } diff -Nru munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/Threads.java munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/Threads.java --- munin-2.0.37/plugins/javalib/org/munin/plugin/jmx/Threads.java 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/javalib/org/munin/plugin/jmx/Threads.java 2019-02-28 14:43:36.000000000 +0000 @@ -10,7 +10,7 @@ public class Threads extends AbstractAnnotationGraphsProvider { private ThreadMXBean threadMXBean; - + public Threads(Config config) { super(config); } diff -Nru munin-2.0.37/plugins/lib/Munin/Plugin/Pgsql.pm munin-2.0.47/plugins/lib/Munin/Plugin/Pgsql.pm --- munin-2.0.37/plugins/lib/Munin/Plugin/Pgsql.pm 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/lib/Munin/Plugin/Pgsql.pm 2019-02-28 14:43:36.000000000 +0000 @@ -156,9 +156,9 @@ base Used for graph_args --base. Default is 1000, set to 1024 when returning sizes in Kb for example. wildcardfilter The SQL to substitute for when a wildcard plugin is run against - a specific entity, for example a database. All occurrances of + a specific entity, for example a database. All occurrences of the string %%FILTER%% will be replaced with this string, and - for each occurance a parameter with the value of the filtering + for each occurrence a parameter with the value of the filtering condition will be added to the DBI statement. paramdatabase Makes the plugin connect to the database in the first parameter (wildcard plugins only) instead of 'template1'. @@ -425,11 +425,15 @@ # variables. my $dbname = "template1"; $dbname = $self->{defaultdb} if ($self->{defaultdb}); - $dbname = $self->wildcard_parameter(0) if ($self->{paramdatabase} && !defined($nowildcard)); + $dbname = $self->wildcard_parameter(0) if ($self->{paramdatabase} && !defined($nowildcard) && $self->wildcard_parameter(0)); $dbname = $ENV{"PGDATABASE"} if ($ENV{"PGDATABASE"}); - $self->{dbh} = DBI->connect("DBI:Pg:dbname=$dbname", '', '', {pg_server_prepare => 0}); + $self->{dbh} = DBI->connect("DBI:Pg:dbname=$dbname", '', '', {pg_server_prepare => 0, PrintError => 0}); unless ($self->{dbh}) { - $self->{connecterror} = "$DBI::errstr"; + my $err_str = "$DBI::errstr"; + $err_str =~ s/[\r\n\t]/ /g; + $err_str =~ s/\h+/ /g; + $err_str =~ s/ $//; + $self->{connecterror} = $err_str; return 0; } } @@ -479,7 +483,9 @@ my $v = $r->[0]->[0]; die "Unable to detect PostgreSQL version\n" unless ($v =~ /^(\d+)\.(\d+).*\b/); - $self->{detected_version} = "$1.$2"; + # from PostgreSQL 10 on only the major version is needed + # see https://www.postgresql.org/support/versioning/ + $self->{detected_version} = ($1 >= 10) ? "$1" : "$1.$2"; } sub get_versioned_query { diff -Nru munin-2.0.37/plugins/lib/Munin/Plugin/SNMP.pm munin-2.0.47/plugins/lib/Munin/Plugin/SNMP.pm --- munin-2.0.37/plugins/lib/Munin/Plugin/SNMP.pm 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/lib/Munin/Plugin/SNMP.pm 2019-02-28 14:43:36.000000000 +0000 @@ -193,6 +193,12 @@ The timeout in seconds to use. Default 5. +=item C + +The Transport Domain to use for exchanging SNMP messages. The default +is UDP/IPv4. Possible values: 'udp', 'udp4', 'udp/ipv4'; 'udp6', +'udp/ipv6'; 'tcp', 'tcp4', 'tcp/ipv4'; 'tcp6', 'tcp/ipv6'. + =item C The SNMP version to use for the connection. One of 1, 2, 3, snmpv1, @@ -220,6 +226,9 @@ # Timeout push @options, (-timeout => $ENV{timeout}) if $ENV{timeout}; + # Transport Domain + push @options, (-domain => $ENV{domain}) if $ENV{domain}; + if ($version eq '1' or $version eq 'snmpv1' or $version eq '2' or $version eq 'snmpv2c') { @@ -485,7 +494,7 @@ return $response->{$oid}; } -=head2 get_by_regex() - Retrive table of values filtered by regex applied to the value +=head2 get_by_regex() - Retrieve table of values filtered by regex applied to the value This example shows the usage for a netstat plugin. diff -Nru munin-2.0.37/plugins/lib/Munin/Plugin.pm munin-2.0.47/plugins/lib/Munin/Plugin.pm --- munin-2.0.37/plugins/lib/Munin/Plugin.pm 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/lib/Munin/Plugin.pm 2019-02-28 14:43:36.000000000 +0000 @@ -32,7 +32,7 @@ ## no critic Prototypes -=head1 NAME +=head1 NAME Munin::Plugin - Utility functions for Perl Munin plugins. diff -Nru munin-2.0.37/plugins/node.d/amavis.in munin-2.0.47/plugins/node.d/amavis.in --- munin-2.0.37/plugins/node.d/amavis.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/amavis.in 2019-02-28 14:43:36.000000000 +0000 @@ -56,9 +56,6 @@ #%# family=auto #%# capabilities=autoconf -=head1 VERSION - - $Id$ =head1 BUGS @@ -76,30 +73,26 @@ =cut -mktempfile () { - cmd=`echo $MUNIN_MKTEMP | sed s/\\$1/$1/` - $cmd -} AMAVIS_LOG=${amavislog:-/var/log/mail/mail.info} LOGTAIL=${logtail:-logtail} STATEFILE=$MUNIN_PLUGSTATE/amavis.offset if [ "$1" = "autoconf" ]; then - if [ -f "${AMAVIS_LOG}" -a -n "${LOGTAIL}" -a -x "${LOGTAIL}" ] ; then + if [ -f "${AMAVIS_LOG}" ] && [ -n "${LOGTAIL}" ] && [ -x "${LOGTAIL}" ] ; then echo yes exit 0 else - echo no + echo "no (command $LOGTAIL or file $AMAVIS_LOG not found)" exit 0 fi fi # Try tailing a random file to check how arguments are passed ARGS=0 -`$LOGTAIL /etc/hosts 2>/dev/null >/dev/null` +"$LOGTAIL" /etc/hosts 2>/dev/null >/dev/null if [ $? = 66 ]; then - if [ ! -n "$logtail" ]; then + if [ -z "$logtail" ]; then ARGS=1 fi fi @@ -124,25 +117,23 @@ spamm=U spams=U -TEMP_FILE=$(mktempfile munin-amavis.XXXXXX) +TEMP_FILE=$(@@MKTEMP@@ munin-amavis.XXXXXX) -if [ -n "$TEMP_FILE" -a -f "$TEMP_FILE" ] -then - if [ $ARGS != 0 ]; then - $LOGTAIL -f ${AMAVIS_LOG} -o ${STATEFILE} | grep 'amavis\[.*\]:' > ${TEMP_FILE} +if [ -n "$TEMP_FILE" ] && [ -f "$TEMP_FILE" ]; then + if [ "$ARGS" != 0 ]; then + "$LOGTAIL" -f "${AMAVIS_LOG}" -o "${STATEFILE}" | grep 'amavis\[.*\]:' > "${TEMP_FILE}" else - $LOGTAIL ${AMAVIS_LOG} ${STATEFILE} | grep 'amavis\[.*\]:' > ${TEMP_FILE} + "$LOGTAIL" "${AMAVIS_LOG}" "${STATEFILE}" | grep 'amavis\[.*\]:' > "${TEMP_FILE}" fi - total=$(grep -c 'Hits:' ${TEMP_FILE}) - virus=$(grep -c 'INFECTED.*Hits:' ${TEMP_FILE}) - spamm=$(grep -c 'SPAMMY.*Hits:' ${TEMP_FILE}) - spams=$(grep -c 'SPAM .*Hits:' ${TEMP_FILE}) + total=$(grep -c 'Hits:' "$TEMP_FILE") + virus=$(grep -c 'INFECTED.*Hits:' "$TEMP_FILE") + spamm=$(grep -c 'SPAMMY.*Hits:' "$TEMP_FILE") + spams=$(grep -c 'SPAM .*Hits:' "$TEMP_FILE") - /bin/rm -f $TEMP_FILE + /bin/rm -f "$TEMP_FILE" fi echo "virus.value ${virus}" echo "spam_maybe.value ${spamm}" echo "spam_sure.value ${spams}" echo "total.value ${total}" - diff -Nru munin-2.0.37/plugins/node.d/apache_accesses.in munin-2.0.47/plugins/node.d/apache_accesses.in --- munin-2.0.37/plugins/node.d/apache_accesses.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/apache_accesses.in 2019-02-28 14:43:36.000000000 +0000 @@ -45,6 +45,20 @@ This will provide for HTTP basic authentication. +It is possible to use HTTPS for accessing the server. You just need to +make sure, that the server certificate is valid (i.e. it is signed by +a locally known CA and it matches the hostname in the URL). +If you really need to connect to an HTTPS URL without a valid +certificate (as described above), then you should try to set one of +the following environment settings in the munin-node plugin +configuration: + + env.PERL_LWP_SSL_VERIFY_HOSTNAME 0 + env.HTTPS_CA_FILE /etc/ssl/acme-ca.pem + env.HTTPS_CA_DIR /etc/acme-ca-certs/ + +See https://metacpan.org/pod/LWP::UserAgent for more details. + =head1 INTERPRETATION The plugin shows the number of accesses (pages and other items served) @@ -109,8 +123,8 @@ next; } else { - print "no (ExtendedStatus option for apache" - . " mod_status is missing on port $port)\n"; + print "no (ExtendedStatus option for apache" + . " mod_status is missing on port $port)\n"; exit 0; } } @@ -138,7 +152,7 @@ print "accesses$port.type DERIVE\n"; print "accesses$port.max 1000000\n"; print "accesses$port.min 0\n"; - print "accesses$port.info The number of accesses (pages and other items" + print "accesses$port.info The number of accesses (pages and other items" . " served) globally on the Apache server\n"; print_thresholds("accesses$port"); } diff -Nru munin-2.0.37/plugins/node.d/apache_processes.in munin-2.0.47/plugins/node.d/apache_processes.in --- munin-2.0.37/plugins/node.d/apache_processes.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/apache_processes.in 2019-02-28 14:43:36.000000000 +0000 @@ -45,6 +45,20 @@ This will provide for HTTP basic authentication. +It is possible to use HTTPS for accessing the server. You just need to +make sure, that the server certificate is valid (i.e. it is signed by +a locally known CA and it matches the hostname in the URL). +If you really need to connect to an HTTPS URL without a valid +certificate (as described above), then you should try to set one of +the following environment settings in the munin-node plugin +configuration: + + env.PERL_LWP_SSL_VERIFY_HOSTNAME 0 + env.HTTPS_CA_FILE /etc/ssl/acme-ca.pem + env.HTTPS_CA_DIR /etc/acme-ca-certs/ + +See https://metacpan.org/pod/LWP::UserAgent for more details. + =head1 INTERPRETATION The plugin shows the number of Apache processes running on the @@ -116,8 +130,8 @@ next; } else { - print "no (ExtendedStatus option for apache" - . " mod_status is missing on port $port)\n"; + print "no (ExtendedStatus option for apache" + . " mod_status is missing on port $port)\n"; exit 0; } } diff -Nru munin-2.0.37/plugins/node.d/apache_volume.in munin-2.0.47/plugins/node.d/apache_volume.in --- munin-2.0.37/plugins/node.d/apache_volume.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/apache_volume.in 2019-02-28 14:43:36.000000000 +0000 @@ -43,6 +43,20 @@ This will provide for HTTP basic authentication. +It is possible to use HTTPS for accessing the server. You just need to +make sure, that the server certificate is valid (i.e. it is signed by +a locally known CA and it matches the hostname in the URL). +If you really need to connect to an HTTPS URL without a valid +certificate (as described above), then you should try to set one of +the following environment settings in the munin-node plugin +configuration: + + env.PERL_LWP_SSL_VERIFY_HOSTNAME 0 + env.HTTPS_CA_FILE /etc/ssl/acme-ca.pem + env.HTTPS_CA_DIR /etc/acme-ca-certs/ + +See https://metacpan.org/pod/LWP::UserAgent for more details. + =head1 INTERPRETATION The plugin shows the Apache HTTP servers global data volume in @@ -97,7 +111,7 @@ print "no ($ret)\n"; exit 0; } - + my $ua = LWP::UserAgent->new(timeout => 30, agent => sprintf("munin/%s (libwww-perl/%s)", $Munin::Common::Defaults::MUNIN_VERSION, $LWP::VERSION)); @@ -109,8 +123,8 @@ next; } else { - print "no (ExtendedStatus option for apache" - . " mod_status is missing on port $port)\n"; + print "no (ExtendedStatus option for apache" + . " mod_status is missing on port $port)\n"; exit 0; } } diff -Nru munin-2.0.37/plugins/node.d/apc_envunit_.in munin-2.0.47/plugins/node.d/apc_envunit_.in --- munin-2.0.37/plugins/node.d/apc_envunit_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/apc_envunit_.in 2019-02-28 14:43:36.000000000 +0000 @@ -49,7 +49,7 @@ =cut -type=`echo $0 | sed -e 's/.*_\(.*\)/\1/'` +type=$(echo "$0" | sed -e 's/.*_\(.*\)/\1/') if [ "${type}" = temperature ] ; then TOID="enterprises.318.1.1.10.3.13.1.1.3" NAME="temperature" @@ -64,27 +64,27 @@ fi fi -UNITS="" -COMMUNITY="public" -SNMPGET=`which snmpget 2>/dev/null` - -if [ "$units" ]; then UNITS=$units ; fi -if [ "$oid" ]; then TOID=$oid ; fi -if [ "$community" ]; then COMMUNITY=$community ; fi +UNITS=${units:-} +COMMUNITY=${community:-public} +SNMPGET=$(which snmpget 2>/dev/null) -SNMPOPTS="-Ov -Oq -v1 -c ${COMMUNITY}" +if [ -n "${oid:-}" ]; then TOID=$oid ; fi +snmp_get() { + "$SNMPGET" -Ov -Oq -v1 -c "$COMMUNITY" +} + if [ "$1" = "autoconf" ]; then if [ -z "${UNITS}" ] ; then echo "no (no units to monitor)" ; exit 0 ; fi - if [ -z "$SNMPGET" -o ! -x "$SNMPGET" ] ; then + if [ -z "$SNMPGET" ] || [ ! -x "$SNMPGET" ] ; then echo "no (no snmpget executable)" exit 0 fi for m in ${UNITS} ; do - if ping -c1 -q $m >/dev/null 2>&1 ; then continue ; fi + if ping -c1 -q "$m" >/dev/null 2>&1; then continue; fi echo "no (can't reach $m)" ; exit 0 done echo "yes" ; exit 0 @@ -100,7 +100,7 @@ echo "graph_title Environmental units (${NAME} probes)" echo "graph_vlabel ${LABEL}" for m in ${UNITS} ; do - mm=`echo ${m} | tr '-' '_'` + mm=$(echo "$m" | tr '-' '_') echo "${mm}_${LETTER}1.label $m ${NAME} #1" echo "${mm}_${LETTER}2.label $m ${NAME} #2" done @@ -108,9 +108,9 @@ fi for m in ${UNITS} ; do - v1=`${SNMPGET} ${SNMPOPTS} $m ${TOID}.1` - v2=`${SNMPGET} ${SNMPOPTS} $m ${TOID}.2` - mm=`echo ${m} | tr '-' '_'` + v1=$(snmp_get "$m" "${TOID}.1") + v2=$(snmp_get "$m" "${TOID}.2") + mm=$(echo "$m" | tr '-' '_') echo "${mm}_${LETTER}1.value $v1" echo "${mm}_${LETTER}2.value $v2" done diff -Nru munin-2.0.37/plugins/node.d/apc_nis.in munin-2.0.47/plugins/node.d/apc_nis.in --- munin-2.0.37/plugins/node.d/apc_nis.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/apc_nis.in 2019-02-28 14:43:36.000000000 +0000 @@ -29,20 +29,26 @@ use IO::Socket; use strict; -if($ARGV[0] and $ARGV[0] eq "autoconf") { - print "yes\n"; - exit 0; -} - my $host = exists $ENV{'host'} ? $ENV{'host'} : "127.0.0.1"; my $port = exists $ENV{'port'} ? $ENV{'port'} : "3551"; +# We connect early: the connection is used for every operation: autoconf, config and data fetch. my $sock = new IO::Socket::INET ( PeerAddr => $host, PeerPort => $port, Proto => 'tcp' ); +if($ARGV[0] and $ARGV[0] eq "autoconf") { + if ($sock) { + # we successfully opened a connected to the configured daemon + print "yes\n"; + } else { + print "no (failed to connect to $host:$port)\n"; + } + exit 0; +} + die "Could not create socket: $!\n" unless $sock; my $buf = pack("CC", 0, 6); @@ -59,12 +65,12 @@ if ($line =~ /\WITEMP /) { $has_temperature = 1; } elsif ($line =~ /\WLOTRANS /) { - $line =~ s/.* (\d+.\d+).*/$1/; - $line_volt_min = $line; + $line =~ s/.* (\d+.\d+).*/$1/; + $line_volt_min = $line; } elsif ($line =~ /\WHITRANS /) { - $line =~ s/.* (\d+.\d+).*/$1/; - $line_volt_max = $line; - } + $line =~ s/.* (\d+.\d+).*/$1/; + $line_volt_max = $line; + } } while(!($line =~ /END APC/)); close($sock); diff -Nru munin-2.0.37/plugins/node.d/asterisk_sipchannels.in munin-2.0.47/plugins/node.d/asterisk_sipchannels.in --- munin-2.0.37/plugins/node.d/asterisk_sipchannels.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/asterisk_sipchannels.in 2019-02-28 14:43:36.000000000 +0000 @@ -126,11 +126,11 @@ #Response: Follows #Privilege: Command -#Peer User/ANR Call ID Seq (Tx/Rx) Format Hold Last Message +#Peer User/ANR Call ID Seq (Tx/Rx) Format Hold Last Message #0 active SIP channels # -- OR -- -#74.218.176.166 (None) c24a5a230c6 00101/278584006 0x0 (nothing) No Rx: REGISTER -#74.218.176.166 (None) 508c037f936 00101/07310 0x0 (nothing) No Rx: REGISTER +#74.218.176.166 (None) c24a5a230c6 00101/278584006 0x0 (nothing) No Rx: REGISTER +#74.218.176.166 (None) 508c037f936 00101/07310 0x0 (nothing) No Rx: REGISTER #2 active SIP channels #--END COMMAND-- diff -Nru munin-2.0.37/plugins/node.d/asterisk_sippeers.in munin-2.0.47/plugins/node.d/asterisk_sippeers.in --- munin-2.0.37/plugins/node.d/asterisk_sippeers.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/asterisk_sippeers.in 2019-02-28 14:43:36.000000000 +0000 @@ -61,11 +61,11 @@ # ################################################################################# # Following example from current asterisk 1.4 #> sip show peers -#Name/username Host Dyn Nat ACL Port Status -#104-RANDALLBUILT/104-RAND 74.218.176.166 D 5060 Unmonitored -#... -#102-ROCKSOLID/102-ROCKSOL (Unspecified) D 0 Unmonitored -#101-ROCKSOLID/101-ROCKSOL (Unspecified) D N 0 UNKNOWN +#Name/username Host Dyn Nat ACL Port Status +#104-RANDALLBUILT/104-RAND 74.218.176.166 D 5060 Unmonitored +#... +#102-ROCKSOLID/102-ROCKSOL (Unspecified) D 0 Unmonitored +#101-ROCKSOLID/101-ROCKSOL (Unspecified) D N 0 UNKNOWN #20 sip peers [Monitored: 0 online, 1 offline Unmonitored: 2 online, 17 offline] # ################################################################################# diff -Nru munin-2.0.37/plugins/node.d/asterisk_voicemail.in munin-2.0.47/plugins/node.d/asterisk_voicemail.in --- munin-2.0.37/plugins/node.d/asterisk_voicemail.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/asterisk_voicemail.in 2019-02-28 14:43:36.000000000 +0000 @@ -118,7 +118,7 @@ while (($line = $pop->getline) and ($line !~ /--END/o)) { if ($start) { - @fields = (split ' ', $line); + @fields = (split ' ', $line); $results = $results + pop(@fields); } diff -Nru munin-2.0.37/plugins/node.d/bind9.in munin-2.0.47/plugins/node.d/bind9.in --- munin-2.0.37/plugins/node.d/bind9.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/bind9.in 2019-02-28 14:43:36.000000000 +0000 @@ -106,7 +106,7 @@ my $k; print "graph_title DNS Queries by type -graph_category BIND +graph_category dns graph_vlabel Queries / \${graph_period} query_other.label Other query_other.type DERIVE diff -Nru munin-2.0.37/plugins/node.d/bind9_rndc.in munin-2.0.47/plugins/node.d/bind9_rndc.in --- munin-2.0.37/plugins/node.d/bind9_rndc.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/bind9_rndc.in 2019-02-28 14:43:36.000000000 +0000 @@ -11,7 +11,7 @@ [bind_rndc] env.rndc /usr/sbin/rndc - env.rndc_options + env.rndc_options env.querystats /var/run/named.stats The user/group that runs the plugin must have read access to the stats @@ -197,9 +197,9 @@ if (defined($ARGV[0]) and ($ARGV[0] eq 'config')) { print "graph_title DNS Queries by status\n"; print "graph_vlabel queries / \${graph_period}\n"; - print "graph_category BIND\n"; + print "graph_category dns\n"; - for my $key (keys %IN) { + for my $key (sort keys %IN) { print "query_$key.label $key\n"; print "query_$key.type DERIVE\n"; print "query_$key.min 0\n"; diff -Nru munin-2.0.37/plugins/node.d/cmc_tc_sensor_.in munin-2.0.47/plugins/node.d/cmc_tc_sensor_.in --- munin-2.0.37/plugins/node.d/cmc_tc_sensor_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/cmc_tc_sensor_.in 2019-02-28 14:43:36.000000000 +0000 @@ -85,18 +85,18 @@ 7 => 'low', 8 => 'warn', ); - + # TODO: Fill out more from MIB my %sensor_types = ( 1 => 'not available', 10 => 'temperature', ); - + if ($configure) { # .1.3.6.1.4.1.2606.4.2.3.5.2.1.x.1 # unit -^ ^ ^- index # `- property - + my $baseoid = "1.3.6.1.4.1.2606.4.2." . (2 + $sensor_unit) . ".5.2.1"; if (defined (my $response = $session->get_table ($baseoid))) { while (my ($oid, $value) = each (%$response)) { @@ -138,19 +138,19 @@ # Find number of connected CMC units my $num_units_oid = '1.3.6.1.4.1.2606.4.2.2.0'; my $num_units = $session->get_request ($num_units_oid)->{$num_units_oid}; - + # .1.3.6.1.4.1.2606.4.2.3.5.2.1.1.1 # ^- 2 + $unit_no - + for (my $i = 1; $i <= $num_units; $i++) { - + # Walk each table my $baseoid = "1.3.6.1.4.1.2606.4.2." . (2 + $i) . ".5.2.1"; - + # Find properties and values # We only traverse the OID tree once per sensor, # to reduce number of SNMP GET requests. - + if (defined (my $response = $session->get_table ($baseoid))) { while (my ($oid, $value) = each (%$response)) { my $prop_id = undef; @@ -183,12 +183,12 @@ # Go directly to the OID we want my $oid = "1.3.6.1.4.1.2606.4.2." . (2 + $sensor_unit) . ".5.2.1.5." . $sensor_index; my $value = $session->get_request ($oid)->{$oid}; - + # Show values print "sensor_" . $sensor_unit . "_" . $sensor_index . ".value $value\n"; } } - + $session->close(); } exit 0; diff -Nru munin-2.0.37/plugins/node.d/courier_.in munin-2.0.47/plugins/node.d/courier_.in --- munin-2.0.37/plugins/node.d/courier_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/courier_.in 2019-02-28 14:43:36.000000000 +0000 @@ -53,18 +53,14 @@ # Set the location of the courier logs COURIER_LOG=${logfile:-/var/log/mail.log} -SERVICE=${service:-`basename $0 | sed 's/^courier_//g'`} +SERVICE=${service:-$(basename "$0" | sed 's/^courier_//g')} OFFSET_FILE=${MUNIN_PLUGSTATE}/courier_${SERVICE}.offset LOGTAIL=${logtail:-/usr/sbin/logtail} -mktempfile () { -@@MKTEMP@@ -} case $1 in autoconf|detect) - if [ -f ${COURIER_LOG} -a -x ${LOGTAIL} ] - then + if [ -f "$COURIER_LOG" ] && [ -x "$LOGTAIL" ]; then # Makes no sense for wildcard plugin to autoconf to yes # unless you can provide suggestions. echo no @@ -89,30 +85,30 @@ esac ARGS=0 -`$LOGTAIL /etc/hosts 2>/dev/null >/dev/null` +"$LOGTAIL" /etc/hosts 2>/dev/null >/dev/null if [ $? = 66 ]; then - if [ ! -n "$logtail" ]; then + if [ -z "$logtail" ]; then ARGS=1 fi fi -TEMP_FILE=`mktempfile munin-courier.XXXXXX` +TEMP_FILE=$(@@MKTEMP@@ munin-courier.XXXXXX) -if [ -z "$TEMP_FILE" -o ! -f "$TEMP_FILE" ]; then +if [ -z "$TEMP_FILE" ] || [ ! -f "$TEMP_FILE" ]; then exit 3 fi -if [ $ARGS != 0 ]; then - ${LOGTAIL} -f ${COURIER_LOG} -o ${OFFSET_FILE} | grep "$SERVICE" > ${TEMP_FILE} +if [ "$ARGS" != 0 ]; then + "$LOGTAIL" -f "${COURIER_LOG}" -o "${OFFSET_FILE}" | grep "$SERVICE" > "$TEMP_FILE" else - ${LOGTAIL} ${COURIER_LOG} ${OFFSET_FILE} | grep "$SERVICE" > ${TEMP_FILE} + "$LOGTAIL" "${COURIER_LOG}" "${OFFSET_FILE}" | grep "$SERVICE" > "$TEMP_FILE" fi -connection=`grep Connection ${TEMP_FILE} | wc -l` -disconnected=`grep DISCONNECTED ${TEMP_FILE} | wc -l` -login=`grep LOGIN ${TEMP_FILE} | wc -l` -logout=`grep LOGOUT ${TEMP_FILE} | wc -l` +connection=$(grep Connection "$TEMP_FILE" | wc -l) +disconnected=$(grep DISCONNECTED "$TEMP_FILE" | wc -l) +login=$(grep LOGIN "$TEMP_FILE" | wc -l) +logout=$(grep LOGOUT "$TEMP_FILE" | wc -l) -rm ${TEMP_FILE} +rm "$TEMP_FILE" echo "connection.value ${connection}" echo "disconnected.value ${disconnected}" diff -Nru munin-2.0.37/plugins/node.d/courier_mta_mailqueue.in munin-2.0.47/plugins/node.d/courier_mta_mailqueue.in --- munin-2.0.37/plugins/node.d/courier_mta_mailqueue.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/courier_mta_mailqueue.in 2019-02-28 14:43:36.000000000 +0000 @@ -42,7 +42,7 @@ case $1 in autoconf|detect) - if [ -d $SPOOLDIR/ -a -r $SPOOLDIR/ ] ; then + if [ -d "$SPOOLDIR/" ] && [ -r "$SPOOLDIR/" ] ; then echo yes exit 0 else @@ -60,7 +60,7 @@ exit 0;; esac -cd $SPOOLDIR >/dev/null 2>/dev/null || { +cd "$SPOOLDIR" >/dev/null 2>/dev/null || { echo "# Cannot cd to $SPOOLDIR" exit 1 } diff -Nru munin-2.0.37/plugins/node.d/courier_mta_mailstats.in munin-2.0.47/plugins/node.d/courier_mta_mailstats.in --- munin-2.0.37/plugins/node.d/courier_mta_mailstats.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/courier_mta_mailstats.in 2019-02-28 14:43:36.000000000 +0000 @@ -141,7 +141,7 @@ if(-l $statefile) { die("$statefile is a symbolic link, refusing to touch it."); -} +} open (OUT, ">$statefile") or exit 4; print OUT "$pos:$delivered\n"; foreach my $i (keys %{$rejects}) { @@ -149,11 +149,11 @@ } close OUT; -sub parseLogfile { +sub parseLogfile { my ($fname, $start, $stop) = @_; open (LOGFILE, $fname) or exit 3; seek (LOGFILE, $start, 0) or exit 2; - + while (tell (LOGFILE) < $stop) { my $line =; chomp ($line); @@ -163,7 +163,7 @@ $rejects->{$1} ++; } } - close(LOGFILE); + close(LOGFILE); } sub get_prev_date { diff -Nru munin-2.0.37/plugins/node.d/courier_mta_mailvolume.in munin-2.0.47/plugins/node.d/courier_mta_mailvolume.in --- munin-2.0.37/plugins/node.d/courier_mta_mailvolume.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/courier_mta_mailvolume.in 2019-02-28 14:43:36.000000000 +0000 @@ -121,16 +121,16 @@ if(-l $statefile) { die("$statefile is a symbolic link, refusing to touch it."); -} +} open (OUT, ">$statefile") or exit 4; print OUT "$pos:$volume\n"; close OUT; -sub parseLogfile { +sub parseLogfile { my ($fname, $start, $stop) = @_; open (LOGFILE, $fname) or exit 3; seek (LOGFILE, $start, 0) or exit 2; - + while (tell (LOGFILE) < $stop) { my $line =; chomp ($line); @@ -138,7 +138,7 @@ $volume += $1; } } - close(LOGFILE); + close(LOGFILE); } sub get_prev_date { diff -Nru munin-2.0.37/plugins/node.d/cupsys_pages.in munin-2.0.47/plugins/node.d/cupsys_pages.in --- munin-2.0.37/plugins/node.d/cupsys_pages.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/cupsys_pages.in 2019-02-28 14:43:36.000000000 +0000 @@ -62,12 +62,17 @@ my $logfile = "$LOGDIR/$LOGFILE"; my $rotlogfile = $logfile . ".0"; +my $rotlogfile_last_sunday = $logfile . "-" . `date --date="last sunday" +%Y%m%d`; +chomp($rotlogfile_last_sunday); + if (-f "$logfile.0") { $rotlogfile = $logfile . ".0"; } elsif (-f "$logfile.1") { $rotlogfile = $logfile . ".1"; } elsif (-f "$logfile.01") { $rotlogfile = $logfile . ".01"; +} elsif (-f "$rotlogfile_last_sunday") { + $rotlogfile = $rotlogfile_last_sunday; } if (! -f $logfile and ! -f $rotlogfile) { @@ -119,6 +124,7 @@ if($ARGV[0] and $ARGV[0] eq "config") { print "host_name $ENV{FQDN}\n"; print "graph_title CUPS pages printed\n"; + print "graph_category printing\n"; print "graph_args --base 1000 -l 0\n"; print "graph_vlabel pages/\${graph_period}\n"; foreach my $printer (sort(keys %printers)) { @@ -152,7 +158,7 @@ } elsif(defined($printers{$1})) { $printers{$1} += int($2)*int($3); } - } + } } close(LOGFILE); } diff -Nru munin-2.0.37/plugins/node.d/debug_sincos munin-2.0.47/plugins/node.d/debug_sincos --- munin-2.0.37/plugins/node.d/debug_sincos 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/debug_sincos 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -#! /usr/bin/perl -# Sample plugin that draw a sine & a cos -# - used for spooling debugging - -if ($ARGV[0] eq "config") { - print "graph_title Trigo plugin\n"; - print "graph_vlabel unit\n"; - print "graph_category debug\n"; - print "update_rate 1\n"; - print "graph_data_size custom 1t, 10s for 1y\n"; - print "sin.label Sine\n"; - print "cos.label Cosine\n"; - - exit 0; -} - - -my $epoch = time; - -for (my $i = $epoch - 5; $i < $epoch; $i += 1) { - print "sin.value $i:". sin($i / 3600). "\n"; -} - -for (my $i = $epoch - 5; $i < $epoch; $i += 1) { - print "cos.value $i:". cos($i / 3600). "\n"; -} diff -Nru munin-2.0.37/plugins/node.d/df.in munin-2.0.47/plugins/node.d/df.in --- munin-2.0.37/plugins/node.d/df.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/df.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,8 @@ #!@@GOODSH@@ # -*- sh -*- +set -e + : << =cut =head1 NAME @@ -25,7 +27,7 @@ . "$MUNIN_LIBDIR/plugins/plugin.sh" -df_entries=$(df -P -l 2>/dev/null | sed -e 1d -e '/\/\//d' -e 's/%//' | sort) +df_entries=$(df -P -l 2>/dev/null | sed -e '1d' -e '/\/\//d' -e 's/%//' | sort) # Use the mountpoint instead of the device name for ambiguous virtual devices (tmpfs, ...). diff -Nru munin-2.0.37/plugins/node.d/df_inode.in munin-2.0.47/plugins/node.d/df_inode.in --- munin-2.0.37/plugins/node.d/df_inode.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/df_inode.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,8 @@ #!@@GOODSH@@ # -*- sh -*- +set -e + : << =cut =head1 NAME diff -Nru munin-2.0.37/plugins/node.d/dhcpd3.in munin-2.0.47/plugins/node.d/dhcpd3.in --- munin-2.0.37/plugins/node.d/dhcpd3.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/dhcpd3.in 2019-02-28 14:43:36.000000000 +0000 @@ -26,9 +26,9 @@ env.critical 0.95 env.warning 0.9 -The optional filter setting is used to strip parts of ranges for the +The optional filter setting is used to strip parts of ranges for the network labels (example will show 10.140.80.0 as 80.0). Both critical -and warning are optional settings, default for warning is 0.9 (90%) +and warning are optional settings, default for warning is 0.9 (90%) and 0.95 for critical (95%). =head1 INTERPRETATION @@ -72,7 +72,7 @@ } if(! eval "require Net::IP") { $ret = "Net::IP not found"; -} +} use strict; @@ -159,10 +159,10 @@ sub parseconfig { my($configfile) = @_; - + local(*IN); open(IN, "<$configfile") or exit 4; - + my $name = undef; LINE: while() { if(/subnet\s+((?:\d+\.){3}\d+)\s+netmask\s+((?:\d+\.){3}\d+)/ && ! /^\s*#/) { @@ -201,7 +201,7 @@ $from = ((new Net::IP($from))->intip())->numify(); $to = ((new Net::IP($to))->intip())->numify(); - + if($from < $to) { return ($to - $from) + 1; } else { @@ -213,7 +213,7 @@ sub parseleases { my $ip = 0; my $abandon = 0; - my $time = time(); + my $time = time(); open(IN, "<$LEASEFILE") or exit 4; while() { @@ -225,9 +225,9 @@ # 2037/12/31 23:59:59 is max date on perl <= 5.6 print "# DEBUG: end $1\n" if $DEBUG; my $end = HTTP::Date::str2time($1, "GMT"); - # we asume that missing $end is valid due to + # we asume that missing $end is valid due to # restrictions in Time::Local on perl <= 5.6 - if($end && $end < $time) { + if($end && $end < $time) { print "# DEBUG: old $end $time:(\n" if $DEBUG; $abandon = 1; } diff -Nru munin-2.0.37/plugins/node.d/digitemp_.in munin-2.0.47/plugins/node.d/digitemp_.in --- munin-2.0.37/plugins/node.d/digitemp_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/digitemp_.in 2019-02-28 14:43:36.000000000 +0000 @@ -18,6 +18,7 @@ =head1 USAGE Symlink as the name of the digitemp program to use, i.e. digitemp_DS2490 +and create configuration file (default: /etc/digitemp.conf). =head1 AUTHOR @@ -40,16 +41,55 @@ =head1 MAGIC MARKERS - #%# family=manual + #%# capabilities=autoconf suggest + #%# family=auto =cut -digitemp=${0##*/} -model=${digitemp##*_} +# common values: digitemp_DS2490, digitemp_DS9097, digitemp_DS9097U +digitemp_bin=${0##*/} +model=${digitemp_bin##*_} digitemprc=${digitemprc:-/etc/digitemp.conf} -if ! [ -x "`which $digitemp`" ]; then - echo "$digitemp not found" >&2 + +get_sensor_data() { + local output_pattern="$1" + "$digitemp_bin" -c "$digitemprc" -q -a -o "$output_pattern" | grep -v ^Found +} + + +# find executable files in the search path starting with "digitemp_" +find_digitemp_executables() { + [ -z "${PATH:-}" ] && return + # split PATH by colons + local IFS=":" + # shellcheck disable=SC2086 + find $PATH -maxdepth 1 -xtype f -executable -name "digitemp_*" -print0 2>/dev/null \ + | xargs -0 -r -n 1 basename +} + + +if [ "$1" = "suggest" ]; then + find_digitemp_executables + exit 0 +fi + + +if [ "$1" = "autoconf" ]; then + if [ -z "$(find_digitemp_executables)" ]; then + echo "no (failed to find executable starting with 'digitemp_')" + elif [ ! -r "$digitemprc" ]; then + echo "no (failed to read configuration file: $digitemprc)" + else + echo "yes" + fi + exit 0 +fi + + +# check if the digitemp executable is available +if ! [ -x "$(which "$digitemp_bin")" ]; then + echo "executable '$digitemp_bin' not found" >&2 exit 1 fi @@ -58,14 +98,14 @@ echo 'graph_vlabel degrees C' echo 'graph_category sensors' echo "graph_info This graph shows the temperature read from $model 1-wire sensors" - $digitemp -c "$digitemprc" -q -a -o '%s %R' | grep -v ^Found | while read sensor serial; do - echo "sensor$serial.label sensor #$sensor" - echo "sensor$serial.type GAUGE" - echo "sensor$serial.info Temperature from sensor #$sensor" - echo "sensor$serial.critical 30" + get_sensor_data "%R %s" | while read -r serial sensor; do + echo "sensor$serial.label sensor #$sensor" + echo "sensor$serial.type GAUGE" + echo "sensor$serial.info Temperature from sensor #$sensor" + echo "sensor$serial.critical 30" echo "sensor$serial.warning 25" done exit 0 fi -$digitemp -c "$digitemprc" -q -a -o 'sensor%R.value %C'|grep -v ^Found +get_sensor_data "sensor%R.value %C" diff -Nru munin-2.0.37/plugins/node.d/ejabberd_.in munin-2.0.47/plugins/node.d/ejabberd_.in --- munin-2.0.37/plugins/node.d/ejabberd_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/ejabberd_.in 2019-02-28 14:43:36.000000000 +0000 @@ -114,7 +114,7 @@ configfile=${configfile:-} -EJCTL=$(which ejabberdctl 2>/dev/null) +EJCTL=$(which ejabberdctl 2>/dev/null) || true # get ejabberd PID # in GNU/Linux Debian Lenny release the pidof command can be executed only by root #EJPID=$(pidof -s /usr/lib/erlang/erts-5.6.3/bin/beam.smp) @@ -149,9 +149,9 @@ local vhosts # try to parse a single-line yaml list, e.g.: # hosts: ["foo.example.org", 'bar.example.com'] - vhosts=$(grep -E "^hosts:\s*\[" "$filename" \ + vhosts=$(grep -E '^hosts:\s*\[' "$filename" \ | sed -E 's/^.*\[(.+)].*$/\1/' \ - | tr "," "\n" \ + | tr ',' '\n' \ | sed -E 's/^.*["'\''](.+)["'\''].*$/\1/') if [ -z "$vhosts" ]; then # try to parse a multi-line yaml list, e.g.: @@ -160,7 +160,7 @@ # - 'bar.example.com' vhosts=$(grep -vE '^(\s*#|$)' "$filename" \ | sed -n '/^hosts:$/,/^\w/p;' \ - | grep "^\s*-" \ + | grep '^\s*-' \ | sed -E 's/^.+["'\''](.*)["'\'']\s*$/\1/') fi echo "$vhosts" @@ -207,7 +207,7 @@ return 1 else # we found a config (or its location was specified) - if echo "$configfile" | grep -qi "\.cfg$"; then + if echo "$configfile" | grep -qi '\.cfg$'; then vhosts=$(parse_vhosts_from_config_cfg "$configfile") else vhosts=$(parse_vhosts_from_config_yaml "$configfile") diff -Nru munin-2.0.37/plugins/node.d/exim_mailqueue.in munin-2.0.47/plugins/node.d/exim_mailqueue.in --- munin-2.0.37/plugins/node.d/exim_mailqueue.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/exim_mailqueue.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,8 @@ #!@@GOODSH@@ # -*- sh -*- +set -e + : << EOF =head1 NAME @@ -81,10 +83,7 @@ EOF # You cannot trust the exit status of which -EXIQGREP=$(which exiqgrep 2>/dev/null) -case $EXIQGREP:$? in - *:1|no*) EXIQGREP='' -esac +EXIQGREP=$(which exiqgrep 2>/dev/null) || true GRAPHTITLE='Exim Mailqueue' @@ -97,15 +96,15 @@ FROZENCRIT=${frozencrit:-200} if [ "$1" = "autoconf" ]; then - if [ -z "$EXIQGREP" ]; then - echo "no (no exiqgrep)" - exit 0 + if [ ! -x "$EXIQGREP" ]; then + echo "no (command exiqgrep not found)" + exit 0 else - echo yes + echo yes exit 0 fi fi - + if [ "$1" = "config" ]; then echo "graph_title $GRAPHTITLE" echo 'graph_args --base 1000 -l 0' diff -Nru munin-2.0.37/plugins/node.d/exim_mailstats.in munin-2.0.47/plugins/node.d/exim_mailstats.in --- munin-2.0.37/plugins/node.d/exim_mailstats.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/exim_mailstats.in 2019-02-28 14:43:36.000000000 +0000 @@ -2,6 +2,9 @@ # -*- perl -*- # vim:syntax=perl +use strict; +use warnings; + =head1 NAME exim_mailstats - Plugin to monitor the number of mails received and @@ -70,7 +73,6 @@ # In most installations the "use lib" can be removed as the Munin # modules are installed in perls module path. -use strict; use lib $ENV{'MUNIN_LIBDIR'}; use Munin::Plugin; @@ -141,7 +143,7 @@ if ($ARGV[0] and $ARGV[0] eq "autoconf") { if (defined($LOGDIR)) { if (! -d $LOGDIR) { - print "no (logdir does not exist)\n"; + print "no (logdir '$LOGDIR' does not exist)\n"; exit 0; } $logfile = $LOGDIR . '/' . ($LOGNAME || 'mainlog'); diff -Nru munin-2.0.37/plugins/node.d/fail2ban.in munin-2.0.47/plugins/node.d/fail2ban.in --- munin-2.0.37/plugins/node.d/fail2ban.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/fail2ban.in 2019-02-28 14:43:36.000000000 +0000 @@ -42,8 +42,7 @@ =head1 BUGS -Needs bash. Uses bashisms ${parm/?/pat/string} and $'...' to avoid -running external programs. +Needs bash, due zo using bashisms to avoid running external programs. =head1 AUTHOR @@ -65,13 +64,12 @@ # List jails, one on each line list_jails() { - ${client} status | while read line - do + "$client" status | while read -r line; do case $line in *'Jail list:'*) line="${line##*Jail list*:}" line="${line//[ $'\t']/}" - [ -n "$line" ] && printf "${line//,/$'\n'}\n" + if [ -n "$line" ]; then echo "${line//,/$'\n'}"; fi ;; esac done @@ -79,15 +77,13 @@ # Print the munin values values() { - list_jails | while read jail - do - ${client} status ${jail} | while read line - do + list_jails | while read -r jail; do + "$client" status "$jail" | while read -r line; do case $line in *'Currently banned'*) line="${line##*Currently banned:}" num="${line//[ $'\t']/}" - echo ${jail//[^0-9A-Za-z]/_}.value ${num} + echo "${jail//[^0-9A-Za-z]/_}.value $num" ;; esac done @@ -104,20 +100,16 @@ echo 'graph_args --base 1000 -l 0' echo 'graph_total total' - list_jails | while read jail - do - echo ${jail//[^0-9A-Za-z]/_}.label $jail + list_jails | while read -r jail; do + echo "${jail//[^0-9A-Za-z]/_}.label $jail" done } # Print autoconfiguration hint autoconf() { - if [ -e ${client} ] - then - if [ -x ${client} ] - then - if ${client} ping >/dev/null - then + if [ -e "$client" ]; then + if [ -x "$client" ]; then + if "$client" ping >/dev/null; then echo "yes" else echo "no (fail2ban-server does not respond to ping)" diff -Nru munin-2.0.37/plugins/node.d/foldingathome.in munin-2.0.47/plugins/node.d/foldingathome.in --- munin-2.0.37/plugins/node.d/foldingathome.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/foldingathome.in 2019-02-28 14:43:36.000000000 +0000 @@ -13,23 +13,16 @@ #%# family=contrib #%# capabilities=autoconf -PATH=/usr/local/fah -FILE=${file:=unitinfo.txt} +FOLDING_PATH=/usr/local/fah +data_filename=$FOLDING_PATH/${file:-unitinfo.txt} if [ "$1" = "autoconf" ]; then - if ( cat $PATH/$FILE 2>/dev/null >/dev/null ); then + if [ -r "$data_filename" ]; then echo yes - exit 0 else - if [ $? -eq 127 ] - then - echo "no (F@H not found)" - exit 0 - else - echo no - exit 0 - fi + echo "no (F@H file '$data_filename' not found)" fi + exit 0 fi if [ "$1" = "config" ]; then @@ -39,8 +32,8 @@ echo 'graph_vlabel % finished' echo 'done.label done folding' echo 'done.type GAUGE' - echo 'done.max 100''' + echo 'done.max 100' exit 0 fi -echo `/bin/grep "Progress" $PATH/$FILE | /bin/sed 's/^.*: \(.*\)%.*/done.value \1/'` +grep "Progress" "$data_filename" | /bin/sed 's/^.*: \(.*\)%.*/done.value \1/' diff -Nru munin-2.0.37/plugins/node.d/foldingathome_rank.in munin-2.0.47/plugins/node.d/foldingathome_rank.in --- munin-2.0.37/plugins/node.d/foldingathome_rank.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/foldingathome_rank.in 2019-02-28 14:43:36.000000000 +0000 @@ -11,35 +11,25 @@ # Magic markers (optional - used by munin-config and some installation # scripts): #%# family=contrib -#%# capabilities=autoconf statefile=$MUNIN_PLUGSTATE/plugin-fah_rank.state -if [ "$1" = "autoconf" ]; then - # No real check of anything - # echo yes - echo no - exit 0 -fi - if [ "$1" = "config" ]; then - echo 'graph_title Folding@Home Rank' echo 'graph_args -l 0 --base 1000' echo 'graph_vlabel rank' echo 'rank.label rank' echo 'rank.type GAUGE' - echo 'rank.max 12000''' + echo 'rank.max 12000' exit 0 fi -rank=`wget "http://vspx27.stanford.edu/cgi-bin/main.py?qtype=userpage&username=8d" -q -t 1 -T 5 -O - | egrep "" | sed 's/.* \([0-9]*\) .*/\1/'` -if [ "$rank" = "" ]; then - if [ -f $statefile ]; then - echo rank.value `cat $statefile` +rank=$(wget "http://vspx27.stanford.edu/cgi-bin/main.py?qtype=userpage&username=8d" -q -t 1 -T 5 -O - | grep -E "" | sed 's/.* \([0-9]*\) .*/\1/') +if [ -z "$rank" ]; then + if [ -f "$statefile" ]; then + echo "rank.value $(cat "$statefile")" fi else - echo $rank > $statefile - echo rank.value $rank + echo "$rank" >"$statefile" + echo "rank.value $rank" fi - diff -Nru munin-2.0.37/plugins/node.d/foldingathome_wu.in munin-2.0.47/plugins/node.d/foldingathome_wu.in --- munin-2.0.37/plugins/node.d/foldingathome_wu.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/foldingathome_wu.in 2019-02-28 14:43:36.000000000 +0000 @@ -27,7 +27,6 @@ =head1 MAGIC MARKERS #%# family=contrib - #%# capabilities=autoconf =cut @@ -35,15 +34,7 @@ statefile=$MUNIN_PLUGSTATE/plugin-fah_wu.state -if [ "$1" = "autoconf" ]; then - # Didn't check anything, which is meaningless in this case. - # echo yes - echo no - exit 0 -fi - if [ "$1" = "config" ]; then - echo 'graph_title Folding@Home Working Units submited' echo 'graph_args -l 0 --base 1000' echo 'graph_vlabel WU done' @@ -52,14 +43,13 @@ exit 0 fi -wu=$(wget "http://vspx27.stanford.edu/cgi-bin/main.py?qtype=userpage&username=8d" -q -t 1 -T 5 -O - | egrep -A 2 "" | grep "" | sed 's/.* \([0-9]*\) .*/\1/') +wu=$(wget "http://vspx27.stanford.edu/cgi-bin/main.py?qtype=userpage&username=8d" -q -t 1 -T 5 -O - | grep -E -A 2 "" | grep "" | sed 's/.* \([0-9]*\) .*/\1/') -if [ "$wu" = "" ]; then - if [ -f $statefile ]; then - echo wu.value `cat $statefile` +if [ -z "$wu" ]; then + if [ -f "$statefile" ]; then + echo "wu.value $(cat "$statefile")" fi else - echo $wu > $statefile - echo wu.value $wu + echo "$wu" > "$statefile" + echo "wu.value $wu" fi - diff -Nru munin-2.0.37/plugins/node.d/freeradius_acct.in munin-2.0.47/plugins/node.d/freeradius_acct.in --- munin-2.0.37/plugins/node.d/freeradius_acct.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/freeradius_acct.in 2019-02-28 14:43:36.000000000 +0000 @@ -43,7 +43,7 @@ =cut -RADMIN=${radmin:-`which radmin 2>/dev/null`} +RADMIN=${radmin:-$(which radmin 2>/dev/null)} RADMIN=${RADMIN:-/usr/sbin/radmin} SOCKETFILE=${socketfile:-/var/run/radiusd/radiusd.sock} @@ -59,6 +59,7 @@ echo 'graph_title FreeRADIUS Accounting Requests' echo 'graph_args --base 1000 -l 0 ' echo 'graph_period second' + # shellcheck disable=SC2016 echo 'graph_vlabel requests / ${graph_period}' echo 'graph_category Other' @@ -105,4 +106,4 @@ exit 0 fi -$RADMIN -f $SOCKETFILE -e "stats client acct" | awk '{print $1".value " $2}' +$RADMIN -f "$SOCKETFILE" -e "stats client acct" | awk '{print $1".value " $2}' diff -Nru munin-2.0.37/plugins/node.d/freeradius_auth.in munin-2.0.47/plugins/node.d/freeradius_auth.in --- munin-2.0.37/plugins/node.d/freeradius_auth.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/freeradius_auth.in 2019-02-28 14:43:36.000000000 +0000 @@ -43,7 +43,7 @@ =cut -RADMIN=${radmin:-`which radmin 2>/dev/null`} +RADMIN=${radmin:-$(which radmin 2>/dev/null)} RADMIN=${RADMIN:-/usr/sbin/radmin} SOCKETFILE=${socketfile:-/var/run/radiusd/radiusd.sock} @@ -59,6 +59,7 @@ echo 'graph_title FreeRADIUS Authentication Requests' echo 'graph_args --base 1000 -l 0 ' echo 'graph_period second' + # shellcheck disable=SC2016 echo 'graph_vlabel requests / ${graph_period}' echo 'graph_category Other' @@ -120,4 +121,4 @@ exit 0 fi -$RADMIN -f $SOCKETFILE -e "stats client auth" | awk '{print $1".value " $2}' +$RADMIN -f "$SOCKETFILE" -e "stats client auth" | awk '{print $1".value " $2}' diff -Nru munin-2.0.37/plugins/node.d/freeradius_proxy_acct.in munin-2.0.47/plugins/node.d/freeradius_proxy_acct.in --- munin-2.0.37/plugins/node.d/freeradius_proxy_acct.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/freeradius_proxy_acct.in 2019-02-28 14:43:36.000000000 +0000 @@ -43,7 +43,7 @@ =cut -RADMIN=${radmin:-`which radmin 2>/dev/null`} +RADMIN=${radmin:-$(which radmin 2>/dev/null)} RADMIN=${RADMIN:-/usr/sbin/radmin} SOCKETFILE=${socketfile:-/var/run/radiusd/radiusd.sock} @@ -59,6 +59,7 @@ echo 'graph_title FreeRADIUS Proxied Accounting Requests' echo 'graph_args --base 1000 -l 0 ' echo 'graph_period second' + # shellcheck disable=SC2016 echo 'graph_vlabel requests / ${graph_period}' echo 'graph_category Other' @@ -105,4 +106,4 @@ exit 0 fi -$RADMIN -f $SOCKETFILE -e "stats home_server acct" | awk '{print $1".value " $2}' +$RADMIN -f "$SOCKETFILE" -e "stats home_server acct" | awk '{print $1".value " $2}' diff -Nru munin-2.0.37/plugins/node.d/freeradius_proxy_auth.in munin-2.0.47/plugins/node.d/freeradius_proxy_auth.in --- munin-2.0.37/plugins/node.d/freeradius_proxy_auth.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/freeradius_proxy_auth.in 2019-02-28 14:43:36.000000000 +0000 @@ -43,7 +43,7 @@ =cut -RADMIN=${radmin:-`which radmin 2>/dev/null`} +RADMIN=${radmin:-$(which radmin 2>/dev/null)} RADMIN=${RADMIN:-/usr/sbin/radmin} SOCKETFILE=${socketfile:-/var/run/radiusd/radiusd.sock} @@ -59,6 +59,7 @@ echo 'graph_title FreeRADIUS Proxied Authentication Requests' echo 'graph_args --base 1000 -l 0 ' echo 'graph_period second' + # shellcheck disable=SC2016 echo 'graph_vlabel requests / ${graph_period}' echo 'graph_category Other' @@ -120,4 +121,4 @@ exit 0 fi -$RADMIN -f $SOCKETFILE -e "stats home_server auth" | awk '{print $1".value " $2}' +$RADMIN -f "$SOCKETFILE" -e "stats home_server auth" | awk '{print $1".value " $2}' diff -Nru munin-2.0.37/plugins/node.d/haproxy_ng.in munin-2.0.47/plugins/node.d/haproxy_ng.in --- munin-2.0.37/plugins/node.d/haproxy_ng.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/haproxy_ng.in 2019-02-28 14:43:36.000000000 +0000 @@ -4,17 +4,17 @@ # Copyright (C) 2012 Redpill Linpro AS # # Author: Trygve Vea -# +# # This program 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 program 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 program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. diff -Nru munin-2.0.37/plugins/node.d/hddtemp2.in munin-2.0.47/plugins/node.d/hddtemp2.in --- munin-2.0.37/plugins/node.d/hddtemp2.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/hddtemp2.in 2019-02-28 14:43:36.000000000 +0000 @@ -3,7 +3,7 @@ # # Plugin to monitor hard drive temperatures. # -# This plugin is an alternative to the hddtemp_smartctl, which is the +# This plugin is an alternative to the hddtemp_smartctl, which is the # preferred one. # # Requirements: diff -Nru munin-2.0.37/plugins/node.d/hddtempd.in munin-2.0.47/plugins/node.d/hddtempd.in --- munin-2.0.37/plugins/node.d/hddtempd.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/hddtempd.in 2019-02-28 14:43:36.000000000 +0000 @@ -3,7 +3,7 @@ # # Munin plugin to monitor hdd temperature from a hddtemp daemon. # -# This plugin is an alternative to the hddtemp_smartctl, which is the +# This plugin is an alternative to the hddtemp_smartctl, which is the # preferred one. # # Author: Stein Magnus Jodal @@ -81,7 +81,7 @@ ${$this}[0] =~ tr#_#/#; print "${$this}[0]\n"; } - + exit 0; } diff -Nru munin-2.0.37/plugins/node.d/hddtemp.in munin-2.0.47/plugins/node.d/hddtemp.in --- munin-2.0.37/plugins/node.d/hddtemp.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/hddtemp.in 2019-02-28 14:43:36.000000000 +0000 @@ -7,11 +7,12 @@ # the preferred one. # # client-conf.d/-options: -# +# # drives -- List drives to monitor. E.g. "hda hdc". # #%# family=contrib +drives=${drives:-} HDDTEMP=/usr/sbin/hddtemp if [ "$1" = "autoconf" ]; then @@ -30,9 +31,8 @@ echo 'graph_args --base 1000 -l 0' echo 'graph_vlabel Degrees Celsius' echo 'graph_category sensors' - for a in $drives ; do echo $a.label $a ; done + for a in $drives ; do echo "$a.label $a"; done exit 0 fi -for a in $drives ; do printf "$a.value $(hddtemp -n -q /dev/$a)\n" ; done - +for a in $drives ; do printf '%s.value %s\n' "$a" "$(hddtemp -n -q "/dev/$a")" ; done diff -Nru munin-2.0.37/plugins/node.d/hddtemp_smartctl.in munin-2.0.47/plugins/node.d/hddtemp_smartctl.in --- munin-2.0.37/plugins/node.d/hddtemp_smartctl.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/hddtemp_smartctl.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,9 @@ #!@@PERL@@ -w # -*- perl -*- +use strict; +use warnings; + =head1 NAME hddtemp_smartctl - Plugin to monitor harddrive temperatures through @@ -94,7 +97,6 @@ =cut -use strict; use File::Spec::Functions qw(splitdir); use lib $ENV{'MUNIN_LIBDIR'}; use Munin::Plugin; @@ -106,14 +108,16 @@ if (exists $ENV{smartctl}) { $smartctl = $ENV{smartctl}; if (defined $ARGV[0] and $ARGV[0] eq 'autoconf') { + # The real "autoconf" section follows later. But here we need to check for requirements, too. if (! -e $smartctl) { - print "no (Predefined smartctl ($smartctl) does not exist)\n"; - exit 0; + print "no (Predefined smartctl ($smartctl) does not exist)\n"; + exit 0; } elsif (! -x $smartctl) { - print "no (Predefined smartctl ($smartctl) is not executable)\n"; - exit 0; + print "no (Predefined smartctl ($smartctl) is not executable)\n"; + exit 0; } } else { + # immediate failure is allowed outside of "autoconf" die "$smartctl does not exist\n" unless (-e $smartctl); die "$smartctl is not executable\n" unless (-x $smartctl); } @@ -121,11 +125,20 @@ # Not defined in %ENV? Check obvious places my @dirs = split(':', $ENV{PATH}); push (@dirs, qw(/usr/bin /usr/sbin /usr/local/bin /usr/local/sbin) ); - + until ($smartctl or @dirs == 0) { - my $dir = shift @dirs; - my $path = $dir.'/smartctl'; - $smartctl = $path if -x $path; + my $dir = shift @dirs; + my $path = $dir.'/smartctl'; + $smartctl = $path if -x $path; + } + + unless ($smartctl) { + if (defined $ARGV[0] and $ARGV[0] eq 'autoconf') { + print "no ('smartctl' executable not found)\n"; + exit 0; + } else { + die "'smartctl' executable not found\n"; + } } } @@ -158,11 +171,19 @@ opendir(SCSI, '/sys/block/'); @drivesSCSI = grep /sd[a-z]/, readdir SCSI; closedir(SCSI); - } + } + + # Look for NVMe drives in /sys + my @drivesNVME; + if (-d '/sys/block/') { + opendir(NVME, '/sys/block/'); + @drivesNVME = grep /nvme[0-9]+n[0-9]+/, readdir NVME; + closedir(NVME); + } # Get list of all drives we found - @drives=(@drivesIDE,@drivesSCSI); - + @drives=(@drivesIDE,@drivesSCSI,@drivesNVME); + } elsif ($^O eq 'freebsd') { opendir(DEV, '/dev'); @drives = grep /^(ada?|da)[0-9]+$/, readdir DEV; @@ -182,11 +203,11 @@ if ($ARGV[0] eq 'autoconf') { if (@drives) { my $cmd = command_for_drive_device($drives[0], - device_for_drive($drives[0])); + device_for_drive($drives[0])); if (`$cmd` =~ /Temperature/) { - print "yes\n"; + print "yes\n"; } else { - print "no (first drive not supported, configure the plugin)\n"; + print "no (first drive not supported, configure the plugin)\n"; } exit 0; } else { @@ -217,9 +238,9 @@ # isn't supported (hdparm isn't available on all platforms). if (!$use_nocheck && $hdparm && $fulldev =~ /\/dev\/[sh]d?/) { if (`$hdparm -C $fulldev 2>/dev/null` =~ /standby/) { - warn "[DEBUG] Drive $fulldev is in standby mode, not checking\n" - if $DEBUG; - next; + warn "[DEBUG] Drive $fulldev is in standby mode, not checking\n" + if $DEBUG; + next; } } @@ -265,6 +286,8 @@ } elsif ($output =~ /^(190 (Airflow_Temperature_Cel|Temperature_Case).*)/m) { my @F = split ' ', $1; print "$drive.value $F[9]\n"; + } elsif ($output =~ /Temperature:\s*(\d+) Celsius/) { + print "$drive.value $1\n"; } else { print "$drive.value U\n"; print "$drive.extinfo Temperature not detected in smartctl output\n"; @@ -284,6 +307,7 @@ return $fulldev; } + sub command_for_drive_device { my ($drive, $fulldev, $use_nocheck) = @_; diff -Nru munin-2.0.37/plugins/node.d/http_loadtime.in munin-2.0.47/plugins/node.d/http_loadtime.in --- munin-2.0.37/plugins/node.d/http_loadtime.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/http_loadtime.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/sh +#!@@GOODSH@@ : << =cut @@ -38,7 +38,7 @@ target=${target:-"http://localhost/"} requisites=${requisites:-"false"} -urls=$(echo "$target" | tr "," "\n") +urls=$(echo "$target" | tr ',' '\n') request_url() { diff -Nru munin-2.0.37/plugins/node.d/ipac-ng.in munin-2.0.47/plugins/node.d/ipac-ng.in --- munin-2.0.37/plugins/node.d/ipac-ng.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/ipac-ng.in 2019-02-28 14:43:36.000000000 +0000 @@ -5,7 +5,7 @@ =head1 NAME -ipac-ng - Skeleton-plugin to monitor ipac-ng rules. +ipac-ng - Skeleton-plugin to monitor ipac-ng rules. =head1 CONFIGURATION @@ -41,34 +41,33 @@ if [ -x /usr/sbin/fetchipac ] && [ -x /usr/sbin/ipacsum ]; then echo yes exit 0 - else - echo no + else + echo "no (can not exectute /usr/sbin/fetchipac or /usr/sbin/ipacsum)" exit 0 - fi + fi fi if [ "$1" = "config" ]; then echo "graph_order down up" - echo "graph_title $TITLE" + echo "graph_title $TITLE" echo 'graph_args --base 1000' echo 'graph_vlabel b/s in (-) / out (+)' - echo 'down.label received' + echo 'down.label received' echo 'down.graph no' # Divide it by 1500 seconds (5m), to get b/s - echo 'down.cdef down,1500,/' - echo 'up.label b/s' + echo 'down.cdef down,1500,/' + echo 'up.label b/s' echo 'up.negative down' echo 'up.cdef up,1500,/' exit 0 fi; -fetchipac || error=1 -if [ "$error" != "1" ]; then +if fetchipac; then ipacsum -s 5m -x -f "$UP" | tail -n 1 | cut -d : -f 2 | awk \ - {'print "up.value " $1'} + '{print "up.value " $1}' ipacsum -s 5m -x -f "$DOWN" | tail -n 1 | cut -d : -f 2 | awk \ - {'print "down.value " $1'} + '{print "down.value " $1}' else - echo 'up.value 0' - echo 'down.value 0' + echo 'up.value U' + echo 'down.value U' fi diff -Nru munin-2.0.37/plugins/node.d/ipmi_.in munin-2.0.47/plugins/node.d/ipmi_.in --- munin-2.0.37/plugins/node.d/ipmi_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/ipmi_.in 2019-02-28 14:43:36.000000000 +0000 @@ -47,8 +47,8 @@ autoconf) type -p ipmitool &>/dev/null || { echo 'no (missing ipmitool command)' && exit 0; } - - ipmitool sensor &>/dev/null || + + ipmitool sensor &>/dev/null || { echo 'no (unable to access IPMI device)' && exit 0; } echo yes @@ -65,7 +65,7 @@ *_temp) MEASURE=temp;; *_fans) MEASURE=fans;; *_power) MEASURE=power;; - *) echo Please invoke as ipmi_temp or ipmi_fans >&2 + *) echo "Please invoke as ipmi_temp, ipmi_fans or ipmi_power" >&2 exit 1;; esac @@ -78,7 +78,7 @@ FANS = ""; TEMPS = ""; POWER = ""; - CFANS = "graph_title Fan speeds based on IPMI\ngraph_vlabel RPM\ngraph_category Sensors\n"; + CFANS = "graph_title Fan speeds based on IPMI\ngraph_vlabel RPM or %\ngraph_category Sensors\n"; CTEMPS = "graph_title Machine temperature based on IPMI\ngraph_vlabel Degrees celcius\ngraph_category Sensors\n"; CPOWER = "graph_title Power usage based on IPMI\ngraph_vlabel W\ngraph_category Sensors\n"; } @@ -119,7 +119,7 @@ } } -/RPM/ { +/(RPM|^Fan.*percent)/ { NAME=THING=$1; gsub(/[^A-Za-z0-9]/,"",NAME); SPEED=$2; diff -Nru munin-2.0.37/plugins/node.d/ipmi_sensor_.in munin-2.0.47/plugins/node.d/ipmi_sensor_.in --- munin-2.0.37/plugins/node.d/ipmi_sensor_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/ipmi_sensor_.in 2019-02-28 14:43:36.000000000 +0000 @@ -75,13 +75,13 @@ CONFIG = '@@CONFDIR@@/ipmi' - def normalize_sensor(name): - name = name.lower().replace("-","M").replace("+","P") - name = re.sub("[^a-z0-9A-Z]","_", name) + name = name.lower().replace("-", "M").replace("+", "P") + name = re.sub("[^a-z0-9A-Z]", "_", name) return name -def parse_data( data ): + +def parse_data(data): """ Parse the data returned by ipmitool get which should be of the following form: @@ -97,10 +97,10 @@ Upper Non-Critical : na Upper Critical : na Upper Non-Recoverable : na - Assertion Events : - Assertions Enabled : lcr- - Deassertions Enabled : lcr- - + Assertion Events : + Assertions Enabled : lcr- + Deassertions Enabled : lcr- + """ sensors = {} cur_sensor = None @@ -110,118 +110,126 @@ continue if line.startswith("Sensor ID"): label, data = line.split(":", 1) - idm = re.match("(.*) \((0x.*)\)", data) + idm = re.match(r"(.*) \((0x.*)\)", data) if not idm: continue id = idm.group(1).strip() - cur_sensor = { "id" : idm.group(2) } + cur_sensor = {"id": idm.group(2)} sensors[id] = cur_sensor if not cur_sensor: continue - label, data = line.split(":", 1) - cur_sensor[label.strip().lower()] = data.strip() + if ":" in line: + label, data = line.split(":", 1) + cur_sensor[label.strip().lower()] = data.strip() return sensors + def get_sensor_names(): try: - p = Popen(["ipmitool","-I","open","sensor"], shell=False, stdout=PIPE) + p = Popen(["ipmitool", "-I", "open", "sensor"], shell=False, stdout=PIPE) except OSError: return - data = p.stdout.readlines() + data = p.stdout.read().decode().splitlines() units = {} - for k,u in UNITS_TO_SENSORS.items(): + for k, u in UNITS_TO_SENSORS.items(): units[u['vlabel'].lower()] = k sensors = {} for line in data: - columns = [ s.strip() for s in line.split('|') ] + columns = [s.strip() for s in line.split('|')] key = units.get(columns[2].lower(), None) if key: lst = sensors.setdefault(key, []) - lst.append( columns[0] ) + lst.append(columns[0]) return sensors + def get_sensors(): - cache_filename = join(CACHEDIR,CACHEFILE) + cache_filename = join(CACHEDIR, CACHEFILE) try: mtime = stat(cache_filename)[ST_MTIME] except OSError: mtime = 0 curtime = time() - if curtime-mtime>CACHEAGE: - if not SENSORS: + if curtime - mtime > CACHEAGE: + if not SENSORS: try: - p = Popen(["ipmitool","-I","open","sensor"], shell=False, stdout=PIPE) + p = Popen(["ipmitool", "-I", "open", "sensor"], shell=False, stdout=PIPE) except OSError: return - else: + else: try: - p = Popen(["ipmitool","-I","open","sensor", "get", "--"] + SENSORS, shell=False, stdout=PIPE) + p = Popen(["ipmitool", "-I", "open", "sensor", "get", "--"] + SENSORS, + shell=False, stdout=PIPE) except OSError: return - data = p.stdout.read() + data = p.stdout.read().decode() try: - f = file(cache_filename,"w") - f.write(data) + with open(cache_filename, "w") as f: + f.write(data) except OSError: pass else: - data = file(cache_filename).read() + with open(cache_filename) as f: + data = f.read() return parse_data(data) + def query_unit(arg): - m = re.search( '_u_(.*)$', arg) + m = re.search('_u_(.*)$', arg) if not m: - raise RuntimeError("Could not figure which unit you want based on executable name") + sys.stderr.write("Could not determine which unit you want based on executable name. " + "Acceptable values: {}\n".format(" / ".join(get_sensor_names()))) + sys.exit(1) return m.group(1) UNITS_TO_SENSORS = { - 'volts' : { 'title' : "Voltages", - 'args' : '--base 1000', - 'vlabel' : 'Volts', - 'info' : "This graph shows the voltages as reported by IPMI", - 'sensors' : [ 'Voltage 2', ], - }, - 'degrees_c' : { 'title' : "Temperature", - 'args' : '--base 1000 -l 0', - 'vlabel' : 'Degrees C', - 'info' : "This graph shows the temperatures as reported by IPMI", - 'sensors' : [ 'Ambient Temp', ], - }, - 'rpm' : { 'title' : "RPMs", - 'args' : '--base 1000 -l 0', - 'vlabel' : 'RPM', - 'info' : "This graph shows the RPMs as reported by IPMI", - 'sensors' : ['FAN 1 RPM', 'FAN 2 RPM', 'FAN 3 RPM', 'FAN 4 RPM',], - }, - 'amps' : { 'title' : "Amperes", - 'args' : '--base 1000', - 'vlabel' : 'Amperes', - 'info' : "This graph shows the amperes as reported by IPMI", - 'sensors' : ['Current 2'], - }, - 'watts' : { 'title' : "Watts", - 'args' : '--base 1000', - 'vlabel' : 'Watts', - 'info' : "This graph shows the watts as reported by IPMI", - 'sensors' : ['System Level',], - }, + 'volts': { + 'title': "Voltages", + 'args': '--base 1000', + 'vlabel': 'Volts', + 'info': "This graph shows the voltages as reported by IPMI", + 'sensors': ['Voltage 2']}, + 'degrees_c': { + 'title': "Temperature", + 'args': '--base 1000 -l 0', + 'vlabel': 'Degrees C', + 'info': "This graph shows the temperatures as reported by IPMI", + 'sensors': ['Ambient Temp']}, + 'rpm': { + 'title': "RPMs", + 'args': '--base 1000 -l 0', + 'vlabel': 'RPM', + 'info': "This graph shows the RPMs as reported by IPMI", + 'sensors': ['FAN 1 RPM', 'FAN 2 RPM', 'FAN 3 RPM', 'FAN 4 RPM']}, + 'amps': { + 'title': "Amperes", + 'args': '--base 1000', + 'vlabel': 'Amperes', + 'info': "This graph shows the amperes as reported by IPMI", + 'sensors': ['Current 2']}, + 'watts': { + 'title': "Watts", + 'args': '--base 1000', + 'vlabel': 'Watts', + 'info': "This graph shows the watts as reported by IPMI", + 'sensors': ['System Level']}, } if access(CONFIG, R_OK): - for line in file(CONFIG): + for line in open(CONFIG): if line.strip().startswith('#'): continue - data = line.split('=',1) - if len(data)!=2: + data = line.split('=', 1) + if len(data) != 2: continue - unit,sensors = [ d.strip() for d in data ] + unit, sensors = [d.strip() for d in data] if unit not in UNITS_TO_SENSORS: continue - sensor_list = [ s.strip() for s in sensors.split(',') if s.strip() ] + sensor_list = [s.strip() for s in sensors.split(',') if s.strip()] UNITS_TO_SENSORS[unit]['sensors'] = sensor_list SENSORS = [] @@ -232,100 +240,110 @@ def config_unit(unit): info = UNITS_TO_SENSORS[unit] data = get_sensors() - print "graph_title IPMI Sensors:", info['title'] - print "graph_args", info['args'] - print "graph_vlabel", info['vlabel'] - print "graph_category sensors" - print "graph_info", info['info'] + print("graph_title IPMI Sensors:", info['title']) + print("graph_args", info['args']) + print("graph_vlabel", info['vlabel']) + print("graph_category sensors") + print("graph_info", info['info']) for lbl in info['sensors']: - values = data[lbl] + try: + values = data[lbl] + except KeyError: + continue nname = normalize_sensor(lbl) - - print "%s.label %s" % (nname, lbl) - assertions = values['assertions enabled'].split() + + print("%s.label %s" % (nname, lbl)) + # detect warning and critical ranges + try: + assertions = values['assertions enabled'].split() + except KeyError: + # Some devices do not provide assertions (e.g. power supplies). Thus there is no way + # to guess their warning/critical ranges. We can skip these. + continue warn_l = warn_u = crit_l = crit_u = "" if 'lcr-' in assertions: - crit_l = values['lower critical'].replace("na","") + crit_l = values['lower critical'].replace("na", "") if 'lnc-' in assertions: - warn_l = values['lower non-critical'].replace("na","") + warn_l = values['lower non-critical'].replace("na", "") if 'ucr+' in assertions: - crit_u = values['upper critical'].replace("na","") + crit_u = values['upper critical'].replace("na", "") if 'unc+' in assertions: - warn_u = values['upper non-critical'].replace("na","") - - #TODO add 'fans' - if 'rpm'==unit: - warn = "%s:%s" % (warn_u,warn_l) - crit = "%s:%s" % (crit_u,crit_l) - else: - warn = "%s:%s" % (warn_l,warn_u) - crit = "%s:%s" % (crit_l,crit_u) + warn_u = values['upper non-critical'].replace("na", "") + warn = "%s:%s" % (warn_l, warn_u) + crit = "%s:%s" % (crit_l, crit_u) + if warn != ":": + print("%s.warning %s" % (nname, warn)) + if crit != ":": + print("%s.critical %s" % (nname, crit)) - if warn!=":": - print "%s.warning %s" % (nname, warn) - if crit!=":": - print "%s.critical %s" % (nname, crit) - - def config(): unit = query_unit(sys.argv[0]) config_unit(unit) + def report_unit(unit): info = UNITS_TO_SENSORS[unit] data = get_sensors() for lbl in info['sensors']: nname = normalize_sensor(lbl) - value = data[lbl]["sensor reading"].split()[0] - print "%s.value %s" % (nname, value) - + try: + value = data[lbl]["sensor reading"].split()[0] + except KeyError: + continue + print("%s.value %s" % (nname, value)) + def report(): unit = query_unit(sys.argv[0]) report_unit(unit) + def autoconf(): data = get_sensors() if data: - print "yes" + print("yes") else: - print "no (no ipmitool output)" + print("no (no ipmitool output)") + def suggest(): names = get_sensor_names() if not access(CONFIG, F_OK): - f = file(CONFIG, "w") - for key, sensors in names.items(): - f.write("%s = %s\n" % (key, ",".join(sensors))) + with open(CONFIG, "w") as f: + for key, sensors in names.items(): + f.write("%s = %s\n" % (key, ",".join(sensors))) for key in names.keys(): - print "u_%s" % key + print("u_%s" % key) def debug(): - print SENSORS + print(SENSORS) data = get_sensors() for key, value in data.items(): - print "%s : %s (%s - %s) [%s - %s] %s" % (key, value['sensor reading'], - value['lower non-critical'], value['upper non-critical'], - value['lower critical'], value['upper critical'], - value['assertions enabled'],) + print("%s: %s (%s - %s) [%s - %s] %s" % (key, value['sensor reading'], + value['lower non-critical'], + value['upper non-critical'], + value['lower critical'], value['upper critical'], + value['assertions enabled'])) + def main(): - if len(sys.argv)>1: + if len(sys.argv) > 1: command = sys.argv[1] else: command = "" - if command=="autoconf": + if command == "autoconf": autoconf() - elif command=="suggest": + elif command == "suggest": suggest() - elif command=='config': + elif command == 'config': config() - elif command=='debug': + elif command == 'debug': debug() else: report() + if __name__ == "__main__": main() diff -Nru munin-2.0.37/plugins/node.d/ircu.in munin-2.0.47/plugins/node.d/ircu.in --- munin-2.0.37/plugins/node.d/ircu.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/ircu.in 2019-02-28 14:43:36.000000000 +0000 @@ -127,6 +127,6 @@ while(1) { $irc->do_one_loop(); -} +} # vim:syntax=perl diff -Nru munin-2.0.37/plugins/node.d/loggrep.in munin-2.0.47/plugins/node.d/loggrep.in --- munin-2.0.37/plugins/node.d/loggrep.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/loggrep.in 2019-02-28 14:43:36.000000000 +0000 @@ -129,7 +129,7 @@ if(-l $statefile) { die("$statefile is a symbolic link, refusing to touch it.\n"); -} +} open(my $out, '>', $statefile) or die("Can't write $statefile: $!\n"); for my $key (keys %regex) { print $out "$key=$regex{$key}{'value'}\n"; diff -Nru munin-2.0.37/plugins/node.d/lpstat.in munin-2.0.47/plugins/node.d/lpstat.in --- munin-2.0.37/plugins/node.d/lpstat.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/lpstat.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,9 @@ #!@@PERL@@ # -*- perl -*- +use strict; +use warnings; + =head1 NAME lpstat - Plugin to graph the queue size for the list of printers @@ -36,7 +39,6 @@ =cut -use strict; use Getopt::Std; my $printer; @@ -54,7 +56,7 @@ my $host = '127.0.0.1'; my $lpstat = exists $ENV{lpstat} ? $ENV{lpstat} : ''; - + # If the envvar is not set, look for lpstat if (!$lpstat) { # Still not found? Check obvious places @@ -72,7 +74,7 @@ undef $lpstat; } -if ($ARGV[0] eq 'autoconf') { +if (defined($ARGV[0]) && $ARGV[0] eq 'autoconf') { if( ! -x $lpstat ) { print "no (lpstat not found)\n"; exit 0; @@ -82,6 +84,11 @@ exit 0; } $_ = ; + if ( ! close(LPSTAT_R) ) { + print "no (lpstat returned non-zero)\n"; + exit 0; + } + if (! m/device for /mi) { print "no (no printers configured)\n"; exit 0; @@ -149,7 +156,7 @@ $jobs{$printer}=$n_jobs || 0; } -if ($ARGV[0] eq 'config') { +if ( defined($ARGV[0]) && $ARGV[0] eq 'config') { print "graph_title Print queues graph_args --base 1000 graph_vlabel Queued jobs diff -Nru munin-2.0.37/plugins/node.d/mailman.in munin-2.0.47/plugins/node.d/mailman.in --- munin-2.0.37/plugins/node.d/mailman.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/mailman.in 2019-02-28 14:43:36.000000000 +0000 @@ -55,7 +55,7 @@ } else { - $rotlogfile = $logfile . ".0"; + $rotlogfile = undef; } if($ARGV[0] and $ARGV[0] eq "config") { @@ -73,15 +73,14 @@ if(-f $logfile && -d $libdir && -x $lister ) { print "yes\n"; } else { - print "no\n"; + print "no (can not find file $logfile or dir $libdir or executable $lister)\n"; } exit 0; } if(! -f $logfile && ! -d $libdir && - ! -x $lister && - ! -f $rotlogfile) { + ! -x $lister) { print "posts.value U\n"; print "posts.extinfo Can't find any log files\n"; print "members.value U\n"; @@ -104,7 +103,9 @@ $startsize = 0; } elsif($startsize < $pos) { # Log rotated - parseMailmanLog($rotlogfile, $pos, (stat $rotlogfile)[7]); + if(defined $rotlogfile) { + parseMailmanLog($rotlogfile, $pos, (stat $rotlogfile)[7]); + } $pos = 0; } @@ -148,7 +149,7 @@ if (-e "$libdir/data") { @domains = ("."); } else { - opendir(DOMAINS, $libdir) or + opendir(DOMAINS, $libdir) or die "Can't open directory $libdir for reading: $!"; @domains = grep ( { !/^\@/ && !/^\./ && -d "$libdir/$_" } readdir(DOMAINS) ); @@ -161,7 +162,7 @@ my ($domain) = @_; opendir(LISTS, "$libdir/$domain/lists") or die "Can't open directory $libdir/$domain/lists for reading: $!"; - my @lists = grep ( { !/^\@/ && !/^\./ && -d "$libdir/$domain/lists/$_" } + my @lists = grep ( { !/^\@/ && !/^\./ && -d "$libdir/$domain/lists/$_" } readdir(LISTS) ); closedir(LISTS); return @lists; diff -Nru munin-2.0.37/plugins/node.d/mbmon_.in munin-2.0.47/plugins/node.d/mbmon_.in --- munin-2.0.37/plugins/node.d/mbmon_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/mbmon_.in 2019-02-28 14:43:36.000000000 +0000 @@ -21,24 +21,24 @@ #%# family=contrib #%# capabilities=autoconf suggest -what=`basename $0 | sed 's/^mbmon_//g'` +what=$(basename "$0" | sed 's/^mbmon_//g') +mbmon=${mbmon:-$(which mbmon)} + if [ "$1" = "suggest" ]; then - printf "TEMP\nFAN\nVoltage\n" + echo 'TEMP' + echo 'FAN' + echo 'Voltage' exit 0 fi if [ "$1" = "autoconf" ]; then - if $mbmon -c 1 > /dev/null 2>/dev/null ; then - printf "yes\n" - exit 0 + if [ -z "$mbmon" ] || [ ! -x "$mbmon" ]; then + echo "no (executable 'mbmon' not found)" + elif "$mbmon" -c 1 > /dev/null 2>/dev/null; then + echo "yes" else - if [ $?=127 ] ;then - echo "no (executable not found)" - else - echo "no (mbmon could not read sensor values)" - fi - exit 0 + echo "no (mbmon could not read sensor values)" fi exit 0 fi @@ -75,7 +75,7 @@ ;; FAN) echo 'graph_title Motherboard Fans' - echo 'graph_category sensors' + echo 'graph_category sensors' echo 'graph_order FAN0 FAN1 FAN2' echo 'graph_vlabel rpm' echo 'FAN0.label Fan 1' @@ -100,7 +100,3 @@ exit 0 ;; esac - - - - diff -Nru munin-2.0.37/plugins/node.d/memcached_.in munin-2.0.47/plugins/node.d/memcached_.in --- munin-2.0.37/plugins/node.d/memcached_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/memcached_.in 2019-02-28 14:43:36.000000000 +0000 @@ -32,17 +32,17 @@ #%# family=contrib #%# capabilities=noautoconf use strict; -my $ret = undef; +my $ret = undef; if (! eval "require Cache::Memcached;") { $ret = "Cache::Memcached not found"; -} +} my $HOST = exists $ENV{'host'} ? $ENV{'host'} : "127.0.0.1"; -my $PORT = exists $ENV{'port'} ? $ENV{'port'} : 11211; +my $PORT = exists $ENV{'port'} ? $ENV{'port'} : 11211; if ( exists $ARGV[0] and $ARGV[0] eq "autoconf" ) { if ($ret) { print "no ($ret)\n"; exit 0; - } + } # Todo: we can always connect to a memcache server without any errors so I cannot really # find a way to detect the presence of a memcache instance. Maybe a forced write/read/delete # but there should be a better way somewhere... @@ -53,7 +53,7 @@ if($ret) { print "no ($ret)\n"; exit 1; -} +} # We do everything by this array my %all_vars = ( @@ -227,7 +227,7 @@ } } exit 0; -} +} my $mc = new Cache::Memcached { 'servers' => [ "$HOST:$PORT" ] }; my $stats = $mc->stats ('misc'); diff -Nru munin-2.0.37/plugins/node.d/multiping.in munin-2.0.47/plugins/node.d/multiping.in --- munin-2.0.37/plugins/node.d/multiping.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/multiping.in 2019-02-28 14:43:36.000000000 +0000 @@ -54,10 +54,9 @@ =cut -if [ -z "$host" ]; then - file_host=$(basename $0 | sed 's/^ping_//g') - host=${host:-${file_host:-www.google.com}} -fi + +host=${host:-www.google.com} + if [ "$1" = "config" ]; then echo graph_title Ping times @@ -66,7 +65,7 @@ echo 'graph_category network' echo 'graph_info This graph shows ping RTT statistics.' for hosts in $host; do - site=`expr $site + 1` + site=$((site + 1)) echo "site$site.label $hosts" echo "site$site.info Ping RTT statistics for $hosts." echo "site$site.draw LINE2" @@ -76,11 +75,12 @@ exit 0 fi -for hosts in $host +for hosts in $host do - export site=$(expr $site + 1) - ${ping:-ping} ${ping_args:-'-c 2'} ${hosts} ${ping_args2} \ - | perl -n -e 'print "site$ENV{'site'}.value ", $1 / 1000, "\n" - if m@min/avg/max.*\s\d+(?:\.\d+)?/(\d+(?:\.\d+)?)/\d+(?:\.\d+)?@; - print "site$ENV{'site'}_packetloss.value $1\n" if /(\d+)% packet loss/;' + export site=$((site + 1)) + # shellcheck disable=SC2086 + "${ping:-ping}" ${ping_args:-'-c 2'} ${hosts} ${ping_args2:-} \ + | perl -n -e 'print "site$ENV{site}.value ", $1 / 1000, "\n" + if m@min/avg/max.*\s\d+(?:\.\d+)?/(\d+(?:\.\d+)?)/\d+(?:\.\d+)?@; + print "site$ENV{site}_packetloss.value $1\n" if /(\d+)% packet loss/;' done diff -Nru munin-2.0.37/plugins/node.d/multips.in munin-2.0.47/plugins/node.d/multips.in --- munin-2.0.37/plugins/node.d/multips.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/multips.in 2019-02-28 14:43:36.000000000 +0000 @@ -35,9 +35,6 @@ #%# family=manual #%# capabilities=autoconf -=head1 VERSION - - $Id$ =head1 BUGS @@ -53,15 +50,18 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" + + +names=${names:-} + if [ "$1" = "autoconf" ]; then if [ -z "$names" ]; then echo "no (Configuration required)" - exit 0 + else + echo yes fi - - echo yes exit 0 fi @@ -76,8 +76,8 @@ echo 'graph_category processes' echo 'graph_args --base 1000 --vertical-label processes -l 0' for name in $names; do - fieldname=$(clean_fieldname $name) - eval REGEX='"${regex_'$name'-\<'$name'\>}"' + fieldname=$(clean_fieldname "$name") + eval REGEX='"${regex_'"$name"'-\<'"$name"'\>}"' echo "$fieldname.label $name" echo "$fieldname.draw LINE2" @@ -89,13 +89,13 @@ fi for name in $names; do - fieldname=$(clean_fieldname $name) - printf "$fieldname.value " + fieldname=$(clean_fieldname "$name") + printf "%s.value " "$fieldname" - eval REGEX='"${regex_'$name'-\<'$name'\>}"' + eval REGEX='"${regex_'"$name"'-\<'"$name"'\>}"' PGREP=$(which pgrep) - if [ -n "$PGREP" -a -x "$PGREP" ]; then - $PGREP -f -l "$name" | grep "$REGEX" | wc -l + if [ -n "$PGREP" ] && [ -x "$PGREP" ]; then + "$PGREP" -f -l "$name" | grep "$REGEX" | wc -l elif [ -x /usr/ucb/ps ]; then # Solaris without pgrep. How old is that? /usr/ucb/ps auxwww | grep "$REGEX" | grep -v grep | wc -l diff -Nru munin-2.0.37/plugins/node.d/multips_memory.in munin-2.0.47/plugins/node.d/multips_memory.in --- munin-2.0.37/plugins/node.d/multips_memory.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/multips_memory.in 2019-02-28 14:43:36.000000000 +0000 @@ -70,7 +70,6 @@ 0.1 first release, based on multips as distributed in Debian. - $Id $ =head1 BUGS AND RESTRICTIONS @@ -99,15 +98,16 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" + +names=${names:-} if [ "$1" = "autoconf" ]; then if [ -z "$names" ]; then - echo "no (Configuration required)" - exit 0 + echo "no (Configuration required)" + else + echo yes fi - - echo yes exit 0 fi @@ -119,7 +119,7 @@ monitor=${monitor:-rss} if [ "$1" = "config" ]; then - echo graph_title Process $monitor summed by name + echo "graph_title Process $monitor summed by name" echo 'graph_category processes' echo 'graph_args --base 1024 -l 0' echo 'graph_vlabel memory' @@ -137,8 +137,8 @@ for name in $names; do fieldname="$(clean_fieldname "$name")" - ps -eo $monitor,comm | gawk ' -BEGIN { total = "U"; } # U = Unknown. + ps -eo "$monitor,comm" | gawk ' +BEGIN { total = "U"; } # U = Unknown. /grep/ { next; } $2 ~ /^'"$name"'$/ { total = total + ($1*1024); } END { print "'"$fieldname"'.value", total; }' diff -Nru munin-2.0.37/plugins/node.d/munin_stats.in munin-2.0.47/plugins/node.d/munin_stats.in --- munin-2.0.37/plugins/node.d/munin_stats.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/munin_stats.in 2019-02-28 14:43:36.000000000 +0000 @@ -48,7 +48,7 @@ if ($ARGV[0] and $ARGV[0] eq 'autoconf') { - my $munin_update_location = + my $munin_update_location = "$Munin::Common::Defaults::MUNIN_LIBDIR/munin-update"; if (! -e $munin_update_location) { @@ -59,7 +59,7 @@ if (! -x $munin_update_location) { print "no ($munin_update_location was found, but is not executable)\n"; exit 0; - } + } else { print "yes\n"; exit 0; diff -Nru munin-2.0.37/plugins/node.d/munin_update.in munin-2.0.47/plugins/node.d/munin_update.in --- munin-2.0.37/plugins/node.d/munin_update.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/munin_update.in 2019-02-28 14:43:36.000000000 +0000 @@ -58,9 +58,6 @@ are two hosts with the same host name in different domains then one of them will be disappeared by the munin-update collection process. -=head1 VERSION - - $Id$ =head1 AUTHOR @@ -77,20 +74,17 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" -if [ -z "$UPDATE_STATSFILE" ]; then - UPDATE_STATSFILE="$MUNIN_DBDIR/munin-update.stats" -fi -if [ -z "$MUNIN_UPDATE_LOCATION" ]; then - MUNIN_UPDATE_LOCATION="$MUNIN_LIBDIR/munin-update"; -fi +UPDATE_STATSFILE=${UPDATE_STATSFILE:-$MUNIN_DBDIR/munin-update.stats} +MUNIN_UPDATE_LOCATION=${MUNIN_UPDATE_LOCATION:-$MUNIN_LIBDIR/munin-update} + if [ "$1" = "autoconf" ]; then if [ -e "$MUNIN_UPDATE_LOCATION" ] ; then echo "yes"; - else + else echo "no ($MUNIN_UPDATE_LOCATION is not present so this is not a munin-master)" fi exit 0 @@ -109,8 +103,8 @@ echo 'graph_vlabel seconds' echo 'graph_category munin' echo 'graph_info This graph shows the time it takes to collect data from each hosts that munin collects data on. Munin-master is run from cron every 5 minutes and we want each of the munin-update runs to complete before the next one starts. If munin-update uses too long time to run on one host run it with --debug to determine which plugin(s) are slow and solve the problem with them if possible.' - sed '/^UD|/!d; s/.*;//; s/|/ /;' < $UPDATE_STATSFILE | sort | - while read i j; do + sed '/^UD|/!d; s/.*;//; s/|/ /;' < "$UPDATE_STATSFILE" | sort | + while read -r i j; do name="$(clean_fieldname "$i")" echo "$name.label $i" echo "$name.warning 240" @@ -119,14 +113,14 @@ exit 0 fi -[ -f $UPDATE_STATSFILE ] || { +[ -f "$UPDATE_STATSFILE" ] || { echo 'error.value 1' echo "error.extinfo Plugin cannot read stats file $UPDATE_STATSFILE" exit 0 } -sed '/^UD|/!d; s/.*;//; s/|/ /;' < $UPDATE_STATSFILE | sort | -while read i j; do +sed '/^UD|/!d; s/.*;//; s/|/ /;' < "$UPDATE_STATSFILE" | sort | +while read -r i j; do name="$(clean_fieldname "$i")" echo "$name.value $j" done diff -Nru munin-2.0.37/plugins/node.d/mysql_bytes.in munin-2.0.47/plugins/node.d/mysql_bytes.in --- munin-2.0.37/plugins/node.d/mysql_bytes.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/mysql_bytes.in 2019-02-28 14:43:36.000000000 +0000 @@ -33,18 +33,14 @@ =cut -MYSQLOPTS="$mysqlopts"; +MYSQLOPTS="${mysqlopts:-}" MYSQLADMIN=${mysqladmin:-mysqladmin} if [ "$1" = "autoconf" ]; then - $MYSQLADMIN --version 2>/dev/null >/dev/null - if [ $? -eq 0 ] - then - $MYSQLADMIN $MYSQLOPTS extended-status 2>/dev/null >/dev/null - if [ $? -eq 0 ] - then + if "$MYSQLADMIN" --version 2>/dev/null >/dev/null; then + # shellcheck disable=SC2086 + if "$MYSQLADMIN" $MYSQLOPTS extended-status 2>/dev/null >/dev/null; then echo yes - exit 0 else echo "no (could not connect to mysql)" fi @@ -57,6 +53,7 @@ if [ "$1" = "config" ]; then echo 'graph_title MySQL throughput' echo 'graph_args --base 1024' + # shellcheck disable=SC2016 echo 'graph_vlabel bytes received (-) / sent (+) per ${graph_period}' echo 'graph_info Note that this is a old plugin which is no longer installed by default. It is retained for compatability with old installations.' echo 'graph_category mysql' @@ -75,4 +72,6 @@ exit 0 fi -($MYSQLADMIN $MYSQLOPTS extended-status 2>/dev/null || ( echo Bytes_sent a a U; echo Bytes_received a a U)) | awk '/Bytes_sent/ { print "sent.value " $4} /Bytes_received/ { print "recv.value " $4}' +# shellcheck disable=SC2086 +("$MYSQLADMIN" $MYSQLOPTS extended-status 2>/dev/null || ( echo Bytes_sent a a U; echo Bytes_received a a U)) \ + | awk '/Bytes_sent/ { print "sent.value " $4} /Bytes_received/ { print "recv.value " $4}' diff -Nru munin-2.0.37/plugins/node.d/mysql_.in munin-2.0.47/plugins/node.d/mysql_.in --- munin-2.0.37/plugins/node.d/mysql_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/mysql_.in 2019-02-28 14:43:36.000000000 +0000 @@ -1017,7 +1017,6 @@ } print "graph_category mysql2\n"; - my $i = 0; for my $ds (@{$graph->{data_sources}}) { my %ds_spec = ( %{$defaults{data_source_attrs}}, @@ -1025,20 +1024,8 @@ %$ds, ); while (my ($k, $v) = each %ds_spec) { - # 'name' is only used internally in this script, not - # understood by munin. - next if ($k eq 'name'); - - # AREASTACK is part of munin as of version 1.3.3 (not - # released yet). Until then ... - if ($k eq 'draw' && $v eq 'AREASTACK') { - printf("%s.%s %s\n", - clean_fieldname($ds->{name}), $k, ($i ? 'STACK' : 'AREA')); - } - else { - printf("%s.%s %s\n", clean_fieldname($ds->{name}), $k, $v); - } - $i++; + # 'name' is only used internally in this script, not understood by munin. + printf("%s.%s %s\n", clean_fieldname($ds->{name}), $k, $v) unless ($k eq 'name'); } print_thresholds(clean_fieldname($ds->{name})); } diff -Nru munin-2.0.37/plugins/node.d/mysql_innodb.in munin-2.0.47/plugins/node.d/mysql_innodb.in --- munin-2.0.37/plugins/node.d/mysql_innodb.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/mysql_innodb.in 2019-02-28 14:43:36.000000000 +0000 @@ -99,8 +99,12 @@ WARNING=${warning:-2147483648} # 2GB CRITICAL=${critical:-1073741824} # 1GB -# Convenient variables -MEXEC="$MYSQL $MYSQLOPTS --batch --skip-column-names --database=information_schema --execute" + +mysql_exec() { + # shellcheck disable=SC2086 + "$MYSQL" $MYSQLOPTS --batch --skip-column-names --database=information_schema --execute +} + ## No user serviceable parts below print_config() { @@ -112,26 +116,26 @@ echo 'free.label Bytes free' echo 'free.type GAUGE' echo 'free.min 0' - echo 'free.warning' $WARNING: - echo 'free.critical' $CRITICAL: + echo "free.warning $WARNING:" + echo "free.critical $CRITICAL:" exit 0 } print_data() { - innodb_free | xargs -r printf "free.value %s\n" + innodb_free | xargs -r printf 'free.value %s\n' } check_autoconf() { # Check client - if [ ! -x $MYSQL ]; then + if [ ! -x "$MYSQL" ]; then echo "no ($MYSQL not executable)" return 0 fi # Check server - $MEXEC "select(1);" | \ - while read res; do + mysql_exec "select(1);" | \ + while read -r res; do case $res in 1) # All is well @@ -143,8 +147,9 @@ esac done - $MEXEC "SHOW VARIABLES LIKE 'innodb_file_per_table';" | \ - while read var res; do + # shellcheck disable=SC2034 + mysql_exec "SHOW VARIABLES LIKE 'innodb_file_per_table';" | \ + while read -r var res; do case $res in OFF) # All is well @@ -160,8 +165,8 @@ esac done - $MEXEC "SELECT count(*) FROM tables WHERE ENGINE = 'InnoDB';" | \ - while read res; do + mysql_exec "SELECT count(*) FROM tables WHERE ENGINE = 'InnoDB';" | \ + while read -r res; do if [ "$res" = "0" ]; then echo "no (No visible tables use InnoDB)" return 0 @@ -174,14 +179,14 @@ # Get major.minor version of the server mysql_version() { - $MEXEC "SELECT version();" | awk '{printf "%1.1f", $1}' + mysql_exec "SELECT version();" | awk '{printf "%1.1f", $1}' } # InnoDB free bytes for MySQL 5.1 and newer innodb_free_new() { - t=$($MEXEC "SELECT count(*) FROM tables WHERE ENGINE = 'InnoDB';") - if [ "$t" ">" "0" ]; then - $MEXEC "SELECT data_free FROM tables WHERE ENGINE = 'InnoDB' LIMIT 1;" + t=$(mysql_exec "SELECT count(*) FROM tables WHERE ENGINE = 'InnoDB';") + if [ "$t" -gt "0" ]; then + mysql_exec "SELECT data_free FROM tables WHERE ENGINE = 'InnoDB' LIMIT 1;" else echo >&2 "$0: Error: No visible tables use InnoDB" echo U @@ -191,14 +196,15 @@ # InnoDB free bytes for MySQL 5.0 and older innodb_free_old() { - $MEXEC "SELECT table_comment FROM tables WHERE ENGINE = 'InnoDB' LIMIT 1;" \ + mysql_exec "SELECT table_comment FROM tables WHERE ENGINE = 'InnoDB' LIMIT 1;" \ | awk '/^InnoDB free:/ {print $3 * 1024}' } # InnoDB free bytes wrapper innodb_free() { ver=$(mysql_version) - if [ "$ver" ">" "5.0" ]; then + major_version=$(echo "$ver" | cut -f 1 -d ".") + if [ "$major_version" -ge "5" ]; then case $ver in 5.0.*|5.1.?|5.1.1?|5.1.2[0123]) innodb_free_old diff -Nru munin-2.0.37/plugins/node.d/mysql_queries.in munin-2.0.47/plugins/node.d/mysql_queries.in --- munin-2.0.37/plugins/node.d/mysql_queries.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/mysql_queries.in 2019-02-28 14:43:36.000000000 +0000 @@ -111,7 +111,7 @@ ); $num++; } - + } diff -Nru munin-2.0.37/plugins/node.d/mysql_slowqueries.in munin-2.0.47/plugins/node.d/mysql_slowqueries.in --- munin-2.0.37/plugins/node.d/mysql_slowqueries.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/mysql_slowqueries.in 2019-02-28 14:43:36.000000000 +0000 @@ -29,18 +29,14 @@ =cut -MYSQLOPTS="$mysqlopts" +MYSQLOPTS=${mysqlopts:-} MYSQLADMIN=${mysqladmin:-mysqladmin} if [ "$1" = "autoconf" ]; then - $MYSQLADMIN --version 2>/dev/null >/dev/null - if [ $? -eq 0 ] - then - $MYSQLADMIN $MYSQLOPTS status 2>/dev/null >/dev/null - if [ $? -eq 0 ] - then + if "$MYSQLADMIN" --version 2>/dev/null >/dev/null; then + # shellcheck disable=SC2086 + if "$MYSQLADMIN" $MYSQLOPTS status 2>/dev/null >/dev/null; then echo yes - exit 0 else echo "no (could not connect to mysql)" fi @@ -53,6 +49,7 @@ if [ "$1" = "config" ]; then echo 'graph_title MySQL slow queries' echo 'graph_args --base 1000 -l 0' + # shellcheck disable=SC2016 echo 'graph_vlabel slow queries / ${graph_period}' echo 'graph_category mysql' echo 'graph_info Note that this is a old plugin which is no longer installed by default. It is retained for compatability with old installations.' @@ -65,4 +62,5 @@ fi /usr/bin/printf "queries.value " -($MYSQLADMIN $MYSQLOPTS status 2>/dev/null || echo a a a a a a a a U) | awk '{print $9}' +# shellcheck disable=SC2086 +("$MYSQLADMIN" $MYSQLOPTS status 2>/dev/null || echo a a a a a a a a U) | awk '{print $9}' diff -Nru munin-2.0.37/plugins/node.d/mysql_threads.in munin-2.0.47/plugins/node.d/mysql_threads.in --- munin-2.0.37/plugins/node.d/mysql_threads.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/mysql_threads.in 2019-02-28 14:43:36.000000000 +0000 @@ -42,18 +42,14 @@ =cut -MYSQLOPTS="$mysqlopts" +MYSQLOPTS=${mysqlopts:-} MYSQLADMIN=${mysqladmin:-mysqladmin} if [ "$1" = "autoconf" ]; then - $MYSQLADMIN --version 2>/dev/null >/dev/null - if [ $? -eq 0 ] - then - $MYSQLADMIN $MYSQLOPTS status 2>/dev/null >/dev/null - if [ $? -eq 0 ] - then + if "$MYSQLADMIN" --version 2>/dev/null >/dev/null; then + # shellcheck disable=SC2086 + if "$MYSQLADMIN" $MYSQLOPTS status 2>/dev/null >/dev/null; then echo yes - exit 0 else echo "no (could not connect to mysql)" fi @@ -68,11 +64,12 @@ echo 'graph_vlabel threads' echo 'graph_category mysql' echo 'graph_info Note that this is a old plugin which is no longer installed by default. It is retained for compatability with old installations.' - + echo 'threads.label mysql threads' echo 'graph_args --base 1000' exit 0 fi /usr/bin/printf "threads.value " -($MYSQLADMIN $MYSQLOPTS status 2>/dev/null || echo 'a a a U') | awk '{print $4}' +# shellcheck disable=SC2086 +("$MYSQLADMIN" $MYSQLOPTS status 2>/dev/null || echo 'a a a U') | awk '{print $4}' diff -Nru munin-2.0.37/plugins/node.d/named.in munin-2.0.47/plugins/node.d/named.in --- munin-2.0.37/plugins/node.d/named.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/named.in 2019-02-28 14:43:36.000000000 +0000 @@ -71,79 +71,79 @@ =cut -if [ -n "$logfile" ]; then + +if [ -n "${logfile:-}" ]; then SYSLOGFILE=$logfile -else +else if [ -f /var/adm/messages ]; then - SYSLOGFILE=/var/adm/messages + SYSLOGFILE=/var/adm/messages else - SYSLOGFILE=/var/log/daemon.log + SYSLOGFILE=/var/log/daemon.log fi fi # ---------------------------------------------------------------------- pick_stat () { - ret=`echo "$2" | sed "s/.* *$1=\([0-9]*\).*/\1/"` + ret=$(echo "$2" | sed 's/.* *'"$1"'=\([0-9]*\).*/\1/') if [ ! "$ret" ]; then - echo 0; + echo 0 else - echo $ret + echo "$ret" fi } do_stats () { - if [ ! -f $SYSLOGFILE ] ; then - echo $SYSLOGFILE is unavailable to me >&2 - exit 1 + if [ ! -f "$SYSLOGFILE" ]; then + echo "$SYSLOGFILE is unavailable to me" >&2 + exit 1 fi # Get out the last XSTATS and NSTATS lines - XSTATS=`grep 'named.*XSTATS' "$SYSLOGFILE" | tail -1` - # NSTATS=`grep 'named.*NSTATS' "$SYSLOGFILE" | tail -1` + XSTATS=$(grep 'named.*XSTATS' "$SYSLOGFILE" | tail -1) + # NSTATS=$(grep 'named.*NSTATS' "$SYSLOGFILE" | tail -1) # We concentrate on what clients communicate with us about # and counters that we suspect can indicate abuse or error conditions - # Received Queries: Total volume of queries received. + # Received Queries: Total volume of queries received. # This should be nice and smooth. - echo "queries.value `pick_stat RQ "$XSTATS"`" + echo "queries.value $(pick_stat RQ "$XSTATS")" # Sent Answers: This should be the same as RQ except when there are # errors. May not be very interesting. - echo "answers.value `pick_stat SAns "$XSTATS"`" + echo "answers.value $(pick_stat SAns "$XSTATS")" # Sent and Forwarded queries, in a proxy setting this should be # the same as Received Queries (?) - echo "forwarded.value `pick_stat SFwdQ "$XSTATS"`" + echo "forwarded.value $(pick_stat SFwdQ "$XSTATS")" # Received Zone Transfer queries - should be low. High value could # indicate some odd error or some kind of abuse - echo "axfr.value `pick_stat RAXFR "$XSTATS"`" # Received AXFR Qs + echo "axfr.value $(pick_stat RAXFR "$XSTATS")" # Received AXFR Qs # Received TCP connections: These are used for zone transfers or # oversized (>512 byte) answers. A high value here could indicate # that you need to trim down the size of your answers somehow (Do you # have a ton of MXes or NSes that gets reported back?), or this could # be due to an error. Or it could be due to abuse. - echo "tcp.value `pick_stat RTCP "$XSTATS"`" - - # Get a total of errors - errexpr=" - `pick_stat RNXD "$XSTATS"` + - `pick_stat RFail "$XSTATS"` + - `pick_stat RErr "$XSTATS"` + - `pick_stat SErr "$XSTATS"` + - `pick_stat RIQ "$XSTATS"` + - `pick_stat RFErr "$XSTATS"` "; + echo "tcp.value $(pick_stat RTCP "$XSTATS")" - echo "errors.value `expr $errexpr`" + # Get a total of errors + local error_value + error_value=$(( $(pick_stat RNXD "$XSTATS") + + $(pick_stat RFail "$XSTATS") + + $(pick_stat RErr "$XSTATS") + + $(pick_stat SErr "$XSTATS") + + $(pick_stat RIQ "$XSTATS") + + $(pick_stat RFErr "$XSTATS") )) + echo "errors.value $error_value" } case $1 in config) - cat <<'EOF' + cat <<'EOF' graph_title BIND DNS Query statistics graph_vlabel Queries / ${graph_period} graph_scale no @@ -166,8 +166,8 @@ errors.type DERIVE errors.min 0 EOF - exit 0 - ;; + exit 0 + ;; esac do_stats diff -Nru munin-2.0.37/plugins/node.d/netopia.in munin-2.0.47/plugins/node.d/netopia.in --- munin-2.0.37/plugins/node.d/netopia.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/netopia.in 2019-02-28 14:43:36.000000000 +0000 @@ -6,17 +6,18 @@ if [ "$1" = "config" ]; then echo "host_name $hostname" - echo "graph_order down up" + echo "graph_order down up" echo "graph_title ADSL Traffic" echo 'graph_args --base 1000' + # shellcheck disable=SC2016 echo 'graph_vlabel bits in (-) / out (+) per ${graph_period}' echo 'down.label received' - echo 'down.type DERIVE' - echo 'down.graph no' - echo 'down.cdef down,8,*' + echo 'down.type DERIVE' + echo 'down.graph no' + echo 'down.cdef down,8,*' echo "down.max $DOWNMAX" echo "down.min 0" - echo 'up.label bps' + echo 'up.label bps' echo 'up.type DERIVE' echo 'up.negative down' echo 'up.cdef up,8,*' @@ -26,6 +27,6 @@ fi; printf "down.value " -snmpget -Ov $hostname $COMMUNITY interfaces.ifTable.ifEntry.ifInOctets.3 | sed 's/^.*: //' +snmpget -Ov "$hostname" "$COMMUNITY" interfaces.ifTable.ifEntry.ifInOctets.3 | sed 's/^.*: //' printf "up.value " -snmpget -Ov $hostname $COMMUNITY interfaces.ifTable.ifEntry.ifOutOctets.3 | sed 's/^.*: //' +snmpget -Ov "$hostname" "$COMMUNITY" interfaces.ifTable.ifEntry.ifOutOctets.3 | sed 's/^.*: //' diff -Nru munin-2.0.37/plugins/node.d/netstat.in munin-2.0.47/plugins/node.d/netstat.in --- munin-2.0.37/plugins/node.d/netstat.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/netstat.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,15 +1,17 @@ #!@@GOODSH@@ # -*- sh -*- +set -e + : << =cut =head1 NAME -netstat - Plugin to monitor network connections. +netstat - Plugin to monitor network connections =head1 CONFIGURATION -No configuration for this plugin +No configuration =head1 AUTHOR @@ -21,32 +23,27 @@ =head1 MAGIC MARKERS -=begin comment - -These magic markers are used by munin-node-configure when installing -munin-node. - -=end comment - #%# family=auto #%# capabilities=autoconf =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" + +NETSTAT_CMD=netstat if [ "$1" = "autoconf" ]; then - if ( netstat -s 2>/dev/null >/dev/null ); then + if ( "$NETSTAT_CMD" -s 2>/dev/null >/dev/null ); then echo yes exit 0 else if [ $? -eq 127 ] then - echo "no (netstat program not found)" + echo "no (program $NETSTAT_CMD not found)" exit 0 else - echo no + echo "no (unknown netstat return value $?)" exit 0 fi fi @@ -56,7 +53,7 @@ echo 'graph_title Netstat' echo 'graph_args --base 1000 --logarithmic' - echo 'graph_vlabel active connections per ${graph_period}' + echo 'graph_vlabel TCP connections' echo 'graph_category network' echo 'graph_period second' echo 'graph_info This graph shows the TCP activity of all the network interfaces combined.' @@ -98,7 +95,7 @@ exit 0 fi -netstat -s | awk ' +"$NETSTAT_CMD" -s | awk ' /connection requests/ { print "active.value " $1 } /connection accepts/ { print "passive.value " $1 } /bad connection/ { print "failed.value " $1 } diff -Nru munin-2.0.37/plugins/node.d/nginx_request.in munin-2.0.47/plugins/node.d/nginx_request.in --- munin-2.0.37/plugins/node.d/nginx_request.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/nginx_request.in 2019-02-28 14:43:36.000000000 +0000 @@ -66,7 +66,6 @@ } my $URL = exists $ENV{'url'} ? $ENV{'url'} : "http://localhost/nginx_status"; -my $port = exists $ENV{'port'} ? $ENV{'port'} : "80"; if ( exists $ARGV[0] and $ARGV[0] eq "autoconf" ) { @@ -74,7 +73,7 @@ print "no ($ret)\n"; exit 0; } - + my $ua = LWP::UserAgent->new(timeout => 30, agent => sprintf("munin/%s (libwww-perl/%s)", $Munin::Common::Defaults::MUNIN_VERSION, $LWP::VERSION)); my $response = $ua->request(HTTP::Request->new('GET',$URL)); @@ -99,9 +98,9 @@ print "graph_vlabel Requests per \${graph_period}\n"; print "request.type DERIVE\n"; print "request.min 0\n"; - print "request.label requests port $port\n"; + print "request.label requests\n"; print "request.draw LINE\n"; - + exit 0; } diff -Nru munin-2.0.37/plugins/node.d/nginx_status.in munin-2.0.47/plugins/node.d/nginx_status.in --- munin-2.0.37/plugins/node.d/nginx_status.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/nginx_status.in 2019-02-28 14:43:36.000000000 +0000 @@ -120,10 +120,10 @@ my $response = $ua->request(HTTP::Request->new('GET',$URL)); -#Active connections: 1845 +#Active connections: 1845 #server accepts handled requests -# 4566318 4566318 84218236 -# Reading: 2 Writing: 278 Waiting: 1565 +# 4566318 4566318 84218236 +# Reading: 2 Writing: 278 Waiting: 1565 if ($response->content =~ /Active connections:\s+(\d+).*Reading:\s+(\d+).*Writing:\s+(\d+).*Waiting:\s+(\d+)/s) { print "total.value $1\n"; print "reading.value $2\n"; diff -Nru munin-2.0.37/plugins/node.d/nomadix_users_.in munin-2.0.47/plugins/node.d/nomadix_users_.in --- munin-2.0.37/plugins/node.d/nomadix_users_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/nomadix_users_.in 2019-02-28 14:43:36.000000000 +0000 @@ -97,7 +97,7 @@ # Checking if snmpwalk is found and executable if(! -x ${snmpwalk}){ ${status}=2; - print STDERR "Error: " . ${snmpwalk} . " not found.\n"; + print STDERR "Error: " . ${snmpwalk} . " not found.\n"; if(${debug}){ print "Exit code: " . ${status} . "\n"; } diff -Nru munin-2.0.37/plugins/node.d/ntp_.in munin-2.0.47/plugins/node.d/ntp_.in --- munin-2.0.37/plugins/node.d/ntp_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/ntp_.in 2019-02-28 14:43:36.000000000 +0000 @@ -128,6 +128,8 @@ if (lc($srcadr) ne lc($name)) { my @addresses; my $resolver = Net::DNS::Resolver->new; + $resolver->tcp_timeout(5); + $resolver->udp_timeout(5); my $query = $resolver->search($name, "AAAA"); if ($query) { diff -Nru munin-2.0.37/plugins/node.d/ntp_kernel_err.in munin-2.0.47/plugins/node.d/ntp_kernel_err.in --- munin-2.0.37/plugins/node.d/ntp_kernel_err.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/ntp_kernel_err.in 2019-02-28 14:43:36.000000000 +0000 @@ -35,7 +35,7 @@ { ntpq -c kerninfo; ntpdc -c kerninfo; } 2>/dev/null | awk 'BEGIN { ev=1; } /^estimated error:/ { ev=0; } - END { if (ev == 0) { print "yes";} else { print "no"; } exit ev; }' + END { if (ev == 0) { print "yes";} else { print "no (command ntpq or ntpdc not found)"; } exit 0; }' exit 0 fi @@ -51,7 +51,7 @@ printf 'ntp_err.value ' -if [ $(ntpq -c version | grep --extended-regexp --only-matching '[[:digit:]]\.[[:digit:]]\.[[:digit:]]' | tr -d '.') -ge 427 ] +if [ "$(ntpq -c version | grep --extended-regexp --only-matching '[[:digit:]]\.[[:digit:]]\.[[:digit:]]' | tr -d '.')" -ge 427 ] then ntpq -c kerninfo | awk '/^estimated error:/ { print $3 / 1000 }' else diff -Nru munin-2.0.37/plugins/node.d/ntp_kernel_pll_freq.in munin-2.0.47/plugins/node.d/ntp_kernel_pll_freq.in --- munin-2.0.37/plugins/node.d/ntp_kernel_pll_freq.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/ntp_kernel_pll_freq.in 2019-02-28 14:43:36.000000000 +0000 @@ -42,12 +42,12 @@ { ntpq -c kerninfo; ntpdc -c kerninfo; } 2>/dev/null | awk 'BEGIN { ev=1; } /^pll frequency:/ { ev=0; } - END { if (ev == 0) { print "yes";} else { print "no"; } exit ev; }' + END { if (ev == 0) { print "yes";} else { print "no (command ntpq or ntpdc not found)"; } exit 0; }' exit 0 fi -if [ -f @@CONFDIR@@/ntp-freq-comp ]; then - fcomp=`cat @@CONFDIR@@/ntp-freq-comp` +if [ -f "@@CONFDIR@@/ntp-freq-comp" ]; then + fcomp=$(cat "@@CONFDIR@@/ntp-freq-comp") else fcomp=0 fi @@ -65,7 +65,7 @@ printf 'ntp_pll_freq.value ' -if [ $(ntpq -c version | grep --extended-regexp --only-matching '[[:digit:]]\.[[:digit:]]\.[[:digit:]]' | tr -d '.') -ge 427 ] +if [ "$(ntpq -c version | grep --extended-regexp --only-matching '[[:digit:]]\.[[:digit:]]\.[[:digit:]]' | tr -d '.')" -ge 427 ] then cmd=ntpq else diff -Nru munin-2.0.37/plugins/node.d/ntp_kernel_pll_off.in munin-2.0.47/plugins/node.d/ntp_kernel_pll_off.in --- munin-2.0.37/plugins/node.d/ntp_kernel_pll_off.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/ntp_kernel_pll_off.in 2019-02-28 14:43:36.000000000 +0000 @@ -35,7 +35,7 @@ { ntpq -c kerninfo; ntpdc -c kerninfo; } 2>/dev/null | awk 'BEGIN { ev=1; } /^pll offset:/ { ev=0; } - END { if (ev == 0) { print "yes";} else { print "no"; } exit ev; }' + END { if (ev == 0) { print "yes";} else { print "no (command ntpq or ntpdc not found)"; } exit 0; }' exit 0 fi @@ -51,7 +51,7 @@ printf 'ntp_pll_off.value ' -if [ $(ntpq -c version | grep --extended-regexp --only-matching '[[:digit:]]\.[[:digit:]]\.[[:digit:]]' | tr -d '.') -ge 427 ] +if [ "$(ntpq -c version | grep --extended-regexp --only-matching '[[:digit:]]\.[[:digit:]]\.[[:digit:]]' | tr -d '.')" -ge 427 ] then ntpq -c kerninfo | awk '/^pll offset:/ { print $3 / 1000 }' else diff -Nru munin-2.0.37/plugins/node.d/ntp_offset.in munin-2.0.47/plugins/node.d/ntp_offset.in --- munin-2.0.37/plugins/node.d/ntp_offset.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/ntp_offset.in 2019-02-28 14:43:36.000000000 +0000 @@ -37,6 +37,10 @@ =cut + +nodelay=${nodelay:-} + + do_autoconf () { ntpq -c help >/dev/null 2>&1 || { echo 'no (no ntpq program)'; exit 0; } @@ -59,6 +63,7 @@ do_config () { syspeer="$(ntpq -n -p | grep '^[*o]')" + # shellcheck disable=SC2086 set - $syspeer peer=$1 @@ -88,6 +93,7 @@ # Fetch operation syspeer="$(ntpq -n -p | grep '^[*o]')" + # shellcheck disable=SC2086 set - $syspeer # peer=$1 @@ -105,7 +111,7 @@ case $1 in autoconf|config|'') - do_$1 + "do_$1" exit $? ;; *) diff -Nru munin-2.0.37/plugins/node.d/ntp_states.in munin-2.0.47/plugins/node.d/ntp_states.in --- munin-2.0.37/plugins/node.d/ntp_states.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/ntp_states.in 2019-02-28 14:43:36.000000000 +0000 @@ -12,6 +12,7 @@ [ntp_states] env.lowercase - Lowercase hostnames after lookup + env.show_syspeer_stratum - Display the stratum of the system peer, field sys_peer_stratum Set the variable env.lowercase to anything to lowercase hostnames. @@ -19,6 +20,7 @@ [ntp_states] env.lowercase + env.show_syspeer_stratum =head1 AUTHORS @@ -56,9 +58,11 @@ "outlier" => 4, "candidate" => 5, "sys.peer" => 6, - "pps.peer" => 7 + "pps.peer" => 7, + "insane" => 8 ); my %peers_condition; +my $syspeer_stratum_value = 15; my $resolver = Net::DNS::Resolver->new; $resolver->tcp_timeout(5); $resolver->udp_timeout(5); @@ -90,7 +94,18 @@ $condition_str = "falsetick"; } - $peers_condition{$peer_addr} = $stateval{$condition_str}; + # save the sys.peer's stratum if configured to graph it + if ($condition_str eq "sys.peer" and exists $ENV{"show_syspeer_stratum"}) { + chomp(my $stratum = `ntpq -n -c "readvar $assid stratum"`); + $stratum =~ s/\s//g; + ($syspeer_stratum_value) = ($stratum =~ m/stratum=(.*)/); + } + + if (exists $stateval{$condition_str}) { + $peers_condition{$peer_addr} = $stateval{$condition_str}; + } else { + $peers_condition{$peer_addr} = 9; + } } } } @@ -144,16 +159,20 @@ &make_hash; if ($ARGV[0] and $ARGV[0] eq "config") { - print "graph_title NTP states\n"; - print "graph_args --base 1000 --vertical-label state --lower-limit 0\n"; - print "graph_category time\n"; - print "graph_info These are graphs of the states of this system's NTP peers. The states translate as follows: 0=reject, 1=falsetick, 2=excess, 3=backup, 4=outiyer, 5=candidate, 6=system peer, 7=PPS peer. See http://www.eecis.udel.edu/~mills/ntp/html/decode.html for more information on the meaning of these conditions.\n"; + print "graph_info These are graphs of the states of this system's NTP peers. The states translate as follows: 0=reject, 1=falsetick, 2=excess, 3=backup, 4=outlyer, 5=candidate, 6=system peer, 7=PPS peer. See http://www.eecis.udel.edu/~mills/ntp/html/decode.html for more information on the meaning of these conditions. If show_syspeer_stratum is specified, the sys.peer stratum is also graphed.\n"; foreach my $addr (keys %peers_condition) { my ($fieldname, $hostname) = &make_names($addr); print "$fieldname.label $hostname\n"; } + # print config for the sys.peer's stratum if configured to graph it + if (exists $ENV{"show_syspeer_stratum"}) { + print "sys_peer_stratum.label sys.peer stratum\n"; + print "sys_peer_stratum.draw LINE1\n"; + print "sys_peer_stratum.colour 000000\n"; + } + exit 0; } @@ -161,6 +180,10 @@ my ($fieldname, $hostname) = &make_names($addr); print "$fieldname.value ", $peers_condition{$addr}, "\n"; } +# include the sys.peer's stratum if configured to graph it +if (exists $ENV{"show_syspeer_stratum"} ) { + print "sys_peer_stratum.value ", $syspeer_stratum_value, "\n"; +} exit 0; diff -Nru munin-2.0.37/plugins/node.d/nutups_.in munin-2.0.47/plugins/node.d/nutups_.in --- munin-2.0.37/plugins/node.d/nutups_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/nutups_.in 2019-02-28 14:43:36.000000000 +0000 @@ -5,26 +5,27 @@ # # Written by Andras Korn in 2005. Licensed under the GPL. # -# usage: ups_upsid_function +# usage: nutups_upsid_function # #%# family=contrib #%# capabilities=autoconf suggest -UPS=$(basename $0 | cut -d_ -f2) -FUNCTION=$(basename $0 | cut -d_ -f3) +UPS=$(basename "$0" | cut -d_ -f2) +FUNCTION=$(basename "$0" | cut -d_ -f3) +UPSC=$(command -v upsc) if [ "$1" = "autoconf" ]; then - [ -x /bin/upsc ] && [ -r /etc/nut/ups.conf ] && echo yes && exit 0 - echo "no (/bin/upsc or /etc/nut/ups.conf not found)" + [ -x "$UPSC" ] && [ -r /etc/nut/ups.conf ] && echo yes && exit 0 + echo "no (upsc or /etc/nut/ups.conf not found)" exit 0 fi if [ "$1" = "suggest" ]; then grep '^\[[^]]*\]$' /etc/nut/ups.conf \ | tr -d '][' \ - | while read ups; do + | while read -r ups; do for i in voltages freq charge current; do - echo ${ups}_${i} + echo "${ups}_${i}" done done fi @@ -42,7 +43,7 @@ echo "${i}.min 0" done else - upsc $UPS | sed -n '/volt/{ + "$UPSC" "$UPS" | sed -n '/^[^:]*volt/{ s/:// /nominal/s/.* /nominal.value / /voltage/s/\.[^ ]*/.value/ @@ -64,7 +65,7 @@ echo "${i}.min 0" done else - upsc $UPS | sed -n '/charge/{ + "$UPSC" "$UPS" | sed -n '/^[^:]*charge/{ s/^[^:]*\.//g s/:/.value/ p @@ -87,7 +88,7 @@ echo "acfreq.max 100" echo "acfreq.min 5" else - upsc $UPS | sed -n '/freq/{s/.*:/acfreq.value/;p}' + "$UPSC" "$UPS" | sed -n '/^[^:]*freq/{s/.*:/acfreq.value/;p}' fi } @@ -102,7 +103,7 @@ echo "current.max 100" echo "current.min 0" else - upsc $UPS | sed -n '/current/{s/.*:/current.value/;p}' + "$UPSC" "$UPS" | sed -n '/^[^:]*current/{s/.*:/current.value/;p}' fi } @@ -110,16 +111,15 @@ case "$FUNCTION" in voltages) - voltages $1 + voltages "$1" ;; charge) - charge $1 + charge "$1" ;; freq) - frequency $1 + frequency "$1" ;; current) - current $1 + current "$1" ;; esac - diff -Nru munin-2.0.37/plugins/node.d/perdition.in munin-2.0.47/plugins/node.d/perdition.in --- munin-2.0.37/plugins/node.d/perdition.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/perdition.in 2019-02-28 14:43:36.000000000 +0000 @@ -49,9 +49,6 @@ =cut -mktempfile () { -@@MKTEMP@@ -} # Set the location of the perdition logs PERDITION_LOG=${logfile:-/var/log/perdition.log} @@ -60,8 +57,7 @@ case $1 in autoconf|detect) - if [ -f ${PERDITION_LOG} -a -x ${LOGTAIL} ] - then + if [ -f "$PERDITION_LOG" ] && [ -x "$LOGTAIL" ]; then echo yes exit 0 else @@ -85,42 +81,42 @@ # Echo warnnig and critical attributes if set in the plugin config for i in imap imaps pop pops fatal connection disconnected; do warn=\$${i}_warn; eval val=$warn - [ "$val" ] && echo "$i.warning ${val}" + [ -n "${val:-}" ] && echo "$i.warning ${val}" crit=\$${i}_crit; eval val=$crit - [ "$val" ] && echo "$i.critical ${val}" + [ -n "${val:-}" ] && echo "$i.critical ${val}" done exit 0 ;; esac ARGS=0 -`$LOGTAIL /etc/hosts 2>/dev/null >/dev/null` +"$LOGTAIL" /etc/hosts 2>/dev/null >/dev/null if [ $? = 66 ]; then - if [ ! -n "$logtail" ]; then + if [ -z "$logtail" ]; then ARGS=1 fi fi -TEMP_FILE=`mktempfile munin-perdition.XXXXXX` +TEMP_FILE=$(@@MKTEMP@@ munin-perdition.XXXXXX) -if [ -z "$TEMP_FILE" -o ! -f "$TEMP_FILE" ]; then +if [ -z "$TEMP_FILE" ] || [ ! -f "$TEMP_FILE" ]; then exit 3 fi -if [ $ARGS != 0 ]; then - ${LOGTAIL} -f ${PERDITION_LOG} -o ${OFFSET_FILE} > ${TEMP_FILE} +if [ "$ARGS" != 0 ]; then + "$LOGTAIL" -f "$PERDITION_LOG" -o "$OFFSET_FILE" > "$TEMP_FILE" else - ${LOGTAIL} ${PERDITION_LOG} ${OFFSET_FILE} > ${TEMP_FILE} + "$LOGTAIL" "$PERDITION_LOG" "$OFFSET_FILE" > "$TEMP_FILE" fi -connection=`grep "Connect:" ${TEMP_FILE} | wc -l` -disconnected=`grep "Close:" ${TEMP_FILE} | wc -l` -imap=`grep 'port="143" status="ok"' ${TEMP_FILE} | wc -l` -imaps=`grep 'port="993" status="ok"' ${TEMP_FILE} | wc -l` -pop=`grep 'port="110" status="ok"' ${TEMP_FILE} | wc -l` -pops=`grep 'port="995" status="ok"' ${TEMP_FILE} | wc -l` -fatal=`grep 'Fatal [e|E]rror' ${TEMP_FILE} | wc -l` +connection=$(grep "Connect:" "$TEMP_FILE" | wc -l) +disconnected=$(grep "Close:" "$TEMP_FILE" | wc -l) +imap=$(grep 'port="143" status="ok"' "$TEMP_FILE" | wc -l) +imaps=$(grep 'port="993" status="ok"' "$TEMP_FILE" | wc -l) +pop=$(grep 'port="110" status="ok"' "$TEMP_FILE" | wc -l) +pops=$(grep 'port="995" status="ok"' "$TEMP_FILE" | wc -l) +fatal=$(grep 'Fatal [e|E]rror' "$TEMP_FILE" | wc -l) -rm ${TEMP_FILE} +rm "$TEMP_FILE" echo "connection.value ${connection}" echo "disconnected.value ${disconnected}" diff -Nru munin-2.0.37/plugins/node.d/pop_stats.in munin-2.0.47/plugins/node.d/pop_stats.in --- munin-2.0.37/plugins/node.d/pop_stats.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/pop_stats.in 2019-02-28 14:43:36.000000000 +0000 @@ -81,13 +81,13 @@ print OUT "$pos:$logons\n"; close OUT; -sub parsePopfile -{ +sub parsePopfile +{ my ($fname, $start, $stop) = @_; open (LOGFILE, $fname) or exit 3; seek (LOGFILE, $start, 0) or exit 2; - while (tell (LOGFILE) < $stop) + while (tell (LOGFILE) < $stop) { my $line =; chomp ($line); @@ -97,7 +97,7 @@ $logons++; } } - close(LOGFILE); + close(LOGFILE); } diff -Nru munin-2.0.37/plugins/node.d/postfix_mailqueue.in munin-2.0.47/plugins/node.d/postfix_mailqueue.in --- munin-2.0.37/plugins/node.d/postfix_mailqueue.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postfix_mailqueue.in 2019-02-28 14:43:36.000000000 +0000 @@ -87,20 +87,20 @@ POSTCONFSPOOL="$(postconf -h queue_directory 2>/dev/null || echo /var/spool/postfix)" SPOOLDIR=${spooldir:-$POSTCONFSPOOL} -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" case $1 in autoconf|detect) - - if [ -d $SPOOLDIR ] ; then - echo yes - exit 0 + + if [ -d "$SPOOLDIR" ] ; then + echo yes + exit 0 else - echo "no (spooldir not found)" - exit 0 - fi;; + echo "no (spooldir not found)" + exit 0 + fi;; config) - cat <<'EOF' + cat <<'EOF' graph_title Postfix Mailqueue graph_vlabel Mails in queue graph_category postfix @@ -112,23 +112,23 @@ corrupt.label corrupt hold.label held EOF - for field in active deferred maildrop incoming corrupt hold; do - print_warning $field - print_critical $field - done - exit 0;; + for field in active deferred maildrop incoming corrupt hold; do + print_warning "$field" + print_critical "$field" + done + exit 0;; esac -cd $SPOOLDIR >/dev/null 2>/dev/null || { +cd "$SPOOLDIR" >/dev/null 2>/dev/null || { echo "# Cannot cd to $SPOOLDIR" exit 1 } cat < =~ /^(\d+):(\d+)/) { - ($pos, $delivered) = ($1, $2); + ($pos, $delivered) = ($1, $2); } while () { - if (/^([0-9a-z.\-]+):(\d+)$/) - { - $rejects->{$1} = $2; - } + if (/^([0-9a-z.\-]+):(\d+)$/) + { + $rejects{$1} = $2; + } } close IN; } @@ -110,15 +114,16 @@ if (! -f $logfile) { print "delivered.value U\n"; - foreach my $i (sort keys %{$rejects}) + foreach my $reason (sort keys %rejects) { - print "r$i.value U\n"; + my $fieldname = clean_fieldname("r$reason"); + print "$fieldname.value U\n"; } exit 0; } -$startsize = (stat $logfile)[7]; +my $startsize = (stat $logfile)[7]; if (!defined $pos) { @@ -142,58 +147,61 @@ print "delivered.type DERIVE\n"; print "delivered.draw AREA\n"; print "delivered.min 0\n"; - foreach my $i (sort keys %{$rejects}) + foreach my $reason (sort keys %rejects) { - print "r$i.label reject $i\n"; - print "r$i.type DERIVE\n"; - print "r$i.draw STACK\n"; - print "r$i.min 0\n"; + my $fieldname = clean_fieldname("r$reason"); + print "$fieldname.label reject $reason\n"; + print "$fieldname.type DERIVE\n"; + print "$fieldname.draw STACK\n"; + print "$fieldname.min 0\n"; } exit 0; } print "delivered.value $delivered\n"; -foreach my $i (sort keys %{$rejects}) +foreach my $reason (sort keys %rejects) { - print "r$i.value ", $rejects->{$i}, "\n"; + my $fieldname = clean_fieldname("r$reason"); + print "$fieldname.value ", $rejects{$reason}, "\n"; } if(-l $statefile) { - die("$statefile is a symbolic link, refusing to touch it."); -} + die("$statefile is a symbolic link, refusing to touch it."); +} open (OUT, '>', $statefile) or die "Unable to open statefile: $!\n"; print OUT "$pos:$delivered\n"; -foreach my $i (sort keys %{$rejects}) +foreach my $i (sort keys %rejects) { - print OUT "$i:", $rejects->{$i}, "\n"; + print OUT "$i:", $rejects{$i}, "\n"; } close OUT; -sub parseLogfile -{ +sub parseLogfile +{ my ($fname, $start, $stop) = @_; open (LOGFILE, $fname) - or die "Unable to open logfile $fname for reading: $!\n"; + or die "Unable to open logfile $fname for reading: $!\n"; seek (LOGFILE, $start, 0) - or die "Unable to seek to $start in $fname: $!\n"; + or die "Unable to seek to $start in $fname: $!\n"; - while (tell (LOGFILE) < $stop) + while (tell (LOGFILE) < $stop) { - my $line = ; - chomp ($line); + my $line = ; + chomp ($line); - if ($line =~ / to=.*, status=sent /) - { - $delivered++; - } - elsif ($line =~ /postfix\/smtpd.*proxy-reject: \S+ (\S+)/ || - $line =~ /postfix\/smtpd.*reject: \S+ \S+ \S+ (\S+)/ || - $line =~ /postfix\/cleanup.* reject: (\S+)/) - { - $rejects->{$1}++; - } + if ($line =~ / to=.*, status=sent /) + { + $delivered++; + } + elsif ($line =~ /postfix\/smtpd.*proxy-reject: \S+ (\S+)/ || + $line =~ /postfix\/smtpd.*reject: \S+ \S+ \S+ (\S+)/ || + $line =~ /postfix\/cleanup.* reject: (\S+)/ || + $line =~ /postfix\/cleanup.* milter-reject: \S+ \S+ \S+ (\S+)/) + { + $rejects{$1}++; + } } - close(LOGFILE) or warn "Error closing $fname: $!\n"; + close(LOGFILE) or warn "Error closing $fname: $!\n"; } # vim:syntax=perl diff -Nru munin-2.0.37/plugins/node.d/postfix_mailvolume.in munin-2.0.47/plugins/node.d/postfix_mailvolume.in --- munin-2.0.37/plugins/node.d/postfix_mailvolume.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postfix_mailvolume.in 2019-02-28 14:43:36.000000000 +0000 @@ -34,7 +34,8 @@ =head1 VERSION - $Id$ +v1.1 2018-03-24 +* calculate extra field for mail volume that is actually delivered ("volume_delivered") =head1 AUTHOR @@ -49,27 +50,57 @@ =cut use strict; +use warnings; use Munin::Plugin; -my $pos = undef; -my $volume = 0; +my $pos = undef; +# the volume that was actually delivered +my $volume_delivered = 0; +my %volumes_per_queue_id = (); +my $serialized_volumes_queue; +my %expired_queue_ids = (); +# Discard old queue IDs after a while (otherwise the state storage grows infinitely). We need to +# store the IDs long enough for the gap between two delivery attempts. Thus multiple hours are +# recommended. +use constant queue_id_expiry => 6 * 3600; + my $LOGDIR = $ENV{'logdir'} || '/var/log'; my $LOGFILE = $ENV{'logfile'} || 'syslog'; + sub parseLogfile { my ($fname, $start) = @_; - my ($LOGFILE,$rotated) = tail_open($fname,$start); - - my $line; + my ($LOGFILE, $rotated) = tail_open($fname, $start || 0); - while ($line =<$LOGFILE>) { - chomp ($line); + while (my $line = <$LOGFILE>) { + chomp ($line); - if ($line =~ /qmgr.*from=.*size=([0-9]+)/) { - $volume += $1; - } + if ($line =~ /qmgr.*: ([0-9A-Za-z]+): from=.*, size=([0-9]+)/) { + # The line with queue ID and size may pass along multiple times (every time the mail + # is moved into the active queue for another delivery attempt). The size should always + # be the same. + if (not exists($volumes_per_queue_id{$1})) { + $volumes_per_queue_id{$1} = {timestamp => time}; + } + # probably it is the same value as before + $volumes_per_queue_id{$1}->{size} = $2; + } elsif ($line =~ / ([0-9A-Za-z]+): to=.*, status=sent /) { + # The "sent" line is repeated for every successful delivery for each recipient. + if (exists($volumes_per_queue_id{$1})) { + $volume_delivered += $volumes_per_queue_id{$1}->{size}; + $volumes_per_queue_id{$1}->{timestamp} = time; + } + } } + # remove all expired queue IDs + my @expired_queue_ids; + for my $key (keys %volumes_per_queue_id) { + if (time > $volumes_per_queue_id{$key}->{timestamp} + queue_id_expiry) { + push @expired_queue_ids, $key; + } + } + delete(@volumes_per_queue_id{@expired_queue_ids}); return tail_close($LOGFILE); } @@ -77,20 +108,20 @@ my $logfile; `which postconf >/dev/null 2>/dev/null`; if (!$?) { - $logfile = "$LOGDIR/$LOGFILE"; + $logfile = "$LOGDIR/$LOGFILE"; - if (-f $logfile) { + if (-f $logfile) { if (-r "$logfile") { print "yes\n"; exit 0; } else { print "no (logfile '$logfile' not readable)\n"; } - } else { - print "no (logfile '$logfile' not found)\n"; - } + } else { + print "no (logfile '$logfile' not found)\n"; + } } else { - print "no (postfix not found)\n"; + print "no (postfix not found)\n"; } exit 0; @@ -103,7 +134,7 @@ print "graph_vlabel bytes / \${graph_period}\n"; print "graph_scale yes\n"; print "graph_category postfix\n"; - print "volume.label throughput\n"; + print "volume.label delivered volume\n"; print "volume.type DERIVE\n"; print "volume.min 0\n"; exit 0; @@ -117,23 +148,37 @@ exit 1; } -($pos,$volume) = restore_state(); +# load the stored data +($pos, $volume_delivered, $serialized_volumes_queue) = restore_state(); + + +if (!defined($volume_delivered)) { -if (!defined($volume)) { - # No state file present. Avoid startup spike: Do not read log # file up to now, but remember how large it is now, and next # time read from there. $pos = (stat $logfile)[7]; # File size - $volume = 0; + $volume_delivered = 0; + %volumes_per_queue_id = (); } else { + # decode the serialized hash + # source format: "$id1=$size1:$timestamp1 $id2=$size2:$timestamp2 ..." + # The "serialized" value may be undefined, in case we just upgraded from the version before + # 2018, since that old version stored only two fields in the state file. Tolerate this. + for my $queue_item_descriptor (split(/ /, $serialized_volumes_queue || "")) { + (my $queue_item_id, my $queue_item_content) = split(/=/, $queue_item_descriptor); + (my $size, my $timestamp) = split(/:/, $queue_item_content); + $volumes_per_queue_id{$queue_item_id} = { size => int($size), timestamp => int($timestamp) }; + } $pos = parseLogfile ($logfile, $pos); } -print "volume.value $volume\n"; +print "volume.value $volume_delivered\n"; -save_state($pos,$volume); +# serialize the hash to a string (see "source format" above) +$serialized_volumes_queue = join(" ", map { sprintf("%s=%s", $_, sprintf("%d:%d", $volumes_per_queue_id{$_}->{size}, $volumes_per_queue_id{$_}->{timestamp})) } keys %volumes_per_queue_id); +save_state($pos, $volume_delivered, $serialized_volumes_queue); # vim:syntax=perl diff -Nru munin-2.0.37/plugins/node.d/postgres_autovacuum.in munin-2.0.47/plugins/node.d/postgres_autovacuum.in --- munin-2.0.37/plugins/node.d/postgres_autovacuum.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_autovacuum.in 2019-02-28 14:43:36.000000000 +0000 @@ -65,8 +65,8 @@ "SELECT 'active', count(*) FROM pg_stat_activity WHERE query LIKE 'autovacuum: %'", [ 9.1, - "SELECT 'active', count(*) FROM pg_stat_activity WHERE current_query LIKE 'autovacuum: %'" - ] + "SELECT 'active', count(*) FROM pg_stat_activity WHERE current_query LIKE 'autovacuum: %'", + ], ], configquery => [ "VALUES('active','Active workers')", [ 8.1, "SELECT 'active','Active workers'" ] ], ); diff -Nru munin-2.0.37/plugins/node.d/postgres_bgwriter.in munin-2.0.47/plugins/node.d/postgres_bgwriter.in --- munin-2.0.37/plugins/node.d/postgres_bgwriter.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_bgwriter.in 2019-02-28 14:43:36.000000000 +0000 @@ -69,8 +69,8 @@ ('buffers_clean','Buffers cleaned', 'Buffers cleaned by background bgwriter runs'), ('buffers_backend', 'Buffers by backend', 'Buffers written by backends and not the bgwriter'), ('buffers_alloc', 'Buffers allocated', 'Buffers allocated globally')", - graphtype => 'DERIVE' + graphtype => 'DERIVE', + graphmin => 0, ); $pg->Process(); - diff -Nru munin-2.0.37/plugins/node.d/postgres_cache_.in munin-2.0.47/plugins/node.d/postgres_cache_.in --- munin-2.0.37/plugins/node.d/postgres_cache_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_cache_.in 2019-02-28 14:43:36.000000000 +0000 @@ -72,13 +72,13 @@ configquery => [ "VALUES ('blks_read','Buffers read'),('blks_hit','Buffers hit')", [ 8.1, - "SELECT 'blks_read','Buffers read' UNION ALL SELECT 'blks_hit','Buffers hit'" - ] + "SELECT 'blks_read','Buffers read' UNION ALL SELECT 'blks_hit','Buffers hit'", + ], ], suggestquery => "SELECT datname FROM pg_database WHERE datallowconn AND NOT datistemplate AND NOT datname='postgres' UNION ALL SELECT 'ALL' ORDER BY 1 LIMIT 10", - graphtype => 'DERIVE' + graphtype => 'DERIVE', + graphmin => 0, ); $pg->Process(); - diff -Nru munin-2.0.37/plugins/node.d/postgres_checkpoints.in munin-2.0.47/plugins/node.d/postgres_checkpoints.in --- munin-2.0.37/plugins/node.d/postgres_checkpoints.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_checkpoints.in 2019-02-28 14:43:36.000000000 +0000 @@ -68,8 +68,8 @@ "VALUES ('checkpoints_timed','Timed checkpoints','Checkpoints started by timeout'),('checkpoints_req','Requested checkpoints','Checkpoints started by request')", stack => 1, graphtype => 'DERIVE', - graphperiod => 'minute' + graphperiod => 'minute', + graphmin => 0, ); $pg->Process(); - diff -Nru munin-2.0.37/plugins/node.d/postgres_connections_db.in munin-2.0.47/plugins/node.d/postgres_connections_db.in --- munin-2.0.37/plugins/node.d/postgres_connections_db.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_connections_db.in 2019-02-28 14:43:36.000000000 +0000 @@ -68,11 +68,10 @@ ], [ 9.1, "SELECT pg_database.datname,COALESCE(count,0) AS count FROM pg_database LEFT JOIN (SELECT datname,count(*) FROM pg_stat_activity WHERE procpid != pg_backend_pid() GROUP BY datname) AS tmp ON pg_database.datname=tmp.datname WHERE datallowconn ORDER BY 1", - ] + ], ], configquery => "SELECT datname,datname FROM pg_database WHERE datallowconn ORDER BY 1", ); $pg->Process(); - diff -Nru munin-2.0.37/plugins/node.d/postgres_connections_.in munin-2.0.47/plugins/node.d/postgres_connections_.in --- munin-2.0.37/plugins/node.d/postgres_connections_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_connections_.in 2019-02-28 14:43:36.000000000 +0000 @@ -65,7 +65,26 @@ info => 'Number of connections', vlabel => 'Connections', basequery => [ - "SELECT tmp.mstate AS state,COALESCE(count,0) FROM + "SELECT tmp.mstate AS state, COALESCE(count,0) FROM + (VALUES ('active'),('waiting'),('idle'),('idletransaction'),('unknown')) AS tmp(mstate) + LEFT JOIN + (SELECT CASE + WHEN a.wait_event_type IS NOT NULL AND a.locked AND state NOT LIKE 'idle in transaction%' THEN 'waiting' + WHEN state='idle' THEN 'idle' + WHEN state LIKE 'idle in transaction%' THEN 'idletransaction' + WHEN state='disabled' THEN 'unknown' + WHEN query='' THEN 'unknown' + ELSE 'active' END AS mstate, + count(*) AS count + FROM (SELECT act.state, act.wait_event_type, EXISTS (SELECT FROM pg_locks AS l WHERE l.pid = act.pid) AS locked, act.query + FROM pg_stat_activity AS act + WHERE act.pid != pg_backend_pid() AND act.backend_type = 'client backend' /*%%FILTER%%*/) + AS a GROUP BY 1 + ) AS tmp2 + ON tmp.mstate=tmp2.mstate + ORDER BY 1; + ", + [ 9.6, "SELECT tmp.mstate AS state,COALESCE(count,0) FROM (VALUES ('active'),('waiting'),('idle'),('idletransaction'),('unknown')) AS tmp(mstate) LEFT JOIN (SELECT CASE WHEN wait_event_type IS NOT NULL THEN 'waiting' WHEN state='idle' THEN 'idle' WHEN state LIKE 'idle in transaction%' THEN 'idletransaction' WHEN state='disabled' THEN 'unknown' WHEN query='' THEN 'unknown' ELSE 'active' END AS mstate, @@ -75,7 +94,7 @@ ) AS tmp2 ON tmp.mstate=tmp2.mstate ORDER BY 1; - ", + " ], [ 9.5, "SELECT tmp.mstate AS state,COALESCE(count,0) FROM (VALUES ('active'),('waiting'),('idle'),('idletransaction'),('unknown')) AS tmp(mstate) LEFT JOIN @@ -107,7 +126,7 @@ GROUP BY CASE WHEN current_query='' THEN 'idle' WHEN current_query=' in transaction' THEN 'idletransaction' WHEN current_query='' THEN 'unknown' ELSE 'active' END ) AS tmp2 ON tmp.state=tmp2.state - ORDER BY 1" ] + ORDER BY 1" ], ], wildcardfilter => " AND datname=?", paramdatabase => 1, @@ -115,14 +134,13 @@ "VALUES ('active','Active'),('waiting','Waiting for lock'),('idle','Idle'),('idletransaction','Idle in transaction'),('unknown','Unknown')", [ 8.1, - "SELECT 'active','Active' UNION ALL SELECT 'idle','Idle' UNION ALL SELECT 'idletransaction','Idle in transaction' UNION ALL SELECT 'unknown','Unknown'" - ] + "SELECT 'active','Active' UNION ALL SELECT 'idle','Idle' UNION ALL SELECT 'idletransaction','Idle in transaction' UNION ALL SELECT 'unknown','Unknown'", + ], ], suggestquery => "SELECT datname FROM pg_database WHERE datallowconn AND NOT datistemplate AND NOT datname='postgres' UNION ALL SELECT 'ALL' ORDER BY 1 LIMIT 10", graphdraw => 'AREA', - stack => 1 + stack => 1, ); $pg->Process(); - diff -Nru munin-2.0.37/plugins/node.d/postgres_locks_.in munin-2.0.47/plugins/node.d/postgres_locks_.in --- munin-2.0.37/plugins/node.d/postgres_locks_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_locks_.in 2019-02-28 14:43:36.000000000 +0000 @@ -85,7 +85,7 @@ FROM pg_locks WHERE database IS NOT NULL %%FILTER%% GROUP BY lower(mode) ) AS tmp2 - ON tmp.mode=tmp2.mode ORDER BY 1" + ON tmp.mode=tmp2.mode ORDER BY 1", ], ], wildcardfilter => "AND database=(SELECT oid FROM pg_database WHERE datname=?)", @@ -108,8 +108,8 @@ SELECT 'sharelock','ShareLock','Used by CREATE INDEX queries' UNION ALL SELECT 'sharerowexclusivelock','ShareRowExclusiveLock','Only issued explicitly from applications' UNION ALL SELECT 'exclusivelock','ExclusiveLock','Infrequently issued on system tables, or by applications' UNION ALL - SELECT 'accessexclusivelock','AccessExclusiveLock','Used by ALTER TABLE, DROP TABLE, TRUNCATE, REINDEX, CLUSTER and VACUUM FULL queries'" - ] + SELECT 'accessexclusivelock','AccessExclusiveLock','Used by ALTER TABLE, DROP TABLE, TRUNCATE, REINDEX, CLUSTER and VACUUM FULL queries'", + ], ], suggestquery => "SELECT datname FROM pg_database WHERE datallowconn AND NOT datistemplate AND NOT datname='postgres' UNION ALL SELECT 'ALL' ORDER BY 1 LIMIT 10", graphdraw => 'AREA', @@ -117,5 +117,3 @@ ); $pg->Process(); -exit(0); - diff -Nru munin-2.0.37/plugins/node.d/postgres_oldest_prepared_xact_.in munin-2.0.47/plugins/node.d/postgres_oldest_prepared_xact_.in --- munin-2.0.37/plugins/node.d/postgres_oldest_prepared_xact_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_oldest_prepared_xact_.in 2019-02-28 14:43:36.000000000 +0000 @@ -78,5 +78,3 @@ ); $pg->Process(); -exit(0); - diff -Nru munin-2.0.37/plugins/node.d/postgres_prepared_xacts_.in munin-2.0.47/plugins/node.d/postgres_prepared_xacts_.in --- munin-2.0.37/plugins/node.d/postgres_prepared_xacts_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_prepared_xacts_.in 2019-02-28 14:43:36.000000000 +0000 @@ -80,5 +80,3 @@ ); $pg->Process(); -exit(0); - diff -Nru munin-2.0.37/plugins/node.d/postgres_querylength_.in munin-2.0.47/plugins/node.d/postgres_querylength_.in --- munin-2.0.37/plugins/node.d/postgres_querylength_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_querylength_.in 2019-02-28 14:43:36.000000000 +0000 @@ -82,20 +82,19 @@ ], [ 8.2, - "SELECT 'query',COALESCE(max(extract(epoch FROM CURRENT_TIMESTAMP-query_start)),0) FROM pg_stat_activity WHERE current_query NOT LIKE ' " AND datname=?", paramdatabase => 1, configquery => [ "VALUES ('query','Oldest query'),('transaction','Oldest transaction')", [8.2, "VALUES ('query','Oldest query')"], - [8.1, "SELECT 'query','Oldest query'"] + [8.1, "SELECT 'query','Oldest query'"], ], suggestquery => "SELECT datname FROM pg_database WHERE datallowconn AND NOT datistemplate AND NOT datname='postgres' UNION ALL SELECT 'ALL' ORDER BY 1 LIMIT 10", - stack => 0 + stack => 0, ); $pg->Process(); - diff -Nru munin-2.0.37/plugins/node.d/postgres_scans_.in munin-2.0.47/plugins/node.d/postgres_scans_.in --- munin-2.0.37/plugins/node.d/postgres_scans_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_scans_.in 2019-02-28 14:43:36.000000000 +0000 @@ -73,8 +73,7 @@ "SELECT datname FROM pg_database WHERE datallowconn AND NOT datistemplate AND NOT datname='postgres' ORDER BY 1 LIMIT 10", stack => 1, graphtype => 'DERIVE', + graphmin => 0, ); $pg->Process(); -exit(0); - diff -Nru munin-2.0.37/plugins/node.d/postgres_size_.in munin-2.0.47/plugins/node.d/postgres_size_.in --- munin-2.0.37/plugins/node.d/postgres_size_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_size_.in 2019-02-28 14:43:36.000000000 +0000 @@ -73,9 +73,8 @@ "SELECT datname FROM pg_database WHERE datallowconn AND NOT datistemplate AND NOT datname='postgres' UNION ALL SELECT 'ALL' ORDER BY 1 LIMIT 10", graphdraw => 'AREA', stack => 1, - base => 1024 + base => 1024, + graphmin => 0, ); $pg->Process(); -exit(0); - diff -Nru munin-2.0.37/plugins/node.d/postgres_transactions_.in munin-2.0.47/plugins/node.d/postgres_transactions_.in --- munin-2.0.37/plugins/node.d/postgres_transactions_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_transactions_.in 2019-02-28 14:43:36.000000000 +0000 @@ -74,16 +74,15 @@ "VALUES ('commit','Committed transactions'),('rollback','Rolled back transactions')", [ 8.1, - "SELECT 'commit','Committed transactions' UNION ALL SELECT 'rollback','Rolled back transactions'" - ] + "SELECT 'commit','Committed transactions' UNION ALL SELECT 'rollback','Rolled back transactions'", + ], ], suggestquery => "SELECT datname FROM pg_database WHERE datallowconn AND NOT datistemplate AND NOT datname='postgres' UNION ALL SELECT 'ALL' ORDER BY 1 LIMIT 10", stack => 1, graphmin => 0, graphdraw => 'AREA', - graphtype => 'DERIVE' + graphtype => 'DERIVE', ); $pg->Process(); - diff -Nru munin-2.0.37/plugins/node.d/postgres_tuples_.in munin-2.0.47/plugins/node.d/postgres_tuples_.in --- munin-2.0.37/plugins/node.d/postgres_tuples_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_tuples_.in 2019-02-28 14:43:36.000000000 +0000 @@ -82,19 +82,18 @@ [ 8.2, "VALUES ('seqread','Tuples sequentally read'), ('idxfetch','Tuples index fetched'), ('inserted','Tuples inserted')," - . " ('updated','Tuples updated'),('deleted','Tuples deleted')" + . " ('updated','Tuples updated'),('deleted','Tuples deleted')", ], [ 8.1, "SELECT 'seqread','Tuples sequentially read' UNION ALL SELECT 'idxfetch','Tuples index fetched' UNION ALL " . "SELECT 'inserted','Tuples inserted' UNION ALL SELECT 'updated','Tuples updated' UNION ALL " - . "SELECT 'deleted','Tuples deleted'" + . "SELECT 'deleted','Tuples deleted'", ], ], suggestquery => "SELECT datname FROM pg_database WHERE datallowconn AND NOT datistemplate AND NOT datname='postgres' ORDER BY 1 LIMIT 10", graphtype => 'DERIVE', + graphmin => 0, ); $pg->Process(); -exit(0); - diff -Nru munin-2.0.37/plugins/node.d/postgres_users.in munin-2.0.47/plugins/node.d/postgres_users.in --- munin-2.0.37/plugins/node.d/postgres_users.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_users.in 2019-02-28 14:43:36.000000000 +0000 @@ -61,22 +61,21 @@ info => 'Number of connections per user', vlabel => 'Connections', basequery => [ - "SELECT usename,count(*) FROM pg_stat_activity WHERE pid != pg_backend_pid() GROUP BY usename ORDER BY 1", + "SELECT usename,count(*) FROM pg_stat_activity WHERE pid != pg_backend_pid() AND usename IS NOT NULL GROUP BY usename ORDER BY 1", [ 9.4, - "SELECT usename,count(*) FROM pg_stat_activity WHERE pid != pg_backend_pid() GROUP BY usename ORDER BY 1", + "SELECT usename,count(*) FROM pg_stat_activity WHERE pid != pg_backend_pid() AND usename IS NOT NULL GROUP BY usename ORDER BY 1", ], [ 9.1, - "SELECT usename,count(*) FROM pg_stat_activity WHERE procpid != pg_backend_pid() GROUP BY usename ORDER BY 1", - ] + "SELECT usename,count(*) FROM pg_stat_activity WHERE procpid != pg_backend_pid() AND usename IS NOT NULL GROUP BY usename ORDER BY 1", + ], ], configquery => [ - "SELECT DISTINCT usename,usename FROM pg_stat_activity WHERE pid != pg_backend_pid() ORDER BY 1", + "SELECT DISTINCT usename,usename FROM pg_stat_activity WHERE pid != pg_backend_pid() AND usename IS NOT NULL ORDER BY 1", [ 9.1, - "SELECT DISTINCT usename,usename FROM pg_stat_activity WHERE procpid != pg_backend_pid() ORDER BY 1", - ] + "SELECT DISTINCT usename,usename FROM pg_stat_activity WHERE procpid != pg_backend_pid() AND usename IS NOT NULL ORDER BY 1", + ], ], ); $pg->Process(); - diff -Nru munin-2.0.37/plugins/node.d/postgres_xlog.in munin-2.0.47/plugins/node.d/postgres_xlog.in --- munin-2.0.37/plugins/node.d/postgres_xlog.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/postgres_xlog.in 2019-02-28 14:43:36.000000000 +0000 @@ -83,14 +83,13 @@ vlabel => 'Log segments', basequery => [ "SELECT count(*) AS segments FROM pg_ls_waldir() WHERE name ~ '^[0-9A-Z]{24}\$'", - [ 9.6, "SELECT count(*) AS segments FROM pg_ls_dir('pg_xlog') t(fn) WHERE fn ~ '^[0-9A-Z]{24}\$'", ] + [ 9.6, "SELECT count(*) AS segments FROM pg_ls_dir('pg_xlog') t(fn) WHERE fn ~ '^[0-9A-Z]{24}\$'", ], ], pivotquery => 1, configquery => [ "VALUES('segments','WAL segments')", - [8.1, "SELECT 'segments','WAL segments'"] - ] + [8.1, "SELECT 'segments','WAL segments'"], + ], ); $pg->Process(); - diff -Nru munin-2.0.37/plugins/node.d/processes.in munin-2.0.47/plugins/node.d/processes.in --- munin-2.0.37/plugins/node.d/processes.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/processes.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,8 @@ #!@@GOODSH@@ # -*- sh -*- +set -e + : << =cut =head1 NAME @@ -62,38 +64,33 @@ =cut # Search for program in $PATH unless predefined. -[ $awk ] || awk="awk" -[ $ps ] || ps="ps" +awk=${awk:-awk} +ps=${ps:-ps} # Find operating system -[ $OPERSYS ] || OPERSYS=`uname | cut -f 1 -d _` || exit 1 +OPERSYS=${OPERSYS:-$(uname | cut -f 1 -d _)} +[ -z "$OPERSYS" ] && echo >&2 "Failed to detect environment via uname" && exit 1 if [ "$1" = "autoconf" ]; then - case "$OPERSYS" in + case "$OPERSYS" in Linux|SunOS|FreeBSD|OpenBSD|NetBSD|Darwin|CYGWIN) - $ps >/dev/null 2>/dev/null - if [ $? -ne 0 ] - then - echo "no (ps=$ps failed)" + if ! "$ps" >/dev/null 2>/dev/null; then + echo "no (ps=$ps failed)" + elif ! echo | "$awk" '{ print "Hei" }' >/dev/null 2>/dev/null; then + echo "no (awk=$awk failed)" + else + echo yes + fi exit 0 - fi - echo | $awk '{ print "Hei" }' >/dev/null 2>/dev/null - if [ $? -ne 0 ] - then - echo "no (awk=$awk failed)" + ;; + *) + echo "no (unknown OS)" exit 0 - fi - echo yes - exit 0 - ;; - *) - echo "no (unknown OS)" - exit 0 - ;; + ;; esac fi -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" # Define colours RUNNABLE='22ff22' # Green @@ -134,7 +131,7 @@ # OS specific flags if [ "$OPERSYS" = "Linux" ]; then - echo "graph_order sleeping stopped zombie dead paging uninterruptible runnable processes" + echo "graph_order sleeping idle stopped zombie dead paging uninterruptible runnable processes" echo "dead.label dead" echo "dead.draw STACK" echo "dead.colour $DEAD" @@ -248,7 +245,20 @@ echo "sleeping.info The number of processes that are sleeping for less than about 20 seconds." print_warning sleeping print_critical sleeping - elif [ "$OPERSYS" = "Linux" ] || [ "$OPERSYS" = "SunOS" ] || [ "$OPERSYS" = "HP-UX" ]; then + elif [ "$OPERSYS" = "Linux" ]; then + echo "idle.label idle" + echo "idle.draw STACK" + echo "idle.colour $IDLE" + echo "idle.info The number of idle kernel threads (>= 4.2 kernels only)." + print_warning idle + print_critical idle + echo "sleeping.label sleeping" + echo "sleeping.draw AREA" + echo "sleeping.colour $SLEEPING" + echo "sleeping.info The number of sleeping processes." + print_warning sleeping + print_critical sleeping + elif [ "$OPERSYS" = "SunOS" ] || [ "$OPERSYS" = "HP-UX" ]; then echo "sleeping.label sleeping" echo "sleeping.draw AREA" echo "sleeping.colour $SLEEPING" @@ -288,7 +298,7 @@ echo "zombie.label zombie" echo "zombie.draw STACK" echo "zombie.colour $ZOMBIE" - echo "zombie.info The number of defunct ("zombie") processes (process terminated and parent not waiting)." + echo "zombie.info The number of defunct ('zombie') processes (process terminated and parent not waiting)." print_warning zombie print_critical zombie fi @@ -308,13 +318,15 @@ fi if [ "$OPERSYS" = "Linux" ]; then - $ps --no-header -eo s | $awk ' + # shellcheck disable=SC2016 + "$ps" --no-header -eo s | "$awk" ' { processes++; stat[$1]++ } END { print "processes.value " 0+processes; print "uninterruptible.value " 0+stat["D"]; print "runnable.value " 0+stat["R"]; print "sleeping.value " 0+stat["S"]; +print "idle.value " 0+stat["I"]; print "stopped.value " 0+stat["T"]; print "paging.value " 0+stat["W"]; print "dead.value " 0+stat["X"]; @@ -322,7 +334,8 @@ }' elif [ "$OPERSYS" = "SunOS" ]; then - $ps -e -o s | $awk ' + # shellcheck disable=SC2016 + "$ps" -e -o s | "$awk" ' { total++; stat[$1]++ } END { print "total.value " 0+total; @@ -333,7 +346,8 @@ print "zombie.value " 0+stat["Z"]; }' elif [ "$OPERSYS" = "FreeBSD" ]; then - $ps -axo state= | sed -e 's/^\(.\).*/\1/' | $awk ' + # shellcheck disable=SC2016 + "$ps" -axo state= | sed -e 's/^\(.\).*/\1/' | "$awk" ' { processes++; stat[$1]++ } END { print "processes.value " 0+processes; @@ -348,7 +362,8 @@ }' elif [ "$OPERSYS" = "OpenBSD" ]; then # First line is header. Remove it. - $ps -axo state= | sed '1d' | sed -e 's/^\(.\).*/\1/' | $awk ' + # shellcheck disable=SC2016 + "$ps" -axo state= | sed '1d' | sed -e 's/^\(.\).*/\1/' | "$awk" ' { processes++; stat[$1]++ } END { print "processes.value " 0+processes; @@ -361,7 +376,8 @@ }' elif [ "$OPERSYS" = "NetBSD" ]; then # First line is header. Remove it. - $ps -axo state= | sed '1d' | sed -e 's/^\(.\).*/\1/' | $awk ' + # shellcheck disable=SC2016 + "$ps" -axo state= | sed '1d' | sed -e 's/^\(.\).*/\1/' | "$awk" ' { processes++; stat[$1]++ } END { print "processes.value " 0+processes; @@ -376,7 +392,8 @@ elif [ "$OPERSYS" = "Darwin" ]; then # First line is header. Remove it. - $ps -axo state= | sed '1d' | sed -e 's/^\(.\).*/\1/' | $awk ' + # shellcheck disable=SC2016 + "$ps" -axo state= | sed '1d' | sed -e 's/^\(.\).*/\1/' | "$awk" ' { processes++; stat[$1]++ } END { print "processes.value " 0+processes; @@ -390,7 +407,8 @@ elif [ "$OPERSYS" = "CYGWIN" ]; then # First line is header. Remove it. Also remove WINPID duplicates. - $ps -aW | sed '1d' | cut -c 30-36 | sort -u | $awk ' + # shellcheck disable=SC2016 + "$ps" -aW | sed '1d' | cut -c 30-36 | sort -u | "$awk" ' { processes++; } END { print "processes.value " 0+processes; @@ -398,7 +416,8 @@ elif [ "$OPERSYS" = "HP-UX" ]; then # First line is header. Remove it. - $ps -el | sed '1d' | $awk '{print $2}' | $awk ' + # shellcheck disable=SC2016 + "$ps" -el | sed '1d' | "$awk" '{print $2}' | "$awk" ' { processes++; stat[$1]++ } END { print "processes.value " 0+processes; diff -Nru munin-2.0.37/plugins/node.d/ps_.in munin-2.0.47/plugins/node.d/ps_.in --- munin-2.0.37/plugins/node.d/ps_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/ps_.in 2019-02-28 14:43:36.000000000 +0000 @@ -39,31 +39,20 @@ =head1 MAGIC MARKERS - #%# family=auto - #%# capabilities=autoconf suggest + #%# family=manual =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" -myname=`basename $0 | sed 's/^ps_//g'` +myname=$(basename "$0" | sed 's/^ps_//g') name="${name-\<$myname\>}" REGEX="${regex-\<$name\>}" -if [ "$1" = "autoconf" ]; then - # Makes little sense to autoconf if you can't suggest - echo no - exit 0 -fi - -if [ "$1" = "suggest" ]; then - exit 0 -fi - if [ "$1" = "config" ]; then - echo graph_title Number of $myname processes + echo "graph_title Number of $myname processes" echo 'graph_args --base 1000 --vertical-label processes -l 0' echo 'graph_category processes' echo "count.label $myname" diff -Nru munin-2.0.37/plugins/node.d/psu_.in munin-2.0.47/plugins/node.d/psu_.in --- munin-2.0.37/plugins/node.d/psu_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/psu_.in 2019-02-28 14:43:36.000000000 +0000 @@ -41,7 +41,7 @@ EOF -name=`basename $0 | sed 's/^psu_//g'` +name=$(basename "$0" | sed 's/^psu_//g') if [ "$1" = "autoconf" ]; then echo yes @@ -54,7 +54,7 @@ if [ "$1" = "config" ]; then - echo graph_title Number of processes owned by $name + echo "graph_title Number of processes owned by $name" echo 'graph_args --base 1000 --vertical-label processes -l 0' echo 'graph_category processes' echo "count.label $name" diff -Nru munin-2.0.37/plugins/node.d/qmailqstat.in munin-2.0.47/plugins/node.d/qmailqstat.in --- munin-2.0.37/plugins/node.d/qmailqstat.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/qmailqstat.in 2019-02-28 14:43:36.000000000 +0000 @@ -16,22 +16,21 @@ # # Configuration: # [qmailstat] -# env.qmailstat /usr/bin/qmail-qstat +# env.qmailqstat /usr/bin/qmail-qstat # # Magic markers - optional - used by installation scripts and munin-config: # #%# family=auto #%# capabilities=autoconf -QMAILQSTAT=/var/qmail/bin/qmail-qstat -if [ "$qmailqstat" ]; then QMAILSTAT=$qmailqstat ; fi +QMAILQSTAT=${qmailqstat:-/var/qmail/bin/qmail-qstat} if [ "$1" = "autoconf" ]; then - if [ -f ${QMAILQSTAT} ] ; then + if [ -f "$QMAILQSTAT" ] ; then echo yes exit 0 else - echo no + echo "no (file ${QMAILQSTAT} not found)" exit 0 fi fi diff -Nru munin-2.0.37/plugins/node.d/qmailscan.in munin-2.0.47/plugins/node.d/qmailscan.in --- munin-2.0.37/plugins/node.d/qmailscan.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/qmailscan.in 2019-02-28 14:43:36.000000000 +0000 @@ -37,23 +37,23 @@ echo 'graph_args --base 1000 -l 0 ' echo 'graph_vlabel Daily Virus Types' echo 'graph_category Mail' - grep "`date +%d\ %b\ %Y`" $LOG0 $LOG1 | \ - grep -v 'Disallowed characters found in MIME headers|Disallowed breakage found in header name - potential virus|Disallowed MIME comment found in header name - potential virus' | \ - sed 's/clamdscan.*$//' | sed 's/[ \t]*$//' | \ - cut -f 5 | sort | uniq -c | sort -r | sed 's/\.\|-/_/g' | while read i; do - name=`echo $i | awk '{print $2}'`; - echo "$name.label $name" ; - echo "'$name.draw LINE2"; - done + grep "$(date "+%d %b %Y")" "$LOG0" "$LOG1" | \ + grep -vE 'Disallowed characters found in MIME headers|Disallowed breakage found in header name - potential virus|Disallowed MIME comment found in header name - potential virus' | \ + sed 's/clamdscan.*$//' | sed 's/[ \t]*$//' | \ + cut -f 5 | sort | uniq -c | sort -r | sed 's/\.\|-/_/g' | while read -r i; do + name=$(echo "$i" | awk '{print $2}') + echo "$name.label $name" + echo "$name.draw LINE2" + done exit 0 fi -grep "`date +%d\ %b\ %Y`" $LOG0 $LOG1 | \ - egrep -v 'Disallowed characters found in MIME headers|Disallowed breakage found in header name - potential virus|Disallowed MIME comment found in header name - potential virus' | \ - sed 's/clamdscan.*$//' | sed 's/[ \t]*$//' | \ - cut -f 5 | sort | uniq -c | sort -r | sed 's/\.\|-/_/g' | while read i; do - name=`echo $i | awk '{print $2}'`; - printf "%s.value " $name; - echo $i | awk '{print $1}' - done +grep "$(date "+%d %b %Y")" "$LOG0" "$LOG1" | \ + grep -vE 'Disallowed characters found in MIME headers|Disallowed breakage found in header name - potential virus|Disallowed MIME comment found in header name - potential virus' | \ + sed 's/clamdscan.*$//' | sed 's/[ \t]*$//' | \ + cut -f 5 | sort | uniq -c | sort -r | sed 's/\.\|-/_/g' | while read -r i; do + name=$(echo "$i" | awk '{print $2}') + printf "%s.value " "$name" + echo "$i" | awk '{print $1}' + done diff -Nru munin-2.0.37/plugins/node.d/samba.in munin-2.0.47/plugins/node.d/samba.in --- munin-2.0.37/plugins/node.d/samba.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/samba.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!@@GOODSH@@ +#!@@GOODSH@@ # -*- sh -*- : << =cut @@ -9,11 +9,20 @@ =head1 CONFIGURATION -This plugin uses the following configuration variables +This plugin uses the following configuration variables: [samba] - env.smbstatus - Path to "smbstatus" executable - env.ignoreipcshare - Set this variable to ignore IPC$ when counting shares. + user root + env.smbstatus /usr/bin/smbstatus + env.ignoreipcshare 1 + +Usually "smbstatus" requires to be run as root (see "user root" above). + +Environment variables: + + * smbstatus: path to "smbstatus" executable + (default: search PATH and fall back to /usr/bin/smbstatus) + * ignoreipcshare: set this variable to any non-empty value to ignore IPC$ when counting shares. =head1 AUTHOR @@ -30,17 +39,20 @@ =cut -SMBSTATUS=${smbstatus:-`which smbstatus`} +SMBSTATUS=${smbstatus:-$(which smbstatus)} SMBSTATUS=${SMBSTATUS:-/usr/bin/smbstatus} if [ "$1" = "autoconf" ]; then - if [ -x $SMBSTATUS ]; then - echo yes - exit 0 + if [ -x "$SMBSTATUS" ]; then + if "$SMBSTATUS" -V >/dev/null 2>&1; then + echo 'yes' + else + echo "no (failed to run $SMBSTATUS - maybe need to run as 'root'?)" + fi else - echo no '(smbstatus not found)' - exit 0 + echo 'no (smbstatus not found)' fi + exit 0 fi if [ "$1" = "config" ]; then @@ -60,15 +72,16 @@ $SMBSTATUS -p 2>/dev/null | awk 'BEGIN {lines=0} $1 ~ /^[0-9]+/ {lines++} END {print "proc.value " lines}' $SMBSTATUS -L 2>/dev/null | awk 'BEGIN {lines=0} $1 ~ /^[0-9]+/ {lines++} END {print "lock.value " lines}' -if [ -n "$ignoreipcshare" ]; then +if [ -n "${ignoreipcshare:-}" ]; then + # shellcheck disable=SC2016 IGNORE='$1=="IPC$" {next}' fi $SMBSTATUS -S 2>/dev/null | awk ' -BEGIN {lines=0;state=0} -$1=="Service"&&state==0 {state=1;next} -/^--*$/&&state==1 {state=2;next} -state<2 {next} -/^$/ {next} -'"$IGNORE"' -{lines++} -END {print "share.value " lines}' + BEGIN {lines=0;state=0} + $1=="Service" && state==0 {state=1; next} + /^--*$/ && state==1 {state=2; next} + state < 2 {next} + /^$/ {next} + '"$IGNORE"' + {lines++} + END {print "share.value " lines}' diff -Nru munin-2.0.37/plugins/node.d/sendmail_mailqueue.in munin-2.0.47/plugins/node.d/sendmail_mailqueue.in --- munin-2.0.37/plugins/node.d/sendmail_mailqueue.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/sendmail_mailqueue.in 2019-02-28 14:43:36.000000000 +0000 @@ -38,17 +38,15 @@ =cut -MSP_QUEUE=/var/spool/mqueue-client -MTA_QUEUE=/var/spool/mqueue -if [ "$mspqueue" ]; then MSP_QUEUE=$mspqueue ; fi -if [ "$mtaqueue" ]; then MTA_QUEUE=$mtaqueue ; fi +MSP_QUEUE=${mspqueue:-/var/spool/mqueue-client} +MTA_QUEUE=${mtaqueue:-/var/spool/mqueue} if [ "$1" = "autoconf" ]; then - if [ -d ${MSP_QUEUE} -a -d ${MTA_QUEUE} ] ; then + if [ -d "$MSP_QUEUE" ] && [ -d "$MTA_QUEUE" ] ; then echo yes exit 0 else - echo no + echo "no (directories ${MSP_QUEUE} and ${MTA_QUEUE} not found)" exit 0 fi fi @@ -65,6 +63,6 @@ # Append /. to directory to force following symlinks at the start # point. -mspmails=$(find ${MSP_QUEUE}/. -type f -name '[qQ]*' 2>/dev/null | fgrep -v '.hoststat' | wc -l) -mtamails=$(find ${MTA_QUEUE}/. -type f -name '[qQ]*' 2>/dev/null | fgrep -v '.hoststat' | wc -l) -echo "mails.value `expr ${mspmails} + ${mtamails}`" +mspmails=$(find "${MSP_QUEUE}/." -type f -name '[qQ]*' 2>/dev/null | grep -vF '.hoststat' | wc -l) +mtamails=$(find "${MTA_QUEUE}/." -type f -name '[qQ]*' 2>/dev/null | grep -vF '.hoststat' | wc -l) +echo "mails.value $((mspmails + mtamails))" diff -Nru munin-2.0.37/plugins/node.d/sendmail_mailstats.in munin-2.0.47/plugins/node.d/sendmail_mailstats.in --- munin-2.0.37/plugins/node.d/sendmail_mailstats.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/sendmail_mailstats.in 2019-02-28 14:43:36.000000000 +0000 @@ -33,22 +33,22 @@ =cut -if [ -n "$mailstats" ]; - then MAILSTATS=$mailstats; - else MAILSTATS=`which mailstats 2>/dev/null`; -fi + +MAILSTATS=${mailstats:-$(which mailstats 2>/dev/null)} + if [ "$1" = "autoconf" ]; then - if [ -n "$MAILSTATS" -a -x "$MAILSTATS" ] + if [ -n "$MAILSTATS" ] && [ -x "$MAILSTATS" ] then echo yes else echo "no (no mailstats command)" - fi + fi exit 0 fi if [ "$1" = "config" ]; then echo "graph_title Sendmail email traffic" echo "graph_order received sent rejected discarded" + # shellcheck disable=SC2016 echo 'graph_vlabel messages/${graph_period}' echo "graph_category sendmail" echo "discarded.label discarded" diff -Nru munin-2.0.37/plugins/node.d/sendmail_mailtraffic.in munin-2.0.47/plugins/node.d/sendmail_mailtraffic.in --- munin-2.0.37/plugins/node.d/sendmail_mailtraffic.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/sendmail_mailtraffic.in 2019-02-28 14:43:36.000000000 +0000 @@ -33,13 +33,12 @@ =cut -if [ -n "$mailstats" ]; - then MAILSTATS=$mailstats; - else MAILSTATS=`which mailstats 2>/dev/null`; -fi + +MAILSTATS=${mailstats:-$(which mailstats 2>/dev/null)} + if [ "$1" = "autoconf" ]; then - if [ -n "$MAILSTATS" -a -x "$MAILSTATS" ] + if [ -n "$MAILSTATS" ] && [ -x "$MAILSTATS" ] then echo yes else echo "no (no mailstats command)" fi @@ -50,6 +49,7 @@ echo "graph_title Sendmail email volumes" echo "graph_order received sent" + # shellcheck disable=SC2016 echo 'graph_vlabel bytes/${graph_period}' echo "graph_category sendmail" echo "received.label received" diff -Nru munin-2.0.37/plugins/node.d/slapd_bdb_cache_.in munin-2.0.47/plugins/node.d/slapd_bdb_cache_.in --- munin-2.0.37/plugins/node.d/slapd_bdb_cache_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/slapd_bdb_cache_.in 2019-02-28 14:43:36.000000000 +0000 @@ -2,7 +2,7 @@ # -*- perl -*- # # Plugin copyright Bjorn Ruberg 2005-2009 -# +# # Licensed under GPLv2. Be nice. # # Environment variables: @@ -17,7 +17,7 @@ # - title (Optional) The plugin's title. Useful if you # have more than one DIT installed. # - warning (Optional) A threshold integer value. Triggers -# plugin to send warnings if cache percentage +# plugin to send warnings if cache percentage # drops below the given value. # # Limitations: @@ -87,7 +87,7 @@ print "percent\n"; exit 0; } - + if ($config) { print < 'Bytes', 'title' => "Number of bytes sent", 'info' => "The graph shows the number of bytes sent", - 'scope' => "base" + 'scope' => "base" }, 'statistics_pdu' => { @@ -64,10 +64,10 @@ 'label' => 'PDUs', 'title' => "Number of PDUs sent", 'info' => "The graph shows the number of PDUs sent", - 'scope' => "base" + 'scope' => "base" }, # Referrals - 'statistics_referrals' + 'statistics_referrals' => { 'search' => "cn=Referrals,cn=Statistics", 'desc' => "The number of Referrals sent by the LDAP server.", @@ -75,7 +75,7 @@ 'label' => 'Referrals', 'title' => "Number of LDAP Referrals", 'info' => "The graph shows the number of referrals sent", - 'scope' => "base" + 'scope' => "base" }, # Entries 'statistics_entries' @@ -86,10 +86,10 @@ 'label' => 'Entries', 'title' => "Number of LDAP Entries", 'info' => "The graph shows the number of entries sent", - 'scope' => "base" + 'scope' => "base" }, # Only read Total - 'connections' + 'connections' => { 'search' => 'cn=Total,cn=Connections', 'desc' => 'The number of connections', @@ -101,7 +101,7 @@ }, # dn: cn=Write,cn=Waiters,cn=Monitor # dn: cn=Read,cn=Waiters,cn=Monitor - 'waiters' + 'waiters' => { 'search' => 'cn=Waiters', 'filter' => '(|(cn=Write)(cn=Read))', @@ -142,7 +142,7 @@ graph_category OpenLDAP graph_info $ops{$action}->{'info'} EOF - + if ($ops{$action}->{'label2'}) { while (my ($key, $val) = each (%{$ops{$action}->{'label2'}})) { my $name = $action . "_" . $key; @@ -174,7 +174,7 @@ 'cn'], ); $mesg->code && die $mesg->error; - + my $max = $mesg->count; for (my $i = 0 ; $i < $max ; $i++) { my $entry = $mesg->entry ($i); @@ -189,7 +189,7 @@ print "$name.info The difference between Initiated "; print "and Completed operations (should be 0)\n"; print "$name.warning 1\n"; - } + } } $ldap->unbind; @@ -206,10 +206,10 @@ if ($ARGV[0]) { if ($ARGV[0] eq 'autoconf') { # Check for Net::LDAP - if ($ret) { - print "no ($ret)\n"; - exit 0; - } + if ($ret) { + print "no ($ret)\n"; + exit 0; + } # Check for LDAP version 3 my $ldap = Net::LDAP->new ($server, version => 3) @@ -315,27 +315,24 @@ my $entry = $mesg->entry ($i); my $cn = $entry->get_value('cn'); if ($action =~ /operations(_diff)?$/) { - if ($1) { - my $opsInit = - $entry->get_value('monitorOpInitiated'); - my $opsComp = - $entry->get_value('monitorOpCompleted'); - print lc ("operations_diff_${cn}.value "); - print ($opsInit - $opsComp); - print "\n"; - } else { - print lc ("operations_${cn}.value "); - print $entry->get_value('monitorOpCompleted'), - "\n"; - } + if ($1) { + my $opsInit = $entry->get_value('monitorOpInitiated'); + my $opsComp = $entry->get_value('monitorOpCompleted'); + print lc ("operations_diff_${cn}.value "); + print ($opsInit - $opsComp); + print "\n"; + } else { + print lc ("operations_${cn}.value "); + print $entry->get_value('monitorOpCompleted'), "\n"; + } } else { - # Hotfix, must do for now - if ($action =~ /_/ || $action eq 'connections') { - print lc ("${action}.value "); - } else { - print lc ("${action}_${cn}.value "); - } - print $entry->get_value('monitorCounter'), "\n"; + # Hotfix, must do for now + if ($action =~ /_/ || $action eq 'connections') { + print lc ("${action}.value "); + } else { + print lc ("${action}_${cn}.value "); + } + print $entry->get_value('monitorCounter'), "\n"; } } $ldap->unbind; diff -Nru munin-2.0.37/plugins/node.d/smart_.in munin-2.0.47/plugins/node.d/smart_.in --- munin-2.0.37/plugins/node.d/smart_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/smart_.in 2019-02-28 14:43:36.000000000 +0000 @@ -17,7 +17,8 @@ # Parameters # smartpath - Specify path to smartctl program (Default: /usr/sbin/smartctl) # smartargs - Override '-a' argument passed to smartctl with '-A -i'+smartargs -# ignorestandby - Ignore the standby state of the drive and perform SMART query. Default: False +# ignorestandby - Ignore the standby state of the drive and perform SMART query. +# Default: False # ignoreexit - Bits in smartctl exit code to ignore, e.g. 64. Default: 0 # # Parameters can be specified on a per-drive basis, eg: @@ -68,8 +69,11 @@ # log to aid in understanding why smartctl exited with # a nonzero status. # v2.2 2014-08-22 - Add "ignoreexit" environment variable. +# v2.3 2018-08-10 - Improve readability, reduce code duplication, avoid shell expansion. +# v2.4 2018-12-19 - Ignore invalid threshold data # # Copyright (c) 2004-2009 Nicolas Stransky. +# Copyright (c) 2018 Lars Kruse # # Permission to use, copy, and modify this software with or without fee # is hereby granted, provided that this entire notice is included in @@ -84,186 +88,246 @@ # # # Magic markers -#%# capabilities=autoconf suggest -#%# family=auto +# #%# capabilities=autoconf suggest +# #%# family=auto +import collections import os import sys import string import pickle -from math import log +import subprocess # Increase verbosity (True/False) -> use munin-run --pidebug verbose = True if os.getenv('MUNIN_DEBUG') == '1' else False -## You may edit the following 3 variables +# collect configuration from environment +smartctl_bin = os.getenv('smartpath', '/usr/sbin/smartctl') +smartctl_args = os.getenv('smartargs', '-a') +smartctl_ignore_standby = bool(os.getenv('ignorestandby', False)) +smartctl_ignore_exitcode_bitmask = int(os.getenv('ignoreexit', 0)) + +# You may edit the following 3 variables # Suppress SMART warnings (True/False) report_warnings = True # You may not modify anything below this line -plugin_version = "2.2" -statefiledir = os.environ['MUNIN_PLUGSTATE'] +plugin_version = "2.4" + +# some disks report invalid threshold values +INVALID_THRESHOLDS_BLACKLIST = {"---"} + + +SmartCtlParseResult = collections.namedtuple("SmartCtlParseResult", + ("has_failed", "smart_data", "model", "is_empty")) + def verboselog(s): - sys.stderr.write(plugin_name+': '+s+'\n') + if verbose: + sys.stderr.write('{}: {}\n'.format(plugin_name, s)) + + +def guess_full_path(hard_drive): + """ try to find the full path for a given hard disk name + + None is returned if no device node was found. + """ + for dev_dir in ('/dev', '/dev/disk/by-id'): + full_path = os.path.join(dev_dir, hard_drive) + if os.path.exists(full_path): + return full_path + else: + return None + + +def is_fatal_exitcode(exit_code): + # The exit code represents a bitmask. + # Bits 0/1/2 belong to fatal errors (see smartctl's man page). Check if one of these is set. + return (exit_code & 0b111) > 0 -if not verbose: - verboselog = lambda s: None def read_values(hard_drive): - global emptyoutput + smart_values = {} try: verboselog('Reading S.M.A.R.T values') os.putenv('LC_ALL', 'C') - device = '/dev/'+hard_drive - if not os.path.exists(device): - device = '/dev/disk/by-id/'+hard_drive - smart_output = os.popen(os.getenv('smartpath', '/usr/sbin/smartctl')+' '+os.getenv('smartargs', '-a')+(os.getenv('ignorestandby', False) and ' ' or ' -n standby ')+'-A -i '+device) - read_values = 0 - lastline = None - for l in smart_output: - lastline = l - if l[:-1] == '': - read_values = 0 - elif l[:13] == 'Device Model:' or l[:7] == 'Device:': - model_list = l.split(':')[1].split() - try: - model_list.remove('Version') - except: - None - model = ''.join(model_list) - if read_values == 1: - smart_attribute = l.split() - smart_values[smart_attribute[1].replace('-', '_')] = {"value":smart_attribute[3], "threshold":smart_attribute[5]} - elif l[:18] == "ID# ATTRIBUTE_NAME": - # Start reading the Attributes block - read_values = 1 - exit_status = smart_output.close() - if exit_status != None: - # smartctl exit code is a bitmask, check man page. - num_exit_status = int(exit_status/256) # Python convention - num_exit_status = num_exit_status & ~int(os.getenv('ignoreexit', 0)) # Allow to turn off warnings for some bits + device = guess_full_path(hard_drive) + command_tokens = [smartctl_bin] + smartctl_args.split() + if not smartctl_ignore_standby: + command_tokens.extend(('-n', 'standby')) + command_tokens.extend(('-A', '-i', device)) + proc = subprocess.Popen(command_tokens, stdout=subprocess.PIPE) + stdout, stderr = proc.communicate() + in_table_data = False + last_output_line = None + model = "unknown" + for line in stdout.decode().splitlines(): + if not line: + # the table is finished + in_table_data = False + elif not in_table_data: + # process header data + if line.startswith('Device Model:') or line.startswith('Device:'): + value = line.split(':', 1)[1].strip() + # ignore the "Version" string + model = ' '.join(token for token in value.split() if token != 'Version') + elif line.startswith('ID# ATTRIBUTE_NAME'): + # Start reading the Attributes block + in_table_data = True + else: + # we can ignore other header lines + pass + else: + # this is a data table row + tokens = line.split() + key = tokens[1].replace('-', '_') + value = tokens[3] + threshold = None if tokens[5] in INVALID_THRESHOLDS_BLACKLIST else tokens[5] + smart_values[key] = {"value": value, "threshold": threshold} + last_output_line = line + real_exit_code = proc.returncode + if real_exit_code > 0: + # Allow to turn off warnings for some bits + num_exit_status = real_exit_code & ~smartctl_ignore_exitcode_bitmask else: num_exit_status = 0 if num_exit_status != 0: - if int(log(num_exit_status, 2)) <= 2: # bit code - verboselog('smartctl cannot access S.M.A.R.T values on drive '+hard_drive+'. Command exited with code '+str(num_exit_status)+' (bit '+str(int(log(num_exit_status, 2)))+')') - verboselog(lastline[:-1]) + if is_fatal_exitcode(num_exit_status): + verboselog('smartctl cannot access S.M.A.R.T values on drive {}. Command exited ' + 'with code {}'.format(hard_drive, num_exit_status)) + verboselog(last_output_line) else: - verboselog('smartctl exited with code '+str(num_exit_status)+' (bit '+str(int(log(num_exit_status, 2)))+'). '+hard_drive+' may be FAILING RIGHT NOW!') - except: - verboselog('Cannot access S.M.A.R.T values! Check user rights or proper smartmontools installation/arguments.') + # the error is not fatal, but we should announce a warning + verboselog('smartctl exited with code {}. {} may be FAILING RIGHT NOW!' + .format(num_exit_status, hard_drive)) + except Exception as exc: + verboselog('Cannot access S.M.A.R.T values ({})! Check user rights or proper ' + 'smartmontools installation/arguments.'.format(exc)) sys.exit(1) - if smart_values == {}: - verboselog('Can\'t find any S.M.A.R.T values in smartctl output!') - emptyoutput = True - #sys.exit(1) + if not smart_values: + verboselog("Can't find any S.M.A.R.T values in smartctl output!") + is_empty = True else: - emptyoutput = False - smart_values["smartctl_exit_status"] = {"value":str(num_exit_status), "threshold":"1"} - try: - smart_values["model"] = model - # For some reason we may have no value for "model" - except: - smart_values["model"] = "unknown" - return exit_status + is_empty = False + smart_values["smartctl_exit_status"] = {"value": str(num_exit_status), "threshold": "1"} + return SmartCtlParseResult(is_fatal_exitcode(real_exit_code), smart_values, model, is_empty) + + +def get_state_filename(hard_drive): + statefiledir = os.environ['MUNIN_PLUGSTATE'] + return os.path.join(statefiledir, "smart-{}.state".format(hard_drive)) + def open_state_file(hard_drive, mode): - return open(statefiledir+'/smart-'+'-'.join(hard_drive)+'.state', mode) + return open(get_state_filename(hard_drive), mode) -def update_state_file(hard_drive): + +def update_state_file(hard_drive, model, smart_values): + data_storage = dict(smart_values) + data_storage["model"] = model try: verboselog('Saving statefile') - pickle.dump(smart_values, open_state_file(hard_drive, "wb")) - except: - verboselog('Error trying to save state file! Check access rights') + pickle.dump(data_storage, open_state_file(hard_drive, "wb")) + except Exception as exc: + verboselog('Error trying to save state file ({})! Check access rights'.format(exc)) + + +def parse_state_file(hard_drive): + data = pickle.load(open_state_file(hard_drive, "rb")) + model = data.pop("model", "unknown") + return model, data -def print_plugin_values(hard_drive): - if not emptyoutput: + +def print_plugin_values(hard_drive, is_empty, smart_values): + if not is_empty: verboselog('Printing S.M.A.R.T values') - for key in smart_values.keys(): - if key == "model": - continue - print(key+".value "+smart_values[key]["value"]) + for key, content in smart_values.items(): + print("{}.value {}".format(key, content["value"])) else: print_unknown_from_statefile(hard_drive) + def print_config(hard_drive): - if os.path.exists(statefiledir+'/smart-'+'-'.join(hard_drive)+'.state'): + if os.path.exists(get_state_filename(hard_drive)): try: - verboselog('Try to recall previous S.M.A.R.T attributes for '+','.join(hard_drive)) - smart_values_state = pickle.load(open_state_file(hard_drive, "rb")) - except: - verboselog('Error opening existing state file!') + verboselog('Try to recall previous S.M.A.R.T attributes for {}' + .format(hard_drive)) + model, smart_values_state = parse_state_file(hard_drive) + except Exception as exc: + verboselog('Error opening existing state file ({})!'.format(exc)) sys.exit(1) else: verboselog('No state file, reading S.M.A.R.T values for the first time') - read_values(hard_drive[0]) - pickle.dump(smart_values, open_state_file(hard_drive, "wb")) - smart_values_state = smart_values + parsed_data = read_values(hard_drive) + update_state_file(hard_drive, parsed_data.model, parsed_data.smart_data) + model = parsed_data.model + smart_values_state = parsed_data.smart_data verboselog('Printing configuration') - print('graph_title S.M.A.R.T values for drive '+','.join(hard_drive)) + print('graph_title S.M.A.R.T values for drive {}'.format(hard_drive)) print('graph_vlabel Attribute S.M.A.R.T value') print('graph_args --base 1000 --lower-limit 0') print('graph_category disk') - print('graph_info This graph shows the value of all S.M.A.R.T attributes of drive '+','.join(hard_drive)+' ('+smart_values_state['model']+'). smartctl_exit_status is the return value of smartctl. A non-zero return value indicates an error, a potential error, or a fault on the drive.') - attributes = smart_values_state.keys() - for key in attributes: - if key in ['smartctl_exit_status', 'model']: - continue - print(key+'.label '+key) - if report_warnings: print(key+'.critical '+smart_values_state[key]["threshold"]+':') - print('smartctl_exit_status.label smartctl_exit_status') - if report_warnings: - print('smartctl_exit_status.warning '+smart_values_state['smartctl_exit_status']["threshold"]) + print('graph_info This graph shows the value of all S.M.A.R.T attributes of drive {} ({}). ' + 'smartctl_exit_status is the return value of smartctl. A non-zero return value ' + 'indicates an error, a potential error, or a fault on the drive.' + .format(hard_drive, model)) + for key, content in smart_values_state.items(): + print('{}.label {}'.format(key, key)) + if report_warnings: + if content["threshold"] is None: + # we did not parse a valid threshold + pass + elif key == 'smartctl_exit_status': + level = 'warning' + print('{}.{} {}'.format(key, level, content["threshold"])) + else: + level = "critical" + print('{}.{} {}:'.format(key, level, content["threshold"])) + def print_unknown_from_statefile(hard_drive): - if os.path.exists(statefiledir+'/smart-'+'-'.join(hard_drive)+'.state'): + if os.path.exists(get_state_filename(hard_drive)): try: - verboselog('Failed to get S.M.A.R.T values from drive. Try to recall previous S.M.A.R.T attributes for '+','.join(hard_drive)) - smart_values_state = pickle.load(open_state_file(hard_drive, "rb")) - except: - verboselog('Error opening existing state file!') + verboselog('Failed to get S.M.A.R.T values from drive. Try to recall previous ' + 'S.M.A.R.T attributes for {}'.format(hard_drive)) + model, smart_values_state = parse_state_file(hard_drive) + except Exception as exc: + verboselog('Error opening existing state file ({})!'.format(exc)) sys.exit(1) else: verboselog('No state file, reading S.M.A.R.T values for the first time') sys.exit(1) verboselog('Printing unknown values for all attributes in state file') - attributes = smart_values_state.keys() - for key in attributes: - if key == 'model': - continue - print(key+'.value U') + for key in smart_values_state.keys(): + print('{}.value U'.format(key)) -def get_hard_drive_name(): + +def get_hard_drive_name(plugin_name): try: - name = [plugin_name[plugin_name.index('_')+1:]] + name = plugin_name.split('_', 1)[1] if os.uname()[0] == "SunOS": - try: - # if hard_drive name starts with "rdsk" or "rmt", try to reconstruct the path - if name[0][0:4] == "rdsk": - name[0] = os.path.join("rdsk", name[0][4:]) - elif name[0][0:3] == "rmt": - name[0] = os.path.join("rmt", name[0][3:]) - except: - verboselog('Failed to find SunOS hard_drive') - if (not os.path.exists('/dev/'+name[0])) and (not os.path.exists('/dev/disk/by-id/'+name[0])): + # Special handling of hard_drive names starting with "rdsk" or "rmt". + # These are changed from "rdsk0" to "rdsk/0". + for prefix in ('rdsk', 'rmt'): + if name.startswith(prefix): + name = os.path.join(prefix, name[len(prefix):]) + if guess_full_path(name) is None: # For 3ware cards, we have to set multiple plugins for the same hard drive name. # Let's see if we find a '-' in the drive name. - if name[0].find('-') != -1: - # Put the drive name and it's number in a list - name = [name[0][:name[0].rindex('-')], name[0][name[0].rindex('-')+1:]] + if '-' in name: + name = name.split('-')[0] # Chech that the drive exists in /dev - if (not os.path.exists('/dev/'+name[0])) and (not os.path.exists('/dev/disk/by-id/'+name[0])): - verboselog('/dev/(disk/by-id/)?'+name[0]+' not found!') + if guess_full_path(name) is None: + verboselog('/dev/(disk/by-id/)? {} not found!'.format(name)) sys.exit(1) return name - except: - verboselog('No S.M.A.R.T device name found in plugin\'s symlink!') + except Exception as exc: + verboselog("No S.M.A.R.T device name found in plugin's symlink ({})!".format(exc)) sys.exit(1) + def find_smart_drives(): # Try to autodetect Linux, *BSD, SunOS drives. Don't try to autodetect drives on a 3Ware card. drives = [] @@ -273,70 +337,73 @@ try: for drive in os.listdir('/sys/block/'): if drive[:2] in ['md', 'fd', 'lo', 'ra', 'dm']: - continue # Ignore MD, Floppy, loop , RAM and LVM devices. + continue # Ignore MD, Floppy, loop , RAM and LVM devices. try: - verboselog('Trying '+drive+'...') - exit_status = read_values(drive) - if (exit_status is None or int(log(int(exit_status/256), 2)) > 2) and not emptyoutput: + verboselog('Trying {} ...'.format(drive)) + parsed_data = read_values(drive) + if not parsed_data.has_failed and not parsed_data.is_empty: drives.append(drive) - except: + except Exception: continue - except: + except Exception: verboselog('Failed to list devices in /sys/block') else: verboselog('Not running linux2.6, failing back to /proc/partitions') try: partitions = open('/proc/partitions', 'r') - L = partitions.readlines() - for l in L: + lines = partitions.readlines() + for l in lines: words = l.split() if len(words) == 0 or words[0][0] not in string.digits: continue if words[0] in ['1', '9', '58', '254']: - continue # Ignore RAM, md, LVM and LVM2 devices + # Ignore RAM, md, LVM and LVM2 devices + continue if words[-1][-1] not in string.digits: try: verboselog('Trying '+words[-1]+'...') - exit_status = read_values(words[-1]) - if (exit_status is None or int(log(int(exit_status/256), 2)) > 2) and not emptyoutput: + parsed_data = read_values(words[-1]) + if not parsed_data.has_failed and not parsed_data.is_empty: drives.append(words[-1]) - except: + except Exception: continue verboselog('Found drives in /proc/partitions ! '+str(drives)) - except: - verboselog('Failed to list devices in /proc/partitions') + except Exception as exc: + verboselog('Failed to list devices in /proc/partitions: {}'.format(exc)) elif os.uname()[0] == "OpenBSD": try: sysctl_kerndisks = os.popen('sysctl hw.disknames') kerndisks = sysctl_kerndisks.readline().strip() for drive in kerndisks[kerndisks.rindex('=')+1:].split(','): if drive[:2] in ['md', 'cd', 'fd']: - continue # Ignore Memory Disks, CD-ROM drives and Floppy + # Ignore Memory Disks, CD-ROM drives and Floppy + continue try: verboselog('Trying '+drive+'c...') - exit_status = read_values(drive+'c') - if (exit_status is None or int(log(int(exit_status/256), 2)) > 2) and not emptyoutput: + parsed_data = read_values(drive + 'c') + if not parsed_data.has_failed and not parsed_data.is_empty: drives.append(drive+'c') - except: + except Exception: continue - except: - verboselog('Failed to list OpenBSD disks') + except Exception as exc: + verboselog('Failed to list OpenBSD disks: {}'.format(exc)) elif os.uname()[0] == "FreeBSD": try: sysctl_kerndisks = os.popen('sysctl kern.disks') kerndisks = sysctl_kerndisks.readline().strip() for drive in kerndisks.split()[1:]: if drive[:2] in ['md', 'cd', 'fd']: - continue # Ignore Memory Disks, CD-ROM drives and Floppy + # Ignore Memory Disks, CD-ROM drives and Floppy + continue try: verboselog('Trying '+drive+'...') - exit_status = read_values(drive) - if (exit_status is None or int(log(int(exit_status/256), 2)) > 2) and not emptyoutput: + parsed_data = read_values(drive) + if not parsed_data.has_failed and not parsed_data.is_empty: drives.append(drive) - except: + except Exception: continue - except: - verboselog('Failed to list FreeBSD disks') + except Exception as exc: + verboselog('Failed to list FreeBSD disks: {}'.format(exc)) elif os.uname()[0] == "Darwin": try: from glob import glob @@ -344,69 +411,69 @@ try: drive = os.path.basename(drivepath) verboselog('Trying '+drive+'...') - exit_status = read_values(drive) - if (exit_status is None or int(log(int(exit_status/256), 2)) > 2) and not emptyoutput: + parsed_data = read_values(drive) + if not parsed_data.has_failed and not parsed_data.is_empty: drives.append(drive) - except: + except Exception: continue - except: - verboselog('Failed to list Darwin disks') + except Exception as exc: + verboselog('Failed to list Darwin disks: {}'.format(exc)) elif os.uname()[0] == "NetBSD": try: sysctl_kerndisks = os.popen('sysctl hw.disknames') kerndisks = sysctl_kerndisks.readline().strip() for drive in kerndisks.split()[2:]: if drive[:2] in ['md', 'cd', 'fd']: - continue # Ignore Memory Disks, CD-ROM drives and Floppy + # Ignore Memory Disks, CD-ROM drives and Floppy + continue try: - verboselog('Trying '+drive+'c...') - exit_status = read_values(drive+'c') - if (exit_status is None or int(log(int(exit_status/256), 2)) > 2) and not emptyoutput: - drives.append(drive+'c') - except: + verboselog('Trying {} ...'.format(drive)) + parsed_data = read_values(drive + 'c') + if not parsed_data.has_failed and not parsed_data.is_empty: + drives.append(drive + 'c') + except Exception: continue - except: - verboselog('Failed to list NetBSD disks') + except Exception as exc: + verboselog('Failed to list NetBSD disks: {}'.format(exc)) elif os.uname()[0] == "SunOS": try: from glob import glob for drivepath in glob('/dev/rdsk/*s2'): try: drive = os.path.basename(drivepath) - verboselog('Trying rdsk'+drive+'...') - exit_status = read_values('rdsk'+drive) - if (exit_status is None or int(log(int(exit_status/256), 2)) > 2) and not emptyoutput: - drives.append('rdsk'+drive) - except: + verboselog('Trying rdsk {} ...'.format(drive)) + parsed_data = read_values('rdsk' + drive) + if not parsed_data.has_failed and not parsed_data.is_empty: + drives.append('rdsk' + drive) + except Exception: continue for drivepath in glob('/dev/rmt/*'): try: drive = os.path.basename(drivepath) - verboselog('Trying rmt'+drive+'...') - exit_status = read_values('rmt'+drive) - if (exit_status is None or int(log(int(exit_status/256), 2)) > 2) and not emptyoutput: - drives.append('rmt'+drive) - except: + verboselog('Trying rmt {} ...'.format(drive)) + parsed_data = read_values('rmt' + drive) + if not parsed_data.has_failed and not parsed_data.is_empty: + drives.append('rmt' + drive) + except Exception: continue - except: + except Exception: verboselog('Failed to list SunOS disks') return drives -### Main part ### -smart_values = {} -emptyoutput = False +""" Main part """ + plugin_name = list(os.path.split(sys.argv[0]))[1] -verboselog('plugins\' UID: '+str(os.geteuid())+' / plugins\' GID: '+str(os.getegid())) +verboselog("plugins' UID: {:d} / plugins' GID: {:d}".format(os.geteuid(), os.getegid())) # Parse arguments if len(sys.argv) > 1: if sys.argv[1] == "config": - hard_drive = get_hard_drive_name() + hard_drive = get_hard_drive_name(plugin_name) print_config(hard_drive) sys.exit(0) elif sys.argv[1] == "autoconf": - if os.path.exists(os.getenv('smartpath', '/usr/sbin/smartctl')): + if os.path.exists(smartctl_bin): if not find_smart_drives(): print('no (no drives accessible)') else: @@ -427,15 +494,15 @@ sys.exit(1) # No argument given, doing the real job: -hard_drive = get_hard_drive_name() -read_values(hard_drive[0]) -if not emptyoutput: - update_state_file(hard_drive) -print_plugin_values(hard_drive) +hard_drive = get_hard_drive_name(plugin_name) +parsed_data = read_values(hard_drive) +if not parsed_data.is_empty: + update_state_file(hard_drive, parsed_data.model, parsed_data.smart_data) +print_plugin_values(hard_drive, parsed_data.is_empty, parsed_data.smart_data) sys.exit(0) -### The following is the smart_ plugin documentation, intended to be used with munindoc +# The following is the smart_ plugin documentation, intended to be used with munindoc """ =head1 NAME diff -Nru munin-2.0.37/plugins/node.d/snmp__cpuload.in munin-2.0.47/plugins/node.d/snmp__cpuload.in --- munin-2.0.37/plugins/node.d/snmp__cpuload.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__cpuload.in 2019-02-28 14:43:36.000000000 +0000 @@ -91,8 +91,8 @@ print <<'EOC'; graph_title CPU usage in percent graph_category system -graph_args --upper-limit 100 -l 0 -graph_vlabel % +graph_args --upper-limit 100 -l 0 +graph_vlabel % graph_info This graph shows the CPU load on the system. EOC foreach my $cpu (keys %cpus) { diff -Nru munin-2.0.37/plugins/node.d/snmp__df_ram.in munin-2.0.47/plugins/node.d/snmp__df_ram.in --- munin-2.0.37/plugins/node.d/snmp__df_ram.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__df_ram.in 2019-02-28 14:43:36.000000000 +0000 @@ -19,7 +19,7 @@ Copyright (C) 2011 Erik Inge Bolsø, Redpill Linpro AS for OSL -Based on snmp__df (C) 2004 Jimmy Olsen +Based on snmp__df (C) 2004 Jimmy Olsen =head1 LICENSE @@ -115,7 +115,7 @@ foreach my $id (keys %$correct_capacity) { - if (exists $correct_type->{$id} and + if (exists $correct_type->{$id} and exists $correct_removable->{$id}) { push (@keep, $id); @@ -162,7 +162,7 @@ $partitions{$spart}{extinfo} = $part; $stor_id->{$id} = $spart; } -} else +} else { # Get the ones we're sure about $stor_id = get_by_regex ($session, $hrStorageDesc, '(^'.join('$|^',keys(%partitions)).'$)'); diff -Nru munin-2.0.37/plugins/node.d/snmp__fc_if_err_.in munin-2.0.47/plugins/node.d/snmp__fc_if_err_.in --- munin-2.0.37/plugins/node.d/snmp__fc_if_err_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__fc_if_err_.in 2019-02-28 14:43:36.000000000 +0000 @@ -58,7 +58,7 @@ die "# Error: couldn't understand what I'm supposed to monitor."; } -my $fcEntryDescr = "1.3.6.1.2.1.8888.1.1.6.1.16.16.0.8.0.136.3.52.64.0.0.0.0.0.0.0.0.$iface"; +my $fcEntryDescr = "1.3.6.1.2.1.8888.1.1.6.1.16.16.0.8.0.136.3.52.64.0.0.0.0.0.0.0.0.$iface"; my $fcEntrySpeed = "1.3.6.1.2.1.8888.1.1.6.1.14.16.0.8.0.136.3.52.64.0.0.0.0.0.0.0.0.$iface"; my $fcEntryStatus = "1.3.6.1.2.1.8888.1.1.6.1.6.16.0.8.0.136.3.52.64.0.0.0.0.0.0.0.0.$iface"; my $fcEntryErrs = "1.3.6.1.2.1.8888.1.3.1.1.2.16.0.8.0.136.3.52.64.0.0.0.0.0.0.0.0.$iface"; @@ -99,7 +99,7 @@ print "errs.type DERIVE\n"; print "errs.min 0\n"; print "errs.max 4000000000\n"; - exit 0; + exit 0; } my $status = 1; diff -Nru munin-2.0.37/plugins/node.d/snmp__fc_if_.in munin-2.0.47/plugins/node.d/snmp__fc_if_.in --- munin-2.0.37/plugins/node.d/snmp__fc_if_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__fc_if_.in 2019-02-28 14:43:36.000000000 +0000 @@ -80,7 +80,7 @@ die "# Error: couldn't understand what I'm supposed to monitor."; } -my $fcEntryDescr = "1.3.6.1.2.1.8888.1.1.6.1.16.16.0.8.0.136.3.52.64.0.0.0.0.0.0.0.0.$iface"; +my $fcEntryDescr = "1.3.6.1.2.1.8888.1.1.6.1.16.16.0.8.0.136.3.52.64.0.0.0.0.0.0.0.0.$iface"; my $fcEntrySpeed = "1.3.6.1.2.1.8888.1.1.6.1.14.16.0.8.0.136.3.52.64.0.0.0.0.0.0.0.0.$iface"; my $fcEntryStatus = "1.3.6.1.2.1.8888.1.1.6.1.6.16.0.8.0.136.3.52.64.0.0.0.0.0.0.0.0.$iface"; my $fcEntryInOctets = "1.3.6.1.2.1.8888.1.3.1.1.6.16.0.8.0.136.3.52.64.0.0.0.0.0.0.0.0.$iface"; @@ -129,7 +129,7 @@ print "recv.graph no\n"; print "recv.cdef recv,8,*\n"; print "recv.max 4000000000\n"; - print "recv.warning ", (-$warn), "\n" if defined $warn; + print "recv.warning $warn\n" if defined $warn; print "send.label bps\n"; print "send.type DERIVE\n"; print "send.min 0\n"; @@ -137,7 +137,7 @@ print "send.cdef send,8,*\n"; print "send.max 4000000000\n"; print "send.warning $warn\n" if defined $warn; - exit 0; + exit 0; } my $status = 1; diff -Nru munin-2.0.37/plugins/node.d/snmp__if_multi.in munin-2.0.47/plugins/node.d/snmp__if_multi.in --- munin-2.0.37/plugins/node.d/snmp__if_multi.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__if_multi.in 2019-02-28 14:43:36.000000000 +0000 @@ -529,7 +529,7 @@ my @mediatypes = split(/[ ,]+/,$mediatypes); # Hash of numerical media types the user finds interesting. - my $mediatype={}; + my $mediatype={}; if ($mediatypes eq 'ALL') { $mediatype = undef; @@ -666,7 +666,7 @@ print "recv.cdef recv,8,*\n"; print "recv.max $speed\n" if $speed; print "recv.min 0\n"; - print "recv.warning ", (-$warn), "\n" if defined $warn; + print "recv.warning $warn\n" if defined $warn; print "send.label bps\n"; print "send.type DERIVE\n"; print "send.negative recv\n"; diff -Nru munin-2.0.37/plugins/node.d/snmp__load.in munin-2.0.47/plugins/node.d/snmp__load.in --- munin-2.0.37/plugins/node.d/snmp__load.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__load.in 2019-02-28 14:43:36.000000000 +0000 @@ -82,7 +82,7 @@ print "host_name $host\n" unless $host eq 'localhost'; print <<"EOC"; graph_title Load average -graph_args --base 1000 -l 0 +graph_args --base 1000 -l 0 graph_vlabel load graph_category system graph_info This graph shows the load average on the host. Load average is a rough way of estimating how hard the machine works. Optimally, a load average should be equal to or lower than the number of CPUs on the machine. diff -Nru munin-2.0.37/plugins/node.d/snmp__memory.in munin-2.0.47/plugins/node.d/snmp__memory.in --- munin-2.0.37/plugins/node.d/snmp__memory.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__memory.in 2019-02-28 14:43:36.000000000 +0000 @@ -78,18 +78,18 @@ # some devices reports negative memtotal value print "# Total memsize reported $memsize..." if $Munin::Plugin::SNMP::DEBUG; - if ($memsize > 0) + if ($memsize > 0) { - print "graph_args --base 1024 -l 0 --upper-limit $memsize\n"; + print "graph_args --base 1024 -l 0 --upper-limit $memsize\n"; } else { - print "graph_args --base 1024 -l 0\n"; + print "graph_args --base 1024 -l 0\n"; } print "memory.draw AREA\n"; print "memory.label memory\n"; - + exit 0; } diff -Nru munin-2.0.37/plugins/node.d/snmp__netapp_diskusage_.in munin-2.0.47/plugins/node.d/snmp__netapp_diskusage_.in --- munin-2.0.37/plugins/node.d/snmp__netapp_diskusage_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__netapp_diskusage_.in 2019-02-28 14:43:36.000000000 +0000 @@ -15,7 +15,7 @@ Unfortunately, SNMPv3 is not fully supported on all NetApp equipments. For this reason, this plugin will use SNMPv2 by default, which is -insecure because it doesn't encrypt the community string. +insecure because it doesn't encrypt the community string. The following parameters will help you get this plugin working : diff -Nru munin-2.0.37/plugins/node.d/snmp__netapp_inodeusage_.in munin-2.0.47/plugins/node.d/snmp__netapp_inodeusage_.in --- munin-2.0.37/plugins/node.d/snmp__netapp_inodeusage_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__netapp_inodeusage_.in 2019-02-28 14:43:36.000000000 +0000 @@ -15,7 +15,7 @@ Unfortunately, SNMPv3 is not fully supported on all NetApp equipments. For this reason, this plugin will use SNMPv2 by default, which is -insecure because it doesn't encrypt the community string. +insecure because it doesn't encrypt the community string. The following parameters will help you get this plugin working : diff -Nru munin-2.0.37/plugins/node.d/snmp__netstat.in munin-2.0.47/plugins/node.d/snmp__netstat.in --- munin-2.0.37/plugins/node.d/snmp__netstat.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__netstat.in 2019-02-28 14:43:36.000000000 +0000 @@ -35,7 +35,7 @@ =head1 MIB INFORMATION -This plugin requires support for the TCP-MIB (RFC 4022). It reports +This plugin requires support for the TCP-MIB (RFC 4022). It reports the contents of the tcpConnState column of tcpConnTable. =head1 MAGIC MARKERS diff -Nru munin-2.0.37/plugins/node.d/snmp__print_pages.in munin-2.0.47/plugins/node.d/snmp__print_pages.in --- munin-2.0.37/plugins/node.d/snmp__print_pages.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__print_pages.in 2019-02-28 14:43:36.000000000 +0000 @@ -3,15 +3,15 @@ =head1 NAME -snmp__print_supplies - SNMP plugin to monitor pages printed on -printers adhering to RFC1759. +snmp__print_supplies - SNMP plugin to monitor pages printed on +printers adhering to RFC1759. =head1 APPLICABLE SYSTEMS Any SNMP capable printer adhering to RFC1759. Using a command such as "munin-node-configure --snmp xerox.skillingstad.no --snmpversion 2c --snmpcommunity public | sh -x" should auto-detect all applicable -interfaces. +interfaces. =head1 CONFIGURATION @@ -21,7 +21,7 @@ [snmp_*] env.version 2 env.community public - + In general SNMP is not very secure at all unless you use SNMP version 3 which supports authentication and privacy (encryption). But in any case the community string for your devices should not be "public". @@ -33,13 +33,13 @@ #%# family=snmpauto #%# capabilities=snmpconf - + =head1 VERSION - + $Id: $ - + =head1 BUGS - + For printers having duplex module: pages != number of sheets =head1 AUTHOR @@ -75,10 +75,10 @@ if(defined $ARGV[0] and $ARGV[0] eq "config") { my ($host,undef,$version) = Munin::Plugin::SNMP->config_session(); - + print "host_name $host\n" unless $host eq 'localhost'; print "graph_title Pages -graph_args --base 1000 -l 0 +graph_args --base 1000 -l 0 graph_vlabel Printed pages pr minute graph_scale no graph_category print diff -Nru munin-2.0.37/plugins/node.d/snmp__print_supplies.in munin-2.0.47/plugins/node.d/snmp__print_supplies.in --- munin-2.0.37/plugins/node.d/snmp__print_supplies.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__print_supplies.in 2019-02-28 14:43:36.000000000 +0000 @@ -4,7 +4,7 @@ =head1 NAME -snmp__print_supplies - SNMP plugin to monitor supplies levels on +snmp__print_supplies - SNMP plugin to monitor supplies levels on printers adhering to RFC1759 =head1 APPLICABLE SYSTEMS @@ -12,7 +12,7 @@ Any SNMP capable printer adhering to RFC1759. Using a command such as "munin-node-configure --snmp xerox.skillingstad.no --snmpversion 2c --snmpcommunity public | sh -x" should auto-detect all applicable -interfaces. +interfaces. =head1 CONFIGURATION @@ -39,13 +39,13 @@ #%# family=snmpauto #%# capabilities=snmpconf - + =head1 VERSION - + $Id: $ - + =head1 BUGS - + None known. =head1 AUTHOR @@ -77,7 +77,7 @@ } -my ($session, $error); +my ($session, $error); # SNMP needed for both config and fetch. $session = Munin::Plugin::SNMP->session(); @@ -94,7 +94,7 @@ # Configure if(defined $ARGV[0] and $ARGV[0] eq "config") { my ($host,undef,$version) = Munin::Plugin::SNMP->config_session(); - + print "host_name $host\n" unless $host eq 'localhost'; print "graph_title Supply Level\n"; print "graph_args --base 1000 -l 0 --upper-limit 100\n"; @@ -102,9 +102,9 @@ print "graph_scale no\n"; print "graph_category print\n"; print "graph_info This graph represents supplies level\n"; - + foreach my $supply (keys(%supplies)) { - print "supply$supply.label ".(length($supplies{$supply}{desc})<=$MAXLABEL ? + print "supply$supply.label ".(length($supplies{$supply}{desc})<=$MAXLABEL ? $supplies{$supply}{desc} : substr($supplies{$supply}{desc},0,($MAXLABEL-3))."..."); print "\n"; print "supply$supply.draw LINE1\n"; @@ -112,7 +112,7 @@ print "supply$supply.warning $warning:100\n"; print "supply$supply.critical $critical:100\n"; } - + exit 0; } @@ -128,9 +128,9 @@ my $session = shift; my $oid = shift; my $type = shift; - + print "# Getting table $oid...\n" if $Munin::Plugin::SNMP::DEBUG; - + my $response = $session->get_table($oid); if(!defined($response)) { diff -Nru munin-2.0.37/plugins/node.d/snmp__processes.in munin-2.0.47/plugins/node.d/snmp__processes.in --- munin-2.0.37/plugins/node.d/snmp__processes.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__processes.in 2019-02-28 14:43:36.000000000 +0000 @@ -81,7 +81,7 @@ print "host_name $host\n" unless ($host eq 'localhost'); print <<'EOC'; graph_title Number of Processes -graph_args --base 1000 -l 0 +graph_args --base 1000 -l 0 graph_vlabel number of processes graph_category system graph_info This graph shows the number of processes running on the system. diff -Nru munin-2.0.37/plugins/node.d/snmp__rdp_users.in munin-2.0.47/plugins/node.d/snmp__rdp_users.in --- munin-2.0.37/plugins/node.d/snmp__rdp_users.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__rdp_users.in 2019-02-28 14:43:36.000000000 +0000 @@ -83,7 +83,7 @@ print "host_name $host\n" unless $host eq 'localhost'; print <<"EOC"; graph_title Number of RDP users -graph_args --base 1000 -l 0 +graph_args --base 1000 -l 0 graph_vlabel number of RDP users graph_scale no graph_category system diff -Nru munin-2.0.37/plugins/node.d/snmp__sensors_fsc_bx_fan.in munin-2.0.47/plugins/node.d/snmp__sensors_fsc_bx_fan.in --- munin-2.0.37/plugins/node.d/snmp__sensors_fsc_bx_fan.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__sensors_fsc_bx_fan.in 2019-02-28 14:43:36.000000000 +0000 @@ -98,7 +98,7 @@ print 'graph_order ', join(' ', map { get_id($_) } oid_lex_sort keys %$fans), "\n"; print 'host_name ', $session->hostname(), "\n" unless $session->hostname eq 'localhost'; - + for my $fan (keys %$fans) { my $id = get_id($fan); for my $key (qw(label warning)) { diff -Nru munin-2.0.37/plugins/node.d/snmp__sensors_fsc_bx_temp.in munin-2.0.47/plugins/node.d/snmp__sensors_fsc_bx_temp.in --- munin-2.0.37/plugins/node.d/snmp__sensors_fsc_bx_temp.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__sensors_fsc_bx_temp.in 2019-02-28 14:43:36.000000000 +0000 @@ -117,7 +117,7 @@ print 'graph_order ', join(' ', map { get_id($_) } oid_lex_sort keys %$temps), "\n"; print 'host_name ', $session->hostname(), "\n" unless $session->hostname eq 'localhost'; - + for my $sensor (keys %$temps) { my $id = get_id($sensor); for my $key (qw(label warning critical info)) { diff -Nru munin-2.0.37/plugins/node.d/snmp__sensors_fsc_fan.in munin-2.0.47/plugins/node.d/snmp__sensors_fsc_fan.in --- munin-2.0.37/plugins/node.d/snmp__sensors_fsc_fan.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__sensors_fsc_fan.in 2019-02-28 14:43:36.000000000 +0000 @@ -93,7 +93,7 @@ print 'graph_order ', join(' ', map { get_id($_) } oid_lex_sort keys %$fans), "\n"; print 'host_name ', $session->hostname(), "\n" unless $session->hostname eq 'localhost'; - + for my $fan (keys %$fans) { my $id = get_id($fan); for my $key (qw(label info)) { diff -Nru munin-2.0.37/plugins/node.d/snmp__sensors_fsc_temp.in munin-2.0.47/plugins/node.d/snmp__sensors_fsc_temp.in --- munin-2.0.37/plugins/node.d/snmp__sensors_fsc_temp.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__sensors_fsc_temp.in 2019-02-28 14:43:36.000000000 +0000 @@ -95,7 +95,7 @@ print 'graph_order ', join(' ', map { get_id($_) } oid_lex_sort keys %$temps), "\n"; print 'host_name ', $session->hostname(), "\n" unless $session->hostname eq 'localhost'; - + for my $sensor (keys %$temps) { my $id = get_id($sensor); for my $key (qw(label warning critical info)) { diff -Nru munin-2.0.37/plugins/node.d/snmp__swap.in munin-2.0.47/plugins/node.d/snmp__swap.in --- munin-2.0.37/plugins/node.d/snmp__swap.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__swap.in 2019-02-28 14:43:36.000000000 +0000 @@ -33,9 +33,9 @@ my $response; if (defined $ARGV[0] and $ARGV[0] eq "snmpconf") { - # HOST-RESOURCES-MIB::hrStorageType + # HOST-RESOURCES-MIB::hrStorageType # HOST-RESOURCES-TYPES::hrStorageVirtualMemory - print "require 1.3.6.1.2.1.25.2.3.1.2. 1.3.6.1.2.1.25.2.1.3\n"; + print "require 1.3.6.1.2.1.25.2.3.1.2. 1.3.6.1.2.1.25.2.1.3\n"; exit 0; } diff -Nru munin-2.0.37/plugins/node.d/snmp__users.in munin-2.0.47/plugins/node.d/snmp__users.in --- munin-2.0.37/plugins/node.d/snmp__users.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__users.in 2019-02-28 14:43:36.000000000 +0000 @@ -80,7 +80,7 @@ print "host_name $host\n" unless $host eq 'localhost'; print <<"EOC"; graph_title Number of users -graph_args --base 1000 -l 0 +graph_args --base 1000 -l 0 graph_vlabel number of users graph_scale no graph_category system @@ -94,4 +94,3 @@ my $session = Munin::Plugin::SNMP->session(); print "users.value ", $session->get_single('1.3.6.1.2.1.25.1.5.0'), "\n"; - diff -Nru munin-2.0.37/plugins/node.d/snmp__winload.in munin-2.0.47/plugins/node.d/snmp__winload.in --- munin-2.0.37/plugins/node.d/snmp__winload.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snmp__winload.in 2019-02-28 14:43:36.000000000 +0000 @@ -38,7 +38,7 @@ my ($host) = Munin::Plugin::SNMP->config_session(); print "host_name $host\n" unless $host eq 'localhost'; print "graph_title Windows CPU load -graph_args --base 1000 -l 0 +graph_args --base 1000 -l 0 graph_vlabel Load graph_scale no graph_category System diff -Nru munin-2.0.37/plugins/node.d/snort_alerts.in munin-2.0.47/plugins/node.d/snort_alerts.in --- munin-2.0.37/plugins/node.d/snort_alerts.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snort_alerts.in 2019-02-28 14:43:36.000000000 +0000 @@ -57,14 +57,11 @@ =cut -if [ -z $statsfile ]; then - _target=/var/snort/snort.stats -else - _target=$statsfile -fi +_target=${statsfile:-/var/snort/snort.stats} + if [ "$1" = "autoconf" ]; then - if [ -f $_target ]; then + if [ -f "$_target" ]; then echo yes else echo "no ($_target not readable)" @@ -78,12 +75,12 @@ echo 'graph_vlabel Alerts / second' echo 'graph_scale no' echo 'alerts.label Alerts/second' - if [ -n "$warning" ]; then - echo "alerts.warning $warning" - fi - if [ -n "$critical" ]; then - echo "alerts.critical $critical" - fi + if [ -n "${warning:-}" ]; then + echo "alerts.warning $warning" + fi + if [ -n "${critical:-}" ]; then + echo "alerts.critical $critical" + fi echo 'alerts.info The number of alerts per second' echo 'graph_category Snort' @@ -91,4 +88,4 @@ fi printf "alerts.value " -echo $(tail -n1 $_target| awk -F, '{ print $4 }') +tail -n1 "$_target" | awk -F, '{ print $4 }' diff -Nru munin-2.0.37/plugins/node.d/snort_bytes_pkt.in munin-2.0.47/plugins/node.d/snort_bytes_pkt.in --- munin-2.0.37/plugins/node.d/snort_bytes_pkt.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snort_bytes_pkt.in 2019-02-28 14:43:36.000000000 +0000 @@ -57,14 +57,11 @@ =cut -if [ -z $statsfile ]; then - _target=/var/snort/snort.stats -else - _target=$statsfile -fi +_target=${statsfile:-/var/snort/snort.stats} + if [ "$1" = "autoconf" ]; then - if [ -f $_target ]; then + if [ -f "$_target" ]; then echo yes else echo "no ($_target not readable)" @@ -78,12 +75,12 @@ echo 'graph_vlabel KBytes / pkt' echo 'graph_scale no' echo 'bytes_pkt.label KBytes/pkt' - if [ -n "$warning" ]; then - echo "bytes_pkt.warning $warning" - fi - if [ -n "$critical" ]; then - echo "bytes_pkt.critical $critical" - fi + if [ -n "${warning:-}" ]; then + echo "bytes_pkt.warning $warning" + fi + if [ -n "${critical:-}" ]; then + echo "bytes_pkt.critical $critical" + fi echo 'bytes_pkt.info Average size per packet' echo 'graph_category Snort' @@ -91,4 +88,4 @@ fi printf "bytes_pkt.value " -echo $(tail -n1 $_target| awk -F, '{ print $6 }') +tail -n1 "$_target" | awk -F, '{ print $6 }' diff -Nru munin-2.0.37/plugins/node.d/snort_drop_rate.in munin-2.0.47/plugins/node.d/snort_drop_rate.in --- munin-2.0.37/plugins/node.d/snort_drop_rate.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snort_drop_rate.in 2019-02-28 14:43:36.000000000 +0000 @@ -57,14 +57,11 @@ =cut -if [ -z $statsfile ]; then - _target=/var/snort/snort.stats -else - _target=$statsfile -fi +_target=${statsfile:-/var/snort/snort.stats} + if [ "$1" = "autoconf" ]; then - if [ -f $_target ]; then + if [ -f "$_target" ]; then echo yes else echo "no ($_target not readable)" @@ -78,12 +75,12 @@ echo 'graph_vlabel % percent' echo 'graph_scale no' echo 'droprate.label % percent' - if [ -n "$warning" ]; then - echo "droprate.warning $warning" - fi - if [ -n "$critical" ]; then - echo "droprate.critical $critical" - fi + if [ -n "${warning:-}" ]; then + echo "droprate.warning $warning" + fi + if [ -n "${critical:-}" ]; then + echo "droprate.critical $critical" + fi echo 'droprate.info Packet drop rate in %' echo 'graph_category Snort' @@ -91,4 +88,4 @@ fi printf "droprate.value " -echo $(tail -n1 $_target| awk -F, '{ print $2 }') +tail -n1 "$_target" | awk -F, '{ print $2 }' diff -Nru munin-2.0.37/plugins/node.d/snort_pattern_match.in munin-2.0.47/plugins/node.d/snort_pattern_match.in --- munin-2.0.37/plugins/node.d/snort_pattern_match.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snort_pattern_match.in 2019-02-28 14:43:36.000000000 +0000 @@ -5,7 +5,7 @@ =head1 NAME -snort_pattmatch - Plugin to monitor percent of data received that +snort_pattmatch - Plugin to monitor percent of data received that Snort processes in pattern matching. =head1 CONFIGURATION @@ -58,14 +58,11 @@ =cut -if [ -z $statsfile ]; then - _target=/var/snort/snort.stats -else - _target=$statsfile -fi +_target=${statsfile:-/var/snort/snort.stats} + if [ "$1" = "autoconf" ]; then - if [ -f $_target ]; then + if [ -f "$_target" ]; then echo yes else echo "no ($_target not readable)" @@ -79,12 +76,12 @@ echo 'graph_vlabel % percent' echo 'graph_scale no' echo 'pattmatch.label % percent' - if [ -n "$warning" ]; then - echo "pattmatch.warning $warning" - fi - if [ -n "$critical" ]; then - echo "pattmatch.critical $critical" - fi + if [ -n "${warning:-}" ]; then + echo "pattmatch.warning $warning" + fi + if [ -n "${critical:-}" ]; then + echo "pattmatch.critical $critical" + fi echo 'pattmatch.info The percent of data received that Snort processes in pattern matching' echo 'graph_category Snort' @@ -92,4 +89,4 @@ fi printf "pattmatch.value " -echo $(tail -n1 $_target| awk -F, '{ print $7 }') +tail -n1 "$_target" | awk -F, '{ print $7 }' diff -Nru munin-2.0.37/plugins/node.d/snort_pkts.in munin-2.0.47/plugins/node.d/snort_pkts.in --- munin-2.0.37/plugins/node.d/snort_pkts.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snort_pkts.in 2019-02-28 14:43:36.000000000 +0000 @@ -5,7 +5,7 @@ =head1 NAME -snort_pktsec - Plugin to monitor the number of packets per second +snort_pktsec - Plugin to monitor the number of packets per second passed through Snort filters =head1 CONFIGURATION @@ -57,15 +57,16 @@ =cut +statsfile=${statsfile:-} -if [ -z $statsfile ]; then +if [ -z "$statsfile" ]; then _target=/var/snort/snort.stats else _target=$statsfile fi if [ "$1" = "autoconf" ]; then - if [ -f $_target ]; then + if [ -f "$_target" ]; then echo yes else echo "no ($_target not readable)" @@ -76,15 +77,16 @@ if [ "$1" = "config" ]; then echo 'graph_title Snort Avg packets/s' echo 'graph_args --base 1000 -l 0' - echo 'graph_vlabel Packets / second' + # shellcheck disable=SC2016 + echo 'graph_vlabel Packets / ${graph_period}' echo 'graph_scale no' - echo 'pktsec.label Packets/second' - if [ -n "$warning" ]; then - echo "pktsec.warning $warning" - fi - if [ -n "$critical" ]; then - echo "pktsec.critical $critical" - fi + echo 'pktsec.label Packets' + if [ -n "${warning:-}" ]; then + echo "pktsec.warning $warning" + fi + if [ -n "${critical:-}" ]; then + echo "pktsec.critical $critical" + fi echo 'pktsec.info The number of packets per second' echo 'graph_category Snort' @@ -92,4 +94,4 @@ fi printf "pktsec.value " -echo $( tail -n1 $_target| awk -F, '{ print $5 }') \* 1000|bc -l +tail -n1 "$_target" | awk -F, '{ print $5 * 1000 }' diff -Nru munin-2.0.37/plugins/node.d/snort_traffic.in munin-2.0.47/plugins/node.d/snort_traffic.in --- munin-2.0.37/plugins/node.d/snort_traffic.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/snort_traffic.in 2019-02-28 14:43:36.000000000 +0000 @@ -57,14 +57,11 @@ =cut -if [ -z $statsfile ]; then - _target=/var/snort/snort.stats -else - _target=$statsfile -fi +_target=${statsfile:-/var/snort/snort.stats} + if [ "$1" = "autoconf" ]; then - if [ -f $_target ]; then + if [ -f "$_target" ]; then echo yes else echo "no ($_target not readable)" @@ -78,12 +75,12 @@ echo 'graph_vlabel Mbits / second' echo 'graph_scale no' echo 'traffic.label Mbits/second' - if [ -n "$warning" ]; then - echo "traffic.warning $warning" - fi - if [ -n "$critical" ]; then - echo "traffic.critical $critical" - fi + if [ -n "${warning:-}" ]; then + echo "traffic.warning $warning" + fi + if [ -n "${critical:-}" ]; then + echo "traffic.critical $critical" + fi echo 'traffic.info Traffic in Mbites per second' echo 'graph_category Snort' @@ -91,4 +88,4 @@ fi printf "traffic.value " -echo $(tail -n1 $_target| awk -F, '{ print $3 }') +tail -n1 "$_target" | awk -F, '{ print $3 }' diff -Nru munin-2.0.37/plugins/node.d/spamstats.in munin-2.0.47/plugins/node.d/spamstats.in --- munin-2.0.37/plugins/node.d/spamstats.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/spamstats.in 2019-02-28 14:43:36.000000000 +0000 @@ -128,25 +128,25 @@ print OUT "$pos:$ham:$spam\n"; close OUT; -sub parselogfile -{ +sub parselogfile +{ my ($fname, $start, $stop) = @_; open (LOGFILE, $fname) or exit 3; seek (LOGFILE, $start, 0) or exit 2; - while (tell (LOGFILE) < $stop) + while (tell (LOGFILE) < $stop) { my $line =; chomp ($line); - if ($line =~ m/clean message/) + if ($line =~ m/clean message/) { $ham++; - } + } elsif ($line =~ m/identified spam/) { $spam++; } } - close(LOGFILE); + close(LOGFILE); } diff -Nru munin-2.0.37/plugins/node.d/squeezebox_.in munin-2.0.47/plugins/node.d/squeezebox_.in --- munin-2.0.37/plugins/node.d/squeezebox_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/squeezebox_.in 2019-02-28 14:43:36.000000000 +0000 @@ -39,10 +39,6 @@ #%# family=auto #%# capabilities=autoconf suggest -=head1 VERSION - - $Id$ - =head1 BUGS None known @@ -62,18 +58,16 @@ NC=${netcat:-nc} if [ "$1" = "autoconf" ]; then - if [ ! "which $NC 1>/dev/null 2>&1" ]; then + if ! which "$NC" 1>/dev/null 2>&1; then echo "no (no netcat/nc binary found)" exit 0 fi - echo exit | $NC $HOST $PORT 1>/dev/null 2>&1 - RET=$? - if [ "$RET" != "0" ]; then + if ! echo exit | "$NC" "$HOST" "$PORT" 1>/dev/null 2>&1; then echo "no (no connection on $HOST port $PORT)" exit 0 fi - VERSION=$(printf "%b" "version ?\nexit\n" | $NC $HOST $PORT 2>/dev/null) - if [ "$VERSION" != "" ]; then + VERSION=$(printf "%b" "version ?\\nexit\\n" | "$NC" "$HOST" "$PORT" 2>/dev/null) + if [ -n "$VERSION" ]; then echo "yes" exit 0 else @@ -100,12 +94,12 @@ # example: 5 * * * * /usr/share/munin/plugins/squeezebox_ update if [ "$1" = "update" ]; then - printf "%b" "rescan\nexit\n" | $NC $HOST $PORT >/dev/null + printf "%b" "rescan\\nexit\\n" | "$NC" "$HOST" "$PORT" >/dev/null exit 0 fi -CHECK=$(echo $0 | cut -d _ -f 2-) +CHECK=$(echo "$0" | cut -d _ -f 2-) case "$CHECK" in songs) ATTR="songs" @@ -137,72 +131,77 @@ ;; esac -if [ "$ATTR" = "" -a "$CMD" = "" ]; then +if [ -z "$ATTR" ] && [ -z "$CMD" ]; then echo "Urk" exit 2 fi if [ "$CMD" = "years" ]; then - no_of_years=$(printf "%b" "years\nexit\n" | $NC $HOST $PORT | sed 's/%3A/:/g' | cut -d ':' -f 2) - years_array=$(printf "%b" "years 0 $no_of_years\nexit\n" | $NC $HOST $PORT | sed 's/%3A/:/g' | cut -d ' ' -f 4- | sed 's/year://g' | cut -d ' ' -f -$no_of_years) - arr1=( `echo "$years_array" | tr -s ' ' ' '` ) + no_of_years=$(printf "%b" "years\\nexit\\n" | "$NC" "$HOST" "$PORT" | sed 's/%3A/:/g' | cut -d ':' -f 2) + years_array=$(printf "%b" "years 0 $no_of_years\\nexit\\n" | "$NC" "$HOST" "$PORT" | sed 's/%3A/:/g' | cut -d ' ' -f 4- | sed 's/year://g' | cut -d ' ' -f "-$no_of_years") + # shellcheck disable=SC2207 + arr1=( $(echo "$years_array" | tr -s ' ' ' ') ) (( no_of_years-- )) # We don't need that last entry in the array if [ "$1" = "config" ]; then echo "graph_title Number of years" + echo "graph_vlabel years" echo "graph_category radio" echo "graph_args --base 1000 -l 0" # echo -n "graph_order " # echo $years_array | tr '[:space:]' " y" # echo "graph_order y0" printf "graph_order y" - echo $years_array | sed 's/ / y/g' + echo "${years_array// / y}" - for i in `seq 0 $no_of_years`; do - year=$(echo ${arr1[$i]}) - if [ $year = 0 ]; then - echo y0.label No year - else - echo y${year}.label $year - fi - if [ $i = 0 ]; then - echo y${year}.draw AREA - else - echo y${year}.draw STACK - fi - done - exit 0 - fi - for i in `seq 0 $no_of_years`; do - year=$(echo ${arr1[$i]}) - printf "y%s.value " ${year} - printf "%b" "albums 0 0 year:${year}\nexit\n" | $NC $HOST $PORT | sed 's/%3A/:/g' | cut -d ':' -f 3 - done -elif [ "$CMD" = "signalstrength" -o "$CMD" = "mixer volume" ]; then + for i in $(seq 0 "$no_of_years"); do + year=${arr1[$i]} + if [ "$year" = 0 ]; then + echo "y0.label No year" + else + echo "y${year}.label $year" + fi + if [ "$i" = 0 ]; then + echo "y${year}.draw AREA" + else + echo "y${year}.draw STACK" + fi + done + exit 0 + fi + for i in $(seq 0 "$no_of_years"); do + year=${arr1[$i]} + printf "y%s.value " "$year" + printf "%b" "albums 0 0 year:${year}\\nexit\\n" | "$NC" "$HOST" "$PORT" | sed 's/%3A/:/g' | cut -d ':' -f 3 + done +elif [ "$CMD" = "signalstrength" ] || [ "$CMD" = "mixer volume" ]; then if [ "$1" = "config" ]; then echo "graph_title $TITLE" + echo "graph_vlabel $CMD" echo "graph_category radio" - COUNT=$(printf "%b" "player count ?\nexit\n" | $NC $HOST $PORT | cut -d " " -f 3) + COUNT=$(printf "%b" 'player count ?\nexit\n' | "$NC" "$HOST" "$PORT" | cut -d " " -f 3) (( COUNT-- )) - for ID in $(seq 0 $COUNT); do - MAC=$(printf "%b" "player id $ID ?\nexit\n" | $NC $HOST $PORT | cut -d " " -f 4 | sed 's/%3A/:/g') - NAME=$(printf "%b" "player name $MAC ?\nexit\n" | $NC $HOST $PORT | cut -d " " -f 4 | sed 's/%20/ /g') - MAC2=$(echo $MAC | sed 's/://g; s/\./_/g') - echo "$MAC2.label $NAME" + for ID in $(seq 0 "$COUNT"); do + MAC=$(printf "%b" "player id $ID ?\\nexit\\n" | "$NC" "$HOST" "$PORT" | cut -d " " -f 4 | sed 's/%3A/:/g') + NAME=$(printf "%b" "player name $MAC ?\\nexit\\n" | "$NC" "$HOST" "$PORT" | cut -d " " -f 4 | sed 's/%20/ /g') + MAC2=${MAC//:/} + MAC2=${MAC2//./_} + echo "$MAC2.label $NAME" done exit 0 fi - COUNT=$(printf "%b" "player count ?\nexit\n" | $NC $HOST $PORT | cut -d " " -f 3) + COUNT=$(printf "%b" 'player count ?\nexit\n' | "$NC" "$HOST" "$PORT" | cut -d " " -f 3) (( COUNT-- )) - for ID in $(seq 0 $COUNT); do - MAC=$(printf "%b" "player id $ID ?\nexit\n" | $NC $HOST $PORT | cut -d " " -f 4 | sed 's/%3A/:/g') - VAL=$(printf "%b" "$MAC $CMD ?\nexit\n"| $NC $HOST $PORT | cut -d " " -f 2- | sed "s/$CMD //") - MAC2=$(echo $MAC| sed 's/://g') - [ $VAL -eq 0 ] && VAL=100 + for ID in $(seq 0 "$COUNT"); do + MAC=$(printf "%b" "player id $ID ?\\nexit\\n" | "$NC" "$HOST" "$PORT" | cut -d " " -f 4 | sed 's/%3A/:/g') + VAL=$(printf "%b" "$MAC $CMD ?\\nexit\\n"| "$NC" "$HOST" "$PORT" | cut -d " " -f 2- | sed "s/$CMD //") + MAC2=${MAC//:/} + [ "$VAL" -eq 0 ] && VAL=100 echo "$MAC2.value $VAL" done else if [ "$1" = "config" ]; then echo "graph_title Number of $ATTR" + echo "graph_vlabel $ATTR" echo "graph_scale no" echo "graph_category radio" echo "$ATTR.label $ATTR" @@ -210,5 +209,5 @@ fi CMD="info total $ATTR " echo -n "$ATTR.value " - printf "%b" "$CMD ?\nexit\n" | $NC $HOST $PORT | sed "s/^$CMD//" + printf "%b" "$CMD ?\\nexit\\n" | "$NC" "$HOST" "$PORT" | sed "s/^$CMD//" fi diff -Nru munin-2.0.37/plugins/node.d/squid_cache.in munin-2.0.47/plugins/node.d/squid_cache.in --- munin-2.0.37/plugins/node.d/squid_cache.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/squid_cache.in 2019-02-28 14:43:36.000000000 +0000 @@ -92,7 +92,7 @@ "Accept: */*\r\n" . &make_auth_header($user, $passwd) . "\r\n"; - + $cachemgr->syswrite($request, length($request)); my @lines = $cachemgr->getlines(); @@ -120,13 +120,13 @@ PeerPort => $port, Proto => 'tcp') or die($!); - + my $request = "GET cache_object://$host/storedir HTTP/1.0\r\n" . "Accept: */*\r\n" . &make_auth_header($user, $passwd) . "\r\n"; - + $cachemgr->syswrite($request, length($request)); my @lines = $cachemgr->getlines(); my %outs = ('Maximum' => 0, 'Current' => 0); diff -Nru munin-2.0.37/plugins/node.d/squid_icp.in munin-2.0.47/plugins/node.d/squid_icp.in --- munin-2.0.37/plugins/node.d/squid_icp.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/squid_icp.in 2019-02-28 14:43:36.000000000 +0000 @@ -101,7 +101,7 @@ "Accept: */*\r\n" . &make_auth_header($user, $passwd) . "\r\n"; - + $cachemgr->syswrite($request, length($request)); my @lines = $cachemgr->getlines(); @@ -130,13 +130,13 @@ PeerPort => $port, Proto => 'tcp') or die($!); - + my $request = "GET cache_object://$host/server_list HTTP/1.0\r\n" . "Accept: */*\r\n" . &make_auth_header($user, $passwd) . "\r\n"; - + $cachemgr->syswrite($request, length($request)); my @lines = $cachemgr->getlines(); my $id = ""; diff -Nru munin-2.0.37/plugins/node.d/squid_objectsize.in munin-2.0.47/plugins/node.d/squid_objectsize.in --- munin-2.0.37/plugins/node.d/squid_objectsize.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/squid_objectsize.in 2019-02-28 14:43:36.000000000 +0000 @@ -73,27 +73,27 @@ my $cachemgr = IO::Socket::INET->new (PeerAddr => $host, PeerPort => $port, Proto => 'tcp'); - + if (!$cachemgr) { print "no (could not connect: $!)\n"; exit 0; } - + my $request = "GET cache_object://$host/info HTTP/1.0\r\n" . "Accept: */*\r\n" . &make_auth_header ($user, $passwd) . "\r\n"; - + $cachemgr->syswrite ($request, length($request)); my @lines = $cachemgr->getlines(); - + print "yes\n"; exit 0; } sub make_auth_header { my ($user, $passwd) = @_; - + if (!defined $passwd || $passwd eq "") { return ""; } else { @@ -108,12 +108,12 @@ my $cachemgr = IO::Socket::INET->new (PeerAddr => $host, PeerPort => $port, Proto => 'tcp') or die($!); - + my $request = "GET cache_object://$host/info HTTP/1.0\r\n" . "Accept: */*\r\n" . &make_auth_header ($user, $passwd) . "\r\n"; - + $cachemgr->syswrite ($request, length($request)); my @lines = grep (/Mean Object Size/, $cachemgr->getlines()); my $line = pop @lines; diff -Nru munin-2.0.37/plugins/node.d/squid_requests.in munin-2.0.47/plugins/node.d/squid_requests.in --- munin-2.0.37/plugins/node.d/squid_requests.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/squid_requests.in 2019-02-28 14:43:36.000000000 +0000 @@ -86,7 +86,7 @@ "Accept: */*\r\n" . &make_auth_header($user, $passwd) . "\r\n"; - + $cachemgr->syswrite($request, length($request)); my @lines = $cachemgr->getlines(); @@ -114,13 +114,13 @@ PeerPort => $port, Proto => 'tcp') or die($!); - + my $request = "GET cache_object://$host/counters HTTP/1.0\r\n" . "Accept: */*\r\n" . &make_auth_header($user, $passwd) . "\r\n"; - + $cachemgr->syswrite($request, length($request)); my @lines = $cachemgr->getlines(); for(my $i = 0; $i <= $#lines; $i++) { diff -Nru munin-2.0.37/plugins/node.d/squid_traffic.in munin-2.0.47/plugins/node.d/squid_traffic.in --- munin-2.0.37/plugins/node.d/squid_traffic.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/squid_traffic.in 2019-02-28 14:43:36.000000000 +0000 @@ -87,7 +87,7 @@ "Accept: */*\r\n" . &make_auth_header($user, $passwd) . "\r\n"; - + $cachemgr->syswrite($request, length($request)); my @lines = $cachemgr->getlines(); @@ -116,17 +116,17 @@ PeerPort => $port, Proto => 'tcp') or die($!); - + my $request = "GET cache_object://$host/counters HTTP/1.0\r\n" . "Accept: */*\r\n" . &make_auth_header($user, $passwd) . "\r\n"; - + $cachemgr->syswrite($request, length($request)); my @lines = $cachemgr->getlines(); for(my $i = 0; $i <= $#lines; $i++) { - if($lines[$i] =~ /$target\s+(\d+)/) { + if($lines[$i] =~ /$target\s+(-?\d+)/) { print "$1.value $2\n"; } } @@ -148,10 +148,10 @@ print "kbytes_out.type DERIVE\n"; print "kbytes_out.min 0\n"; print "kbytes_out.max 500000\n"; - print "hit_kbytes_out.label from cache\n"; + print "hit_kbytes_out.label from cache\n"; print "hit_kbytes_out.cdef hit_kbytes_out,8096,*\n"; - print "hit_kbytes_out.type DERIVE\n"; - print "hit_kbytes_out.min 0\n"; + print "hit_kbytes_out.type DERIVE\n"; + print "hit_kbytes_out.min 0\n"; print "hit_kbytes_out.max 500000\n"; exit 0; } diff -Nru munin-2.0.37/plugins/node.d/sybase_space.in munin-2.0.47/plugins/node.d/sybase_space.in --- munin-2.0.37/plugins/node.d/sybase_space.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/sybase_space.in 2019-02-28 14:43:36.000000000 +0000 @@ -67,7 +67,7 @@ exit 0; } -if (!$dbh) +if (!$dbh) { die "Could not run DBI::connect\n"; } diff -Nru munin-2.0.37/plugins/node.d/tomcat_.in munin-2.0.47/plugins/node.d/tomcat_.in --- munin-2.0.37/plugins/node.d/tomcat_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/tomcat_.in 2019-02-28 14:43:36.000000000 +0000 @@ -11,7 +11,7 @@ =head1 USAGE -Needs access to http://:@localhost:8080/manager/status?XML=true (or modify the address for another host). +Needs access to http://:@localhost:8080/manager/status?XML=true (or modify the address for another host). A munin-user in $CATALINA_HOME/conf/tomcat-users.xml should be set up for this to work. @@ -45,11 +45,11 @@ =item user -Manager username +Manager username =item password -Manager password +Manager password =item connector @@ -131,8 +131,8 @@ puts "yes" return 0 else - puts "no" - return 1 + puts "no (could not connect to #{@host}#{@request} on port #{@port})" + return 0 end rescue puts "no (#{$!})" diff -Nru munin-2.0.37/plugins/node.d/tomcat_jvm.in munin-2.0.47/plugins/node.d/tomcat_jvm.in --- munin-2.0.37/plugins/node.d/tomcat_jvm.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/tomcat_jvm.in 2019-02-28 14:43:36.000000000 +0000 @@ -36,7 +36,7 @@ =head1 USAGE -Needs access to http://:@localhost:8080/manager/status?XML=true (or modify the address for another host). +Needs access to http://:@localhost:8080/manager/status?XML=true (or modify the address for another host). Tomcat 5.0 or higher. @@ -122,13 +122,13 @@ my $response = $ua->request(HTTP::Request->new('GET',$url)); my $xml = $xs->XMLin($response->content); -if($xml->{'jvm'}->{'memory'}->{'free'} && +if($xml->{'jvm'}->{'memory'}->{'free'} && $xml->{'jvm'}->{'memory'}->{'total'} && $xml->{'jvm'}->{'memory'}->{'max'}) { print "free.value " . $xml->{'jvm'}->{'memory'}->{'free'} . "\n"; - print "used.value " . - ($xml->{'jvm'}->{'memory'}->{'total'} - - $xml->{'jvm'}->{'memory'}->{'free'}) . "\n"; + print "used.value " . + ($xml->{'jvm'}->{'memory'}->{'total'} - + $xml->{'jvm'}->{'memory'}->{'free'}) . "\n"; print "max.value " . $xml->{'jvm'}->{'memory'}->{'max'} . "\n"; } else { print "free.value U\n"; diff -Nru munin-2.0.37/plugins/node.d/users.in munin-2.0.47/plugins/node.d/users.in --- munin-2.0.37/plugins/node.d/users.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/users.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,9 @@ #!@@PERL@@ -w # -*- perl -*- +use strict; +use warnings; + =head1 NAME users - Munin plugin to monitor the number of users logged in to a Unix box. @@ -86,11 +89,11 @@ } } -$tty = 0; -$pty = 0; -$pts = 0; -$X = 0; -$unc = 0; # Unclassified +my $tty = 0; +my $pty = 0; +my $pts = 0; +my $X = 0; +my $unc = 0; # Unclassified open (WHO,"who |"); diff -Nru munin-2.0.37/plugins/node.d/varnish_.in munin-2.0.47/plugins/node.d/varnish_.in --- munin-2.0.37/plugins/node.d/varnish_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/varnish_.in 2019-02-28 14:43:36.000000000 +0000 @@ -880,12 +880,14 @@ # Note that 'flag' is translated to RRD-equivalents here. sub xml_commit_state { + my $type; + my $name; if ($state{'values'}{'name'} =~ /\./) { # since Varnish 5.2 the 'name' field includes a 'type' prefix ("type.name") - (my $type, my $name) = split(/\./, $state{'values'}{'name'}, 2); + ($type, $name) = split(/\./, $state{'values'}{'name'}, 2); } else { - my $name = $state{'values'}{'name'}; - my $type = $state{'values'}{'type'}; + $name = $state{'values'}{'name'}; + $type = $state{'values'}{'type'}; } my $ident = $state{'values'}{'ident'}; @@ -934,7 +936,7 @@ my $parser = new XML::Parser(Handlers => {Start => \&xml_start_elem, End => \&xml_end_elem, Char => \&xml_characters} ); - + if ($varnishname) { $arg .= " -n $varnishname"; } @@ -974,7 +976,7 @@ } my $counter = $ASPECTS{$self}{'values'}{$name}{'counter'}; my $type = $ASPECTS{$self}{'values'}{$name}{'family'}; - + foreach my $key (keys %{$data{$type}}) { my $pname = normalize_name($type . "_" . $key . "_" . $counter); print $pname . $suffix . " "; @@ -1062,7 +1064,7 @@ } next; } - + if (!print_if_exist(\%values,$value,'label')) { print "$value.label $data{$value}{'description'}\n"; } @@ -1100,9 +1102,9 @@ # Execution starts here # ################################ -set_aspect; -check_args; -populate_stats; +set_aspect(); +check_args(); +populate_stats(); # We only get here if we're supposed to. # Walks through the relevant values and either prints the varnishstat, or diff -Nru munin-2.0.37/plugins/node.d/vmstat.in munin-2.0.47/plugins/node.d/vmstat.in --- munin-2.0.37/plugins/node.d/vmstat.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/vmstat.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,8 @@ #!@@GOODSH@@ # -*- sh -*- +set -e + : << =cut =head1 NAME @@ -31,7 +33,7 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" if [ "$1" = "autoconf" ]; then if ( vmstat 1 1 >/dev/null 2>&1 ); then @@ -42,7 +44,7 @@ echo "no (could not run \"vmstat\")" exit 0 else - echo no + echo "no (unknown vmstat return value $?)" exit 0 fi fi diff -Nru munin-2.0.37/plugins/node.d/zimbra_.in munin-2.0.47/plugins/node.d/zimbra_.in --- munin-2.0.37/plugins/node.d/zimbra_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d/zimbra_.in 2019-02-28 14:43:36.000000000 +0000 @@ -68,7 +68,7 @@ Public License as published by the Free Software Foundation; version 2 dated June, 1991. -=head1 VERSION +=head1 VERSION $Id$ @@ -892,7 +892,7 @@ my @csvfields = $csv->fields(); my $csvindex = 0; $csvindex++ until $csvindex > $#csvfields or $csvfields[$csvindex] eq $field->{'csvfield'}; if ($csvindex > $#csvfields) { $error = 1; goto FIELDERR; } - + my $csvindex2; if (exists $field->{'csvfield2'}) { diff -Nru munin-2.0.37/plugins/node.d.aix/cpu.in munin-2.0.47/plugins/node.d.aix/cpu.in --- munin-2.0.37/plugins/node.d.aix/cpu.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.aix/cpu.in 2019-02-28 14:43:36.000000000 +0000 @@ -56,7 +56,7 @@ } } - + if($arg eq 'config') { my($percent) = 100; @@ -102,8 +102,7 @@ my($sysTime) = ceil($sys); my($idleTime) = ceil($idle); my($iowaitTime) = ceil($iowait); - - + print "user.value $userTime\nsystem.value $sysTime\nidle.value $idleTime\niowait.value $iowaitTime\n"; } @@ -145,4 +144,3 @@ my($iowait)= $items[6]; return ($user,$sys,$idle,$iowait); } - diff -Nru munin-2.0.37/plugins/node.d.aix/df.in munin-2.0.47/plugins/node.d.aix/df.in --- munin-2.0.37/plugins/node.d.aix/df.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.aix/df.in 2019-02-28 14:43:36.000000000 +0000 @@ -63,10 +63,10 @@ echo 'graph_category disk' echo 'graph_scale no' df -P -k | sed 1d | grep -v "//" | grep -v "nfs" | while read i; do - name=`echo $i | sed 's/[\/.-]/_/g'| awk '{ print $6 }'` + name=`echo "$i" | sed 's/[\/.-]/_/g'| awk '{ print $6 }'` devName="$name.label " - fsLabel=`echo $i | awk '{ print $6 }'` - echo $devName$fsLabel + fsLabel=`echo "$i" | awk '{ print $6 }'` + echo "$devName$fsLabel" echo "$name.warning ${warning:-92}" echo "$name.critical ${critical:-98}" done @@ -74,7 +74,7 @@ fi df -P -k | sed 1d | grep -v "//" | grep -v "nfs" | while read i; do - name=`echo $i | sed 's/[\/.-]/_/g'| awk '{ print $6 ".value " }'` - name2=`echo $i | awk '{ print $5 }' | cut -f1 -d%` - echo $name $name2 + name=`echo "$i" | sed 's/[\/.-]/_/g'| awk '{ print $6 ".value " }'` + name2=`echo "$i" | awk '{ print $5 }' | cut -f1 -d%` + echo "$name $name2" done diff -Nru munin-2.0.37/plugins/node.d.aix/iostat.hd_only.in munin-2.0.47/plugins/node.d.aix/iostat.hd_only.in --- munin-2.0.37/plugins/node.d.aix/iostat.hd_only.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.aix/iostat.hd_only.in 2019-02-28 14:43:36.000000000 +0000 @@ -56,7 +56,7 @@ exit 0; } } - + if($arg && $arg eq "config") { print "graph_title IOstat (Internal Disks Only)\n"; @@ -72,13 +72,13 @@ } exit 0; } - + my(@info) = getDiskIO(''); my($line); foreach $line (@info) {print "$line";} - - + + sub getDiskIO { my($diskOnly) = @_; @@ -104,7 +104,7 @@ chomp($writes); $reads = $lineArray[4]; chomp($reads); - + push(@diskArray,"$lineArray[0]_read.value $reads\n","$lineArray[0]_write.value $writes\n"); } } diff -Nru munin-2.0.37/plugins/node.d.aix/iostat.in munin-2.0.47/plugins/node.d.aix/iostat.in --- munin-2.0.37/plugins/node.d.aix/iostat.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.aix/iostat.in 2019-02-28 14:43:36.000000000 +0000 @@ -63,7 +63,7 @@ exit 0; } } - + if($arg && $arg eq "config") { print "graph_title IOstat\n"; @@ -80,7 +80,7 @@ } exit 0; } - + my(@info) = getDiskIO(''); my($line); foreach $line (@info) @@ -88,8 +88,8 @@ @info = processVPaths(); foreach $line (@info) {print "$line";} - - + + sub getDiskIO { my($diskOnly) = @_; @@ -115,7 +115,7 @@ chomp($writes); $reads = $lineArray[4]; chomp($reads); - + push(@diskArray,"$lineArray[0]_read.value $reads\n","$lineArray[0]_write.value $writes\n"); } } @@ -161,4 +161,4 @@ {print $labels[$count].substr($spacer,0,length($spacer)-length($labels[$count])).$item."\n";} $count++; } -} +} diff -Nru munin-2.0.37/plugins/node.d.aix/iostat.vp_only.in munin-2.0.47/plugins/node.d.aix/iostat.vp_only.in --- munin-2.0.37/plugins/node.d.aix/iostat.vp_only.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.aix/iostat.vp_only.in 2019-02-28 14:43:36.000000000 +0000 @@ -53,7 +53,7 @@ exit 0; } } - + if($arg && $arg eq "config") { print "graph_title IOstat (VPaths Only)\n"; @@ -69,13 +69,13 @@ } exit 0; } - + my($line); my @info = processVPaths(); foreach $line (@info) {print "$line";} - - + + sub getDiskIO { my($diskOnly) = @_; @@ -131,4 +131,4 @@ {print $labels[$count].substr($spacer,0,length($spacer)-length($labels[$count])).$item."\n";} $count++; } -} +} diff -Nru munin-2.0.37/plugins/node.d.aix/memory.in munin-2.0.47/plugins/node.d.aix/memory.in --- munin-2.0.37/plugins/node.d.aix/memory.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.aix/memory.in 2019-02-28 14:43:36.000000000 +0000 @@ -61,7 +61,7 @@ exit 0; } } - + if($arg eq "config") { print "graph_args --base 1024 -l 0 --vertical-label Bytes --upper-limit ".getTotalMemBytes()."\n"; @@ -83,7 +83,7 @@ my($inUse,$free,$pinned) = findMemoryUsage(); print "swap.value $swapUsed\ninuse.value $inUse\nfree.value $free\npinned.value $pinned\n"; - + sub getTotalMemBytes { my($line,@memInfo,$item,$totalMem); diff -Nru munin-2.0.37/plugins/node.d.aix/netstat.in munin-2.0.47/plugins/node.d.aix/netstat.in --- munin-2.0.37/plugins/node.d.aix/netstat.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.aix/netstat.in 2019-02-28 14:43:36.000000000 +0000 @@ -16,7 +16,7 @@ This will measure the amount of network traffic coming into and out of the server. It will report back the number of connections accepted, requested, established, and closed. It uses -/usr/bin/netstat to gather it's information. +/usr/bin/netstat to gather its information. =head2 RESTRICTIONS @@ -39,22 +39,14 @@ use strict; -if($ARGV[0] && $ARGV[0] eq "autoconf") - { - if(-e "/usr/bin/netstat" && -X "/usr/bin/netstat") - { +if (defined $ARGV[0] and $ARGV[0] eq "autoconf") { + if(-e "/usr/bin/netstat" && -X "/usr/bin/netstat") { print "yes\n"; - exit 0; - } - else - { + } else { print "no\n"; - exit 0; - } - } - -if($ARGV[0] && $ARGV[0] eq "config") - { + } + exit 0; +} elsif (defined $ARGV[0] and $ARGV[0] eq "config") { print "graph_title Netstat\n"; print "graph_args --base 1000 --logarithmic\n"; print "graph_vlabel requests connections per \${graph_period}\n"; @@ -72,14 +64,14 @@ print "closed.type COUNTER\n"; print "closed.max 50000\n"; exit 0; - } - +} + my(%toFind) = ("requests" => "connection requests", "accepts" => "connection accepts", "established" => "connections established", "closed" => "connections closed (" ); - + my($item,$line,@lineArray); foreach $item (keys(%toFind)) { diff -Nru munin-2.0.37/plugins/node.d.aix/processes.in munin-2.0.47/plugins/node.d.aix/processes.in --- munin-2.0.37/plugins/node.d.aix/processes.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.aix/processes.in 2019-02-28 14:43:36.000000000 +0000 @@ -62,7 +62,7 @@ } } -my($item); +my($item); if($ARGV[0] && $ARGV[0] eq "config") { print "graph_title Number of Processes\n"; @@ -71,23 +71,23 @@ print "graph_category processes\n"; print "global.label global\n"; print "global.draw LINE2\n"; - + foreach $item (@lookFor) { print "$item.label $item\n"; print "$item.draw LINE2\n"; } } - -my($procNum); + +my($procNum); foreach $item (@lookFor) { $procNum = `/usr/bin/ps -ef|grep $item|grep -v grep |wc -l`; chomp($procNum); - + print "$item.value $procNum\n"; } - + $procNum = `/usr/bin/ps -ef|grep -v grep|wc -l`; chomp($procNum); print "global.value $procNum\n"; diff -Nru munin-2.0.37/plugins/node.d.aix/swap.in munin-2.0.47/plugins/node.d.aix/swap.in --- munin-2.0.37/plugins/node.d.aix/swap.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.aix/swap.in 2019-02-28 14:43:36.000000000 +0000 @@ -65,7 +65,7 @@ my(@swapInfo) = getSwapSpace(); print "total.value $swapInfo[0]\n"; print "used.value $swapInfo[1]\n"; - + sub getSwapSpace { my($line,@lineArray,$amountUsed,$totalSpace); diff -Nru munin-2.0.37/plugins/node.d.cygwin/df.in munin-2.0.47/plugins/node.d.cygwin/df.in --- munin-2.0.37/plugins/node.d.cygwin/df.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.cygwin/df.in 2019-02-28 14:43:36.000000000 +0000 @@ -46,12 +46,12 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" print_values () { df -P -x iso9660 2>/dev/null | sed -e 1d -e '/\/\//d' -e 's/%//' | - while read dev size used free pct fs; do - echo "$(clean_fieldname $dev).value $pct" + while read -r dev size used free pct fs; do + echo "$(clean_fieldname "$dev").value $pct" done } @@ -71,12 +71,13 @@ echo 'graph_vlabel %' echo 'graph_scale no' echo 'graph_category disk' - df -P -x iso9660 | sed -e 1d -e '/\/\//d' -e 's/%//' | sort | - while read dev size used free pct fs; do - name=$(clean_fieldname $dev) - echo "$name.label $fs" - print_warning $name - print_critical $name + # shellcheck disable=SC2034 + df -P -x iso9660 | sed -e 1d -e '/\/\//d' -e 's/%//' | sort \ + | while read -r dev size used free pct fs; do + name=$(clean_fieldname "$dev") + echo "$name.label $fs" + print_warning "$name" + print_critical "$name" done exit 0 fi diff -Nru munin-2.0.37/plugins/node.d.cygwin/netstat.in munin-2.0.47/plugins/node.d.cygwin/netstat.in --- munin-2.0.37/plugins/node.d.cygwin/netstat.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.cygwin/netstat.in 2019-02-28 14:43:36.000000000 +0000 @@ -32,16 +32,20 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" + + +NETSTAT_CMD=netstat + if [ "$1" = "autoconf" ]; then - if ( netstat -s 2>/dev/null >/dev/null ); then + if ( "$NETSTAT_CMD" -s 2>/dev/null >/dev/null ); then echo yes exit 0 else if [ $? -eq 127 ] then - echo "no (netstat program not found)" + echo "no (program $NETSTAT_CMD not found)" exit 0 else echo no @@ -54,35 +58,35 @@ echo 'graph_title Netstat' echo 'graph_args --base 1000 --logarithmic' - echo 'graph_vlabel active connections' + echo 'graph_vlabel TCP connections' echo 'graph_category network' echo 'graph_period second' echo 'graph_info This graph shows the TCP activity of all the network interfaces combined.' echo 'active.label active' echo 'active.type DERIVE' - echo 'active.max 50000' echo 'active.min 0' + echo 'active.max 50000' echo 'active.info The number of active TCP openings per second.' print_warning active print_critical active echo 'passive.label passive' echo 'passive.type DERIVE' - echo 'passive.max 50000' echo 'passive.min 0' + echo 'passive.max 50000' echo 'passive.info The number of passive TCP openings per second.' print_warning passive print_critical passive echo 'failed.label failed' echo 'failed.type DERIVE' - echo 'failed.max 50000' echo 'failed.min 0' + echo 'failed.max 50000' echo 'failed.info The number of failed TCP connection attempts per second.' print_warning failed print_critical failed echo 'resets.label resets' echo 'resets.type DERIVE' - echo 'resets.max 50000' echo 'resets.min 0' + echo 'resets.max 50000' echo 'resets.info The number of TCP connection resets.' print_warning resets print_critical resets @@ -95,7 +99,7 @@ exit 0 fi -netstat -s | awk ' +"$NETSTAT_CMD" -s | awk ' /Active Opens/ { print "active.value " $4 } /Passive Opens/ { print "passive.value " $4 } /Failed Connection Attempts/ { print "failed.value " $5 } diff -Nru munin-2.0.37/plugins/node.d.darwin/df_inode.in munin-2.0.47/plugins/node.d.darwin/df_inode.in --- munin-2.0.37/plugins/node.d.darwin/df_inode.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.darwin/df_inode.in 2019-02-28 14:43:36.000000000 +0000 @@ -20,10 +20,10 @@ /bin/df -P -i -t noprocfs,devfs,fdesc,linprocfs,nfs,nullfs,autofs | tail +2 | grep -v "//" | while read i; do case $i in mfs:*) name=mfs$mfs; mfs=`expr $mfs + 1`;; - *) name=`echo $i | awk '{ gsub("[^a-zA-Z0-9_]", "_", $1); print $1 }'` ;; + *) name=`echo "$i" | awk '{ gsub("[^a-zA-Z0-9_]", "_", $1); print $1 }'` ;; esac - printf "$name.value " - echo $i | awk '{ print $8 }' | cut -f1 -d% + printf "%s.value " "$name" + echo "$i" | awk '{ print $8 }' | cut -f1 -d% done } diff -Nru munin-2.0.37/plugins/node.d.darwin/if_err_.in munin-2.0.47/plugins/node.d.darwin/if_err_.in --- munin-2.0.37/plugins/node.d.darwin/if_err_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.darwin/if_err_.in 2019-02-28 14:43:36.000000000 +0000 @@ -62,6 +62,7 @@ echo "graph_order down up collisions" echo "graph_title $INTERFACE errors and collisions" echo 'graph_args --base 1000' + # shellcheck disable=SC2016 echo 'graph_vlabel packets in (-) / out (+) per ${graph_period}' echo 'graph_category network' echo "graph_info This graph shows the amount of errors and collisions on the $INTERFACE network interface." diff -Nru munin-2.0.37/plugins/node.d.darwin/if_.in munin-2.0.47/plugins/node.d.darwin/if_.in --- munin-2.0.37/plugins/node.d.darwin/if_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.darwin/if_.in 2019-02-28 14:43:36.000000000 +0000 @@ -62,6 +62,7 @@ echo "graph_order down up" echo "graph_title $INTERFACE traffic" echo 'graph_args --base 1000' + # shellcheck disable=SC2016 echo 'graph_vlabel bits in (-) / out (+) per ${graph_period}' echo 'graph_category network' echo "graph_info This graph shows the traffic of the $INTERFACE network interface. Please note that the traffic is shown in bits per second, not bytes. IMPORTANT: Since the data source for this plugin use 32bit counters, this plugin is really unreliable and unsuitable for most 100Mb (or faster) interfaces, where bursts are expected to exceed 50Mbps. This means that this plugin is unsuitable for most production environments." diff -Nru munin-2.0.37/plugins/node.d.darwin/load.in munin-2.0.47/plugins/node.d.darwin/load.in --- munin-2.0.37/plugins/node.d.darwin/load.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.darwin/load.in 2019-02-28 14:43:36.000000000 +0000 @@ -49,8 +49,8 @@ fi # If run with the "config"-parameter, give out information on how the -# graphs should look. - +# graphs should look. + if [ "$1" = "config" ]; then LOAD_WARN=${load_warn:-10} LOAD_CRIT=${load_crit:-120} @@ -71,7 +71,7 @@ # Graph category. Defaults to 'other' echo 'graph_category system' # The fields. "label" is used in the legend. "label" is the only - # required subfield. + # required subfield. echo 'load.label load' # These two are optional. They are only used if you have # configured your munin to tell a Nagios-server about any diff -Nru munin-2.0.37/plugins/node.d.debug/colour_tester.in munin-2.0.47/plugins/node.d.debug/colour_tester.in --- munin-2.0.37/plugins/node.d.debug/colour_tester.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.debug/colour_tester.in 2019-02-28 14:43:36.000000000 +0000 @@ -25,13 +25,13 @@ I=1 for C in $COLOURS; do col[$I]="$C" - I=$(($I + 1)) + I=$((I + 1)) done -NUMCOL=$(($I - 1)) +NUMCOL=$((I - 1)) do_ () { # Fetch - for I in $(seq 1 $NUMCOL); do + for I in $(seq 1 "$NUMCOL"); do echo "l$I.value $I" done } @@ -39,14 +39,14 @@ do_config () { echo "graph_title Colour testing plugin" echo "graph_vlabel Colour index and colour" - for I in $(seq 1 $NUMCOL); do - echo "l$I.label "${col[$I]} - echo "l$I.colour "${col[$I]} + for I in $(seq 1 "$NUMCOL"); do + echo "l$I.label ${col[$I]}" + echo "l$I.colour ${col[$I]}" echo "l$I.type GAUGE" done } case $1 in - ''|config) eval do_$1;; + ''|config) eval "do_$1";; *) echo Error >&2; exit 1;; esac diff -Nru munin-2.0.37/plugins/node.d.debug/extinfo_tester.in munin-2.0.47/plugins/node.d.debug/extinfo_tester.in --- munin-2.0.37/plugins/node.d.debug/extinfo_tester.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.debug/extinfo_tester.in 2019-02-28 14:43:36.000000000 +0000 @@ -20,4 +20,4 @@ EOF } -do_$1 +"do_$1" diff -Nru munin-2.0.37/plugins/node.d.debug/if.in munin-2.0.47/plugins/node.d.debug/if.in --- munin-2.0.37/plugins/node.d.debug/if.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.debug/if.in 2019-02-28 14:43:36.000000000 +0000 @@ -67,7 +67,7 @@ # Collect data -# +# open(FH, $PROCNETDEV) or die "Failed to open $PROCNETDEV: $!"; diff -Nru munin-2.0.37/plugins/node.d.debug/multigraph_complex munin-2.0.47/plugins/node.d.debug/multigraph_complex --- munin-2.0.37/plugins/node.d.debug/multigraph_complex 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.debug/multigraph_complex 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#! /bin/sh +#!@@GOODSH@@ # Plugin to test complex multigraph thingies # This plugin, ideally, creates a multigraph tree that is 3 levels deep. The diff -Nru munin-2.0.37/plugins/node.d.debug/multigraph_tester.in munin-2.0.47/plugins/node.d.debug/multigraph_tester.in --- munin-2.0.37/plugins/node.d.debug/multigraph_tester.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.debug/multigraph_tester.in 2019-02-28 14:43:36.000000000 +0000 @@ -3,7 +3,7 @@ #%# family=test #%# capabilities=autoconf -. $MUNIN_LIBDIR/plugins/plugin.sh || exit 1 +. "$MUNIN_LIBDIR/plugins/plugin.sh" || exit 1 # Handle the case where the munin node does not understand multigraph. is_multigraph "$@" @@ -78,7 +78,7 @@ # Main is here -do_$1 2>/dev/null || { +"do_$1" 2>/dev/null || { echo "Do what now?" >&2 exit 1 } diff -Nru munin-2.0.37/plugins/node.d.debug/negative_tester munin-2.0.47/plugins/node.d.debug/negative_tester --- munin-2.0.37/plugins/node.d.debug/negative_tester 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.debug/negative_tester 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/bash +#!@@BASH@@ # A small plugin for testing .negative. Currently exposes issues with # .negative and field names longer than 15 characters. This also fails if a diff -Nru munin-2.0.37/plugins/node.d.debug/sincos munin-2.0.47/plugins/node.d.debug/sincos --- munin-2.0.37/plugins/node.d.debug/sincos 1970-01-01 00:00:00.000000000 +0000 +++ munin-2.0.47/plugins/node.d.debug/sincos 2019-02-28 14:43:36.000000000 +0000 @@ -0,0 +1,26 @@ +#! /usr/bin/perl +# Sample plugin that draw a sine & a cos +# - used for spooling debugging + +if ($ARGV[0] eq "config") { + print "graph_title Trigo plugin\n"; + print "graph_vlabel unit\n"; + print "graph_category debug\n"; + print "update_rate 1\n"; + print "graph_data_size custom 1t, 10s for 1y\n"; + print "sin.label Sine\n"; + print "cos.label Cosine\n"; + + exit 0; +} + + +my $epoch = time; + +for (my $i = $epoch - 5; $i < $epoch; $i += 1) { + print "sin.value $i:". sin($i / 3600). "\n"; +} + +for (my $i = $epoch - 5; $i < $epoch; $i += 1) { + print "cos.value $i:". cos($i / 3600). "\n"; +} diff -Nru munin-2.0.37/plugins/node.d.debug/sum_cdef_tester.in munin-2.0.47/plugins/node.d.debug/sum_cdef_tester.in --- munin-2.0.37/plugins/node.d.debug/sum_cdef_tester.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.debug/sum_cdef_tester.in 2019-02-28 14:43:36.000000000 +0000 @@ -57,11 +57,11 @@ donald_disk \ ferdinand_disk=mg_ferdinand_disk.sda \ donald_mb=mg_donald_mb.temp1 \ - ferdinand_mb=mg_ferdinand_mb.temp1 + ferdinand_mb=mg_ferdinand_mb.temp1 donald_disk.sum \ mg_donald_disk.sda \ mg_donald_disk.sdb \ - mg_donald_disk.sdc + mg_donald_disk.sdc donald_disk.cdef donald_disk,3,/ donald_disk.label donald disk donald_mb.label Mainboard donald diff -Nru munin-2.0.37/plugins/node.d.debug/test_99_100 munin-2.0.47/plugins/node.d.debug/test_99_100 --- munin-2.0.37/plugins/node.d.debug/test_99_100 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.debug/test_99_100 2019-02-28 14:43:36.000000000 +0000 @@ -1,11 +1,11 @@ -#! /bin/bash +#!@@BASH@@ if [ "$1" == "config" ]; then echo "graph_title test with decimal value" echo "graph_category Debug" echo "graph_vlabel Some value" echo "field99_100.label Some random decimal between 99 and 100" -else +else # emit a random decimal value between 99 and 100 echo "field99_100.value 99.${RANDOM:1}" fi diff -Nru munin-2.0.37/plugins/node.d.debug/testplugin munin-2.0.47/plugins/node.d.debug/testplugin --- munin-2.0.37/plugins/node.d.debug/testplugin 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.debug/testplugin 2019-02-28 14:43:36.000000000 +0000 @@ -6,8 +6,8 @@ # 22:00 < janll> 4. broken config, good fetch # 22:00 < janll> 5. good config, broken fetch # 22:00 < janll> 6. broken everything -# -# 22:03 < janll> modes of breakage: mistyped keywords, missing keywords, missing +# +# 22:03 < janll> modes of breakage: mistyped keywords, missing keywords, missing # values, illegal values # Plugin filename = testplugin @@ -132,11 +132,11 @@ if ($other eq 'disturb') { $configure_mode -= 1; } - + if ($configure_mode) { foreach $line (keys %{$config{$config}->{$aspect}}) { - print $line, " ", $config{$config}->{$aspect}->{$line}, "\n"; + print $line, " ", $config{$config}->{$aspect}->{$line}, "\n"; } } else { foreach $line (keys %{$fetch{$fetch}->{$aspect}}) { diff -Nru munin-2.0.37/plugins/node.d.debug/warning_tester.in munin-2.0.47/plugins/node.d.debug/warning_tester.in --- munin-2.0.37/plugins/node.d.debug/warning_tester.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.debug/warning_tester.in 2019-02-28 14:43:36.000000000 +0000 @@ -27,7 +27,7 @@ EOF } -do_$1 2>/dev/null || { +"do_$1" 2>/dev/null || { echo "Do what now?">&2 exit 1 } diff -Nru munin-2.0.37/plugins/node.d.freebsd/cpu.in munin-2.0.47/plugins/node.d.freebsd/cpu.in --- munin-2.0.37/plugins/node.d.freebsd/cpu.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.freebsd/cpu.in 2019-02-28 14:43:36.000000000 +0000 @@ -67,8 +67,8 @@ echo 'system.max 5000' echo 'system.type DERIVE' echo 'system.min 0' -# echo "system.warning $SYSWARNING" -# echo "system.critical $SYSCRITICAL" +# echo "system.warning $SYSWARNING" +# echo "system.critical $SYSCRITICAL" echo 'system.info CPU time spent by the kernel in system activities' echo "system.cdef system,$CDEF" echo 'interrupt.label interrupt' diff -Nru munin-2.0.37/plugins/node.d.freebsd/df.in munin-2.0.47/plugins/node.d.freebsd/df.in --- munin-2.0.37/plugins/node.d.freebsd/df.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.freebsd/df.in 2019-02-28 14:43:36.000000000 +0000 @@ -24,9 +24,11 @@ exit 0 fi -EXCLUDEDFS="-t noprocfs,devfs,fdescfs,linprocfs,linsysfs,nfs,nullfs" +EXCLUDEDFS="-t noprocfs,devfs,fdescfs,linprocfs,linsysfs,sysfs,nfs,nullfs,cd9660" if [ $(uname -s) = "GNU/kFreeBSD" ]; then + # Debian ships df from GNU coreutils + # use "-x" instead of "-t", split comma-separated list into single arguments EXCLUDEDFS=$(echo $EXCLUDEDFS | sed 's/^-t /-x /; s/,/ -x /g') fi @@ -38,7 +40,7 @@ echo 'graph_scale no' echo 'graph_info This graph shows disk usage on the machine.' mfs=0 - /bin/df -P $EXCLUDEDFS | tail -n +2 | sort | grep -v '^/sys' | grep -v "//" | while read i; do + /bin/df -P $EXCLUDEDFS | tail -n +2 | sort | grep -v "//" | while read i; do case $i in mfs:*) name=mfs$mfs; mfs=`expr $mfs + 1`;; *) name=`echo $i | awk '{ gsub("[^a-zA-Z0-9_]", "_", $1); print $1 }'` ;; @@ -52,7 +54,7 @@ fi mfs=0 -/bin/df -P $EXCLUDEDFS | tail -n +2 | sort | grep -v '^/sys' | grep -v "//" | while read i; do +/bin/df -P $EXCLUDEDFS | tail -n +2 | sort | grep -v "//" | while read i; do case $i in mfs:*) name=mfs$mfs; mfs=`expr $mfs + 1`;; *) name=`echo $i | awk '{ gsub("[^a-zA-Z0-9_]", "_", $1); print $1 }'` ;; diff -Nru munin-2.0.37/plugins/node.d.freebsd/df_inode.in munin-2.0.47/plugins/node.d.freebsd/df_inode.in --- munin-2.0.37/plugins/node.d.freebsd/df_inode.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.freebsd/df_inode.in 2019-02-28 14:43:36.000000000 +0000 @@ -15,9 +15,17 @@ #%# family=auto #%# capabilities=autoconf +EXCLUDEDFS="-t noprocfs,devfs,fdescfs,linprocfs,linsysfs,sysfs,nfs,nullfs,cd9660" + +if [ $(uname -s) = "GNU/kFreeBSD" ]; then + # Debian ships df from GNU coreutils + # use "-x" instead of "-t", split comma-separated list into single arguments + EXCLUDEDFS=$(echo $EXCLUDEDFS | sed 's/^-t /-x /; s/,/ -x /g') +fi + print_values() { mfs=0 - /bin/df -P -i -t noprocfs,devfs,fdescfs,linprocfs,nfs,nullfs | tail +2 | grep -v "//" | while read i; do + /bin/df -P -i $EXCLUDEDFS | tail -n +2 | sort | grep -v "//" | while read i; do case $i in mfs:*) name=mfs$mfs; mfs=`expr $mfs + 1`;; *) name=`echo $i | awk '{ gsub("[^a-zA-Z0-9_]", "_", $1); print $1 }'` ;; @@ -44,7 +52,7 @@ echo 'graph_category disk' echo 'graph_scale no' echo 'graph_info This graph shows the inode usage for the partitions of types that use inodes.' - /bin/df -P -i -t noprocfs,devfs,fdescfs,linprocfs,nfs,nullfs | tail +2 | grep -v "//" | awk " + /bin/df -P -i $EXCLUDEDFS | tail -n +2 | sort | grep -v "//" | awk " BEGIN { mfs = 0 } diff -Nru munin-2.0.37/plugins/node.d.freebsd/if_.in munin-2.0.47/plugins/node.d.freebsd/if_.in --- munin-2.0.37/plugins/node.d.freebsd/if_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.freebsd/if_.in 2019-02-28 14:43:36.000000000 +0000 @@ -8,7 +8,7 @@ # # ...will monitor eth0. # -# To aggregate all network interfaces on the system (except lo0), +# To aggregate all network interfaces on the system (except lo0), # link if_aggregated to this file. # # Any device found in /usr/bin/netstat can be monitored. @@ -46,7 +46,7 @@ if [ "$1" = "config" ]; then - echo "graph_order rbytes obytes" + echo "graph_order rbytes obytes" echo "graph_title $INTERFACE traffic" echo 'graph_args --base 1000' echo 'graph_vlabel bits per ${graph_period} in (-) / out (+)' @@ -70,7 +70,7 @@ /usr/bin/netstat -i -b -n | grep -v '^lo' | awk ' BEGIN { rsum = 0; osum = 0; } // { - if (NF == 10) { + if (NF == 10) { rsum += $6; osum += $9; } else if (NF == 11) { if ($4 ~ /:/) { @@ -86,11 +86,11 @@ printf "rbytes.value %i\n", rsum; printf "obytes.value %i\n", osum; }' - + else /usr/bin/netstat -i -b -n -I $INTERFACE | awk ' // { - if (NF == 10) { + if (NF == 10) { print "rbytes.value", $6; print "obytes.value", $9; } else if (NF == 11) { diff -Nru munin-2.0.37/plugins/node.d.freebsd/if_packets_.in munin-2.0.47/plugins/node.d.freebsd/if_packets_.in --- munin-2.0.37/plugins/node.d.freebsd/if_packets_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.freebsd/if_packets_.in 2019-02-28 14:43:36.000000000 +0000 @@ -8,7 +8,7 @@ # # ...will monitor eth0. # -# To aggregate all network interfaces on the system (except lo0), +# To aggregate all network interfaces on the system (except lo0), # link if_packets_aggregated to this file. # # Any device found in /usr/bin/netstat can be monitored. @@ -70,7 +70,7 @@ /usr/bin/netstat -i -b -n | grep -v '^lo' | awk ' BEGIN { rsum = 0; osum = 0; } // { - if (NF == 10) { + if (NF == 10) { rsum += $4; osum += $7; } else if (NF == 11) { if ($4 ~ /:/) { diff -Nru munin-2.0.37/plugins/node.d.freebsd/iostat.in munin-2.0.47/plugins/node.d.freebsd/iostat.in --- munin-2.0.37/plugins/node.d.freebsd/iostat.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.freebsd/iostat.in 2019-02-28 14:43:36.000000000 +0000 @@ -2,7 +2,7 @@ # -*- sh -*- # # Original script (NetBSD) by he -# +# # Adapted to FreeBSD 6.2 / PC-BSD 1.4 by Pierre Bauduin (pierre@baudu.in) # Version 0.0.2 # October 24 2007 @@ -45,8 +45,8 @@ echo 'graph_category disk' echo 'graph_info This graph shows the I/O to and from block devices' # We don't give a XXXX about device or extended - drives=`/usr/sbin/iostat -I -x | - awk '/^device/ { next; } // { print $1; }' | + drives=`/usr/sbin/iostat -I -x | + awk '/^device/ { next; } // { print $1; }' | awk '/extended/ { next; } // { print $1; }'` echo -n 'graph_order' for d in $drives; do @@ -76,7 +76,7 @@ # On NetBSD the kilobyte read and kilobyte write are columns 5 and 9 # On FreeBSD the kilobyte read and kilobyte write are columns 4 and 5 /usr/sbin/iostat -I -x | - awk '/^device/ { next; } //' | + awk '/^device/ { next; } //' | awk '/extended/ { next; } //' | awk ' { print $1 "_read.value " int($4); diff -Nru munin-2.0.37/plugins/node.d.freebsd/memory.in munin-2.0.47/plugins/node.d.freebsd/memory.in --- munin-2.0.37/plugins/node.d.freebsd/memory.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.freebsd/memory.in 2019-02-28 14:43:36.000000000 +0000 @@ -30,13 +30,19 @@ PAGESIZE=$(/sbin/sysctl -n vm.stats.vm.v_page_size) MEMSIZE=$(/sbin/sysctl -n vm.stats.vm.v_page_count) MEMMAX=$(($PAGESIZE*$MEMSIZE)) +CACHE_COUNT=$(/sbin/sysctl -n vm.stats.vm.v_cache_count) +LAUNDRY_COUNT=$(/sbin/sysctl -n vm.stats.vm.v_laundry_count) if [ "$1" = "config" ]; then echo 'graph_args --base 1024 -l 0 --vertical-label Bytes --upper-limit' $MEMMAX echo 'graph_title Memory usage' echo 'graph_category system' echo 'graph_info This graph shows what the machine uses its memory for.' - echo 'graph_order active inactive wired buffers cached free swap' + # assemble the graph order (including the optional items) + printf 'graph_order active inactive wired buffers' + if [ -n "$CACHE_COUNT" ]; then printf ' cached'; fi + if [ -n "$LAUNDRY_COUNT" ]; then printf ' laundry'; fi + echo ' free swap' echo 'active.label active' echo 'active.info pages recently statistically used' echo 'active.draw AREA' @@ -49,9 +55,18 @@ echo 'buffers.label buffers' echo 'buffers.info pages used for filesystem buffers' echo 'buffers.draw STACK' - echo 'cached.label cache' - echo 'cached.info pages that have percolated from inactive to a status where they maintain their data, but can often be immediately reused' - echo 'cached.draw STACK' + # the "cache" counter was removed in 2015 + if [ -n "$CACHE_COUNT" ]; then + echo 'cached.label cache' + echo 'cached.info pages that have percolated from inactive to a status where they maintain their data, but can often be immediately reused' + echo 'cached.draw STACK' + fi + # the "laundry" counter was introduced in 2015 + if [ -n "$LAUNDRY_COUNT" ]; then + echo 'laundry.label laundry' + echo 'laundry.info number of dirty bytes inactive' + echo 'laundry.draw STACK' + fi echo 'free.label free' echo 'free.info pages without data content' echo 'free.draw STACK' @@ -65,13 +80,17 @@ INACTIVE_COUNT=$(/sbin/sysctl -n vm.stats.vm.v_inactive_count) WIRED_COUNT=$(/sbin/sysctl -n vm.stats.vm.v_wire_count) BUFFERS_COUNT=$(/sbin/sysctl -n vfs.bufspace) -CACHE_COUNT=$(/sbin/sysctl -n vm.stats.vm.v_cache_count) FREE_COUNT=$(/sbin/sysctl -n vm.stats.vm.v_free_count) echo active.value $(($ACTIVE_COUNT*$PAGESIZE)) echo inactive.value $(($INACTIVE_COUNT*$PAGESIZE)) echo wired.value $(($WIRED_COUNT*$PAGESIZE)) echo buffers.value $(($BUFFERS_COUNT)) -echo cached.value $(($CACHE_COUNT*$PAGESIZE)) +if [ -n "$CACHE_COUNT" ]; then + echo cached.value $(($CACHE_COUNT*$PAGESIZE)) +fi +if [ -n "$LAUNDRY_COUNT" ]; then + echo "laundry.value $(( LAUNDRY_COUNT * PAGESIZE ))" +fi echo free.value $(($FREE_COUNT*$PAGESIZE)) -echo swap.value $(swapinfo -k | awk '{sum += $3}; END {print sum * 1024}') +echo swap.value $(swapinfo -k | awk '!/^Total/ && !/^Device/ {sum += $3}; END {print sum * 1024}') diff -Nru munin-2.0.37/plugins/node.d.freebsd/netstat.in munin-2.0.47/plugins/node.d.freebsd/netstat.in --- munin-2.0.37/plugins/node.d.freebsd/netstat.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.freebsd/netstat.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,5 +1,6 @@ #!@@GOODSH@@ # -*- sh -*- + : << =cut =head1 NAME @@ -18,8 +19,6 @@ GPLv2 -=head1 BUGS - =head1 MAGIC MARKERS #%# family=auto @@ -27,16 +26,20 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" + + +NETSTAT_CMD=netstat + if [ "$1" = "autoconf" ]; then - if ( /usr/bin/netstat -s 2>/dev/null >/dev/null ); then + if ( "$NETSTAT_CMD" -s 2>/dev/null >/dev/null ); then echo yes exit 0 else if [ $? -eq 127 ] then - echo "no (netstat program not found)" + echo "no (program $NETSTAT_CMD not found)" exit 0 else echo no @@ -49,7 +52,7 @@ echo 'graph_title Netstat' echo 'graph_args --base 1000 --logarithmic' - echo 'graph_vlabel active connections per ${graph_period}' + echo 'graph_vlabel TCP connections' echo 'graph_category network' echo 'graph_period second' echo 'graph_info This graph shows the TCP activity of all the network interfaces combined.' @@ -91,9 +94,9 @@ exit 0 fi -/usr/bin/netstat -s | awk ' -/connection requests/ { print "active.value " $1 } -/connection accepts/ { print "passive.value " $1 } -/bad connection/ { print "failed.value " $1 } -/reset$/ { print "resets.value " $1 } +"$NETSTAT_CMD" -s | awk ' +/connection requests/ { print "active.value " $1 } +/connection accepts/ { print "passive.value " $1 } +/bad connection/ { print "failed.value " $1 } +/reset$/ { print "resets.value " $1 } /connections established/ { print "established.value " $1 }' diff -Nru munin-2.0.37/plugins/node.d.freebsd/open_files.in munin-2.0.47/plugins/node.d.freebsd/open_files.in --- munin-2.0.37/plugins/node.d.freebsd/open_files.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.freebsd/open_files.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,10 +1,10 @@ #!@@GOODSH@@ # -*- sh -*- -# +# # Plugin to monitor the number of open files in the system. # # Parameters: -# +# # config (required) # autoconf (optional - used by munin-config) # diff -Nru munin-2.0.37/plugins/node.d.freebsd/swap.in munin-2.0.47/plugins/node.d.freebsd/swap.in --- munin-2.0.37/plugins/node.d.freebsd/swap.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.freebsd/swap.in 2019-02-28 14:43:36.000000000 +0000 @@ -18,13 +18,13 @@ if [ "$1" = "autoconf" ]; then if [ -x /sbin/sysctl ]; then /sbin/sysctl vm.stats.vm.v_swappgsin > /dev/null - if [ $? = "0" ]; then - echo yes - exit 0 - else - echo no - exit 0 - fi + if [ $? = "0" ]; then + echo yes + exit 0 + else + echo no + exit 0 + fi else echo no exit 0 @@ -51,7 +51,7 @@ exit 0 fi -#awk '/swap/ { print "swap_in.value " $2 "\nswap_out.value " $3 }' < /proc/stat +#awk '/swap/ { print "swap_in.value " $2 "\nswap_out.value " $3 }' < /proc/stat echo -n 'swap_in.value ' /sbin/sysctl -n vm.stats.vm.v_swappgsin echo -n 'swap_out.value ' diff -Nru munin-2.0.37/plugins/node.d.hp-ux/gp_gbl_mem_util.adv munin-2.0.47/plugins/node.d.hp-ux/gp_gbl_mem_util.adv --- munin-2.0.37/plugins/node.d.hp-ux/gp_gbl_mem_util.adv 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.hp-ux/gp_gbl_mem_util.adv 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -if (gbl_interval > 2) then +if (gbl_interval > 2) then { print "mem_util.value ",gbl_mem_util|6|2 print "mem_user.value ",gbl_mem_user_util|6|2 diff -Nru munin-2.0.37/plugins/node.d.hp-ux/gp_gbl_mem_util.in munin-2.0.47/plugins/node.d.hp-ux/gp_gbl_mem_util.in --- munin-2.0.37/plugins/node.d.hp-ux/gp_gbl_mem_util.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.hp-ux/gp_gbl_mem_util.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,7 +1,7 @@ -#!/usr/bin/sh +#!@@GOODSH@@ # # gp_gbl_mem - Munin plug-in to fetch global memory utilisation via Glance -# (should only run on HP-UX with GlancePlus (GP) installed therefore) +# (should only run on HP-UX with GlancePlus (GP) installed therefore) # # Requires: Separate GP adviser syntax file whose location is made known # by ADVISER environment variable which defaults to @@ -23,13 +23,13 @@ # # # Note, to avoid parsing problems on start of munin-node -# add this entry to your munin-node.conf if you place the *.adv file +# add this entry to your munin-node.conf if you place the *.adv file # in above mentioned location: "ignore_file \.adv$" # # The contents of the syntax file for this plugin should look like # this: # -# if (gbl_interval > 2) then +# if (gbl_interval > 2) then # { # print "mem_util.value ",gbl_mem_util|6|2 # print "mem_user.value ",gbl_mem_user_util|6|2 diff -Nru munin-2.0.37/plugins/node.d.hp-ux/if_err_.in munin-2.0.47/plugins/node.d.hp-ux/if_err_.in --- munin-2.0.37/plugins/node.d.hp-ux/if_err_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.hp-ux/if_err_.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,6 @@ -#!/usr/bin/sh +#!@@GOODSH@@ # -# if_err_ +# if_err_ # # HP-UX wildcard-plugin to fetch error mibstats from network interfaces (NICs). # To add a NIC, symlink if_err_ in munin-node's plugins confdir to this file, @@ -53,7 +53,7 @@ fi if [[ $1 = config ]]; then - echo "graph_order inbound outbound" + echo "graph_order inbound outbound" echo "graph_title $INTERFACE errors" echo 'graph_args --base 1000' echo 'graph_vlabel packets per ${graph_period} in (-) / out (+)' diff -Nru munin-2.0.37/plugins/node.d.hp-ux/if_.in munin-2.0.47/plugins/node.d.hp-ux/if_.in --- munin-2.0.37/plugins/node.d.hp-ux/if_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.hp-ux/if_.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/sh +#!@@GOODSH@@ # # if_ # @@ -23,8 +23,8 @@ if [[ $1 = autoconf ]]; then if ! uname -s|grep -qEi hp-?ux; then - echo "no (OS doesn't seem to be HP-UX but reports as '$(uname -s)')" - exit 0 + echo "no (OS doesn't seem to be HP-UX but reports as '$(uname -s)')" + exit 0 fi if [ -x $LANADMIN ]; then echo yes @@ -38,22 +38,22 @@ if [[ $1 = suggest ]]; then # lanscan will list all usable NICs seen by the kernel if [ -x $LANSCAN ] \ - && seen=$($LANSCAN|awk '$3~/^[0-9]+$/&&$4=="UP"{print$5}'); then + && seen=$($LANSCAN|awk '$3~/^[0-9]+$/&&$4=="UP"{print$5}'); then # but netstat will only list currently configured NICs - if [[ -n $seen ]] && netstat -in|grep -q "$seen"; then - # HP-UX names all NICs with leading string "lan" (afaik) - # Note, in SG environments NICs with trailing asterisk - # are usually standby NICs that often are used for heartbeat exchange, - # why they are suitable for collecting data as well - netstat -in|awk 'NR>1&&$1~/^lan[0-9]+\*?$/{print$1}'|tr -d \* - exit 0 - fi + if [[ -n $seen ]] && netstat -in|grep -q "$seen"; then + # HP-UX names all NICs with leading string "lan" (afaik) + # Note, in SG environments NICs with trailing asterisk + # are usually standby NICs that often are used for heartbeat exchange, + # why they are suitable for collecting data as well + netstat -in|awk 'NR>1&&$1~/^lan[0-9]+\*?$/{print$1}'|tr -d \* + exit 0 + fi fi exit 1 fi if [[ $1 = config ]]; then - echo "graph_order inbound outbound" + echo "graph_order inbound outbound" echo "graph_title $INTERFACE traffic" echo 'graph_args --base 1000' echo 'graph_vlabel bits per ${graph_period} in (-) / out (+)' diff -Nru munin-2.0.37/plugins/node.d.hp-ux/mw_cpu.in munin-2.0.47/plugins/node.d.hp-ux/mw_cpu.in --- munin-2.0.37/plugins/node.d.hp-ux/mw_cpu.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.hp-ux/mw_cpu.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,5 +1,5 @@ #!@@PERL@@ -# -*- perl -*- +# -*- perl -*- # # this is public domain copy and share at will # quick n dirty hack to read specific performance data on HP-UX thru diff -Nru munin-2.0.37/plugins/node.d.hp-ux/netstat_rate_tcp_.in munin-2.0.47/plugins/node.d.hp-ux/netstat_rate_tcp_.in --- munin-2.0.37/plugins/node.d.hp-ux/netstat_rate_tcp_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.hp-ux/netstat_rate_tcp_.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/sh +#!@@GOODSH@@ # # netstat_rate_tcp_ - Munin wildcard plug-in to parse netstat TCP counters # diff -Nru munin-2.0.37/plugins/node.d.hp-ux/sar_cpu.in munin-2.0.47/plugins/node.d.hp-ux/sar_cpu.in --- munin-2.0.37/plugins/node.d.hp-ux/sar_cpu.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.hp-ux/sar_cpu.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/sh +#!@@GOODSH@@ # # HP-UX port from original cpu plugin, here using sar instead of # Solaris' kstat. Also note that kstat as well as Linux /proc/stat diff -Nru munin-2.0.37/plugins/node.d.java/jmx_.in munin-2.0.47/plugins/node.d.java/jmx_.in --- munin-2.0.37/plugins/node.d.java/jmx_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.java/jmx_.in 2019-02-28 14:43:36.000000000 +0000 @@ -35,7 +35,7 @@ to CATALINA_OPTS in your startup scripts. -Replace authenticate=false with +Replace authenticate=false with -Dcom.sun.management.jmxremote.password.file=/etc/tomcat/jmxremote.password \ -Dcom.sun.management.jmxremote.access.file=/etc/tomcat/jmxremote.access ...if you want authentication. diff -Nru munin-2.0.37/plugins/node.d.java/jmx_tomcat_dbpools.in munin-2.0.47/plugins/node.d.java/jmx_tomcat_dbpools.in --- munin-2.0.37/plugins/node.d.java/jmx_tomcat_dbpools.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.java/jmx_tomcat_dbpools.in 2019-02-28 14:43:36.000000000 +0000 @@ -33,7 +33,7 @@ to CATALINA_OPTS in your startup scripts. -Replace authenticate=false with +Replace authenticate=false with -Dcom.sun.management.jmxremote.password.file=/etc/tomcat/jmxremote.password \ -Dcom.sun.management.jmxremote.access.file=/etc/tomcat/jmxremote.access ...if you want authentication. @@ -52,8 +52,8 @@ =encoding UTF-8 -Code written by Jimmy Olsen, Redpill Linpro AS. This code also -uses code written by Mo Amini, Diyar Amin and Younes Hajji, +Code written by Jimmy Olsen, Redpill Linpro AS. This code also +uses code written by Mo Amini, Diyar Amin and Younes Hajji, Høgskolen i Oslo/Oslo University College. Previous work on JMX plugin by Aleksey Studnev. Support for @@ -111,7 +111,7 @@ sub fetch() { # Fetch bean values (through jmx) via the command line. We basically run the class "org.munin.plugin.jmx.Beans" - # with the parameters and , the being a bean pattern to fetch (in this case + # with the parameters and , the being a bean pattern to fetch (in this case # "Catalina:type=DataSource,class=javax.sql.DataSource,name=*", and being "numActive" (the single field # we're actually interested in). We can fetch multiple fields by listing them all as parameters, or list all fields # by not supplying a filter (only a bean). diff -Nru munin-2.0.37/plugins/node.d.linux/acpi.in munin-2.0.47/plugins/node.d.linux/acpi.in --- munin-2.0.37/plugins/node.d.linux/acpi.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/acpi.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,7 +1,7 @@ #!@@GOODSH@@ # -*- sh -*- -: <<=cut +: <<=cut =head1 NAME @@ -21,7 +21,7 @@ =head1 INTERPRETATION -The plugin shows the temperature from the different thermal zones. +The plugin shows the temperature from the different thermal zones. =head1 MAGIC MARKERS @@ -49,7 +49,11 @@ # directories containing thermal zone information -ATZ=$(find /sys/class/thermal/ -maxdepth 1 -name "thermal_zone*") +if [ -d /sys/class/thermal/ ]; then + ATZ=$(find /sys/class/thermal/ -maxdepth 1 -name "thermal_zone*") +else + ATZ= +fi do_ () { # Fetch diff -Nru munin-2.0.37/plugins/node.d.linux/apt_all.in munin-2.0.47/plugins/node.d.linux/apt_all.in --- munin-2.0.37/plugins/node.d.linux/apt_all.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/apt_all.in 2019-02-28 14:43:36.000000000 +0000 @@ -19,6 +19,12 @@ [apt_all] env.options -o Debug::pkgDepCache::AutoInstall=false -o APT::Get::Show-Versions=false +env.releases stable experimental + +"options" is empty by default. +"releases" is a space separated list of release names. It defaults to +the empty string. This default triggers the automatic detection of +available distributions from the URLs of all configured repositories. Note that apt is called with no extra options by default, so it fully honors your /etc/apt.conf defaults. @@ -55,12 +61,35 @@ # Now for the real work... use strict; +use Munin::Plugin; $ENV{'LANG'}="C"; $ENV{'LC_ALL'}="C"; my $statefile = ($ENV{MUNIN_PLUGSTATE} || '@@PLUGSTATE@@/nobody/') . "/plugin-apt.state"; -my @releases = ("stable", "testing","unstable"); + + +# try to determine the currently available distributions by inspecting the repository URLs +sub guess_releases() { + open(my $fh, "-|", "apt-get update --print-uris") + or die("Failed to determine distribution releases via 'apt-get update --print-uris"); + my %release_names; + my $line; + while ( ! eof($fh) ) { + defined( $line = readline $fh ) or die "Failed to read line from output of 'apt-get': $!"; + # example line: + # 'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0 + if ($line =~ m'^.*/dists/([^/]+)/.*$') { + $release_names{$1} = 1; + } + } + return keys %release_names; +} + + +# use a given 'releases' environment variable (space separated names) or inspect the repository URLs +my @releases = split(/\s/, ($ENV{releases} || "")); +@releases = guess_releases() unless @releases; sub print_state() { @@ -75,7 +104,14 @@ } open(STATE, "$statefile") or die("Couldn't open state file $statefile for reading."); - print while ; + while (my $line = ) { + foreach my $release (@releases) { + my $release_cleaned = clean_fieldname($release); + # print only lines that are exected for the currently requested releases + print $line if ($line =~ /^(hold|pending)_$release_cleaned\.(value|extinfo)/); + last; + } + } close STATE; } @@ -146,12 +182,13 @@ push (@pending, @remove ) if @remove; close APT; - print STATE "pending_$release.value ", scalar (@pending), "\n"; + my $release_cleaned = clean_fieldname($release); + print STATE "pending_$release_cleaned.value ", scalar (@pending), "\n"; if (@pending) { - print STATE "pending_$release.extinfo ", join (' ', @pending), "\n"; + print STATE "pending_$release_cleaned.extinfo ", join (' ', @pending), "\n"; } - print STATE "hold_$release.value $hold\n"; + print STATE "hold_$release_cleaned.value $hold\n"; } close(STATE); @@ -190,9 +227,10 @@ print "graph_category system\n"; foreach my $release (@releases) { - print "pending_$release.label pending_$release\n"; - print "pending_$release.warning 0:0\n"; - print "hold_$release.label hold_$release\n"; + my $release_cleaned = clean_fieldname($release); + print "pending_$release_cleaned.label pending ($release)\n"; + print "pending_$release_cleaned.warning 0:0\n"; + print "hold_$release_cleaned.label hold ($release)\n"; } exit 0; } @@ -200,26 +238,17 @@ if ($ARGV[0] and $ARGV[0] eq "update") { my $maxinterval = $ARGV[1] ? $ARGV[1] : update_helpandexit; my $probability = $ARGV[2] ? $ARGV[2] : update_helpandexit; - - # if it's been $probability seconds since the last update, do - # it now. - if(-e $statefile && - (stat($statefile))[10] + $maxinterval < time()) { - update_state(); - exec("/usr/bin/apt-get update") - or die("Unable to exec() apt-get"); - } - - # if the state-file doesn't exist, create it. - if(!-e $statefile) { - update_state(); - } - # update the database if the 1 in $probability check hits. - if(!int(rand($probability))) { + # The state file needs an update in three situations: + # * it does not exist + # * $maxinterval seconds elapsed since the last update + # * random $probability was hit (one out of $probability) + if (!-e $statefile + || ((stat($statefile))[10] + $maxinterval < time()) + || (int(rand($probability)) == 0)) { + system("/usr/bin/apt-get update") == 0 + or die("Failed to run 'apt-get update'"); update_state(); - exec("/usr/bin/apt-get update") - or die("Unable to exec() apt-get"); } exit(0); } diff -Nru munin-2.0.37/plugins/node.d.linux/apt.in munin-2.0.47/plugins/node.d.linux/apt.in --- munin-2.0.37/plugins/node.d.linux/apt.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/apt.in 2019-02-28 14:43:36.000000000 +0000 @@ -128,7 +128,7 @@ { my $maxinterval = $ARGV[1] ? $ARGV[1] : update_helpandexit; my $probability = $ARGV[2] ? $ARGV[2] : update_helpandexit; - + # if it's been $probability seconds since the last update, do # it now. if(-e $statefile && diff -Nru munin-2.0.37/plugins/node.d.linux/bonding_err_.in munin-2.0.47/plugins/node.d.linux/bonding_err_.in --- munin-2.0.37/plugins/node.d.linux/bonding_err_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/bonding_err_.in 2019-02-28 14:43:36.000000000 +0000 @@ -47,11 +47,19 @@ EOF # Source plugin library functions -. $MUNIN_LIBDIR/plugins/plugin.sh +# shellcheck disable=SC1090 +. "$MUNIN_LIBDIR/plugins/plugin.sh" PROCDIR="/proc/net/bonding" -MYSELF=$(basename $0) +MYSELF=$(basename "$0") FILENAME="bonding_err_" +BONDINGIF=$(echo "$MYSELF" | sed "s/^$FILENAME//") + + +get_bonding_interface_names() { + grep "^Slave Interface:" "${PROCDIR}/${BONDINGIF}" | awk '{print $3}' +} + if [ "$1" = "autoconf" ]; then if [ -d "${PROCDIR}" ]; then @@ -63,40 +71,35 @@ fi if [ "$1" = "suggest" ]; then - ls -1 ${PROCDIR} + ls -1 "$PROCDIR" exit 0 fi +if [ "$MYSELF" = "$FILENAME" ]; then + echo "Can't run an un-symlinked plugin. Please run the plugin with 'suggest' before attempting this." + exit 1 +fi + if [ "$1" = "config" ]; then - if [ "$MYSELF" = "$FILENAME" ]; then - echo "Can't run config on un-symlinked plugin. Please run the plugin with 'suggest' before attempting this." - exit 0 - else - BONDINGIF=$(echo $MYSELF | sed "s/^$FILENAME//") echo "graph_title Bonding interface errors for $BONDINGIF" echo "graph_category Network" echo "graph_args --base 1000 -l 0" - grep "^Slave Interface:" ${PROCDIR}/${BONDINGIF} | while read a b if; do - fieldname=$(clean_fieldname "$if") - echo "if_${fieldname}.label ${if}" + get_bonding_interface_names | while read -r if_name; do + fieldname=$(clean_fieldname "$if_name") + echo "if_${fieldname}.label $if_name" echo "if_${fieldname}.type DERIVE" echo "if_${fieldname}.min 0" echo "if_${fieldname}.warning 0" done - fi - exit 0 -fi - -if [ "$MYSELF" = "$FILENAME" ]; then - echo "Can't run an un-symlinked plugin. Please run the plugin with 'suggest' before attempting this." - exit 0 + exit 0 fi -BONDINGIF=$(echo $MYSELF | sed "s/^$FILENAME//") -grep "^Slave Interface:" ${PROCDIR}/${BONDINGIF} | while read a b if; do - fieldname=$(clean_fieldname "$if") +get_bonding_interface_names | while read -r if_name; do + fieldname=$(clean_fieldname "$if_name") echo -n "if_${fieldname}.value " - grep -A 4 "^Slave Interface: ${if}" ${PROCDIR}/${BONDINGIF} | grep "Link Failure Count:" | cut -d " " -f 4 + sed "0,/^Slave Interface: ${if_name}/d; /^\$/,\$d" "${PROCDIR}/${BONDINGIF}" \ + | grep "Link Failure Count:" \ + | cut -d " " -f 4 done diff -Nru munin-2.0.37/plugins/node.d.linux/cps_.in munin-2.0.47/plugins/node.d.linux/cps_.in --- munin-2.0.37/plugins/node.d.linux/cps_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/cps_.in 2019-02-28 14:43:36.000000000 +0000 @@ -27,6 +27,7 @@ #%# capabilities=autoconf suggest # +use warnings; use strict; if ( defined $ARGV[0] and $ARGV[0] eq "autoconf" ) { @@ -83,15 +84,18 @@ print "yes\n"; exit 0; } + elsif ($? & 127) { + print "no (system call exited with %d)", $? & 127; + } elsif (($?>>8) == 2) { print "no (permission denied)\n"; exit 0; } - elsif ($? == 127) { + elsif (($?>>8) == 127) { print "no (ipvsadm not found)\n"; exit 0; } else { - print "no\n"; + print "no (unknown ipvsadm return value: $?, %d)\n", $? >> 8; exit 0; } } diff -Nru munin-2.0.37/plugins/node.d.linux/cpu.in munin-2.0.47/plugins/node.d.linux/cpu.in --- munin-2.0.37/plugins/node.d.linux/cpu.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/cpu.in 2019-02-28 14:43:36.000000000 +0000 @@ -16,8 +16,13 @@ [cpu] env.HZ 100 + env.scaleto100 no -See "BUGS" for a explanation of this setting. +"scaleto100" may be "yes" or "no". With "yes" all CPU-related values +are scaled for a limit of 100. With "no" (the default) all CPU-related +values are scaled for a limit of n * 100 ("n" being the number of CPUs). + +See "BUGS" for an explanation of the "HZ" setting. =head2 EXAMPLE WARNING AND CRITICAL SETTINGS @@ -72,10 +77,6 @@ #%# capabilities=autoconf -=head1 VERSION - - $Id$ - =head1 BUGS Some combinations of hardware and Linux (probably only 2.4 kernels) @@ -98,7 +99,7 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" if [ "$1" = "autoconf" ]; then if [ -r /proc/stat ]; then @@ -111,15 +112,16 @@ fi HZ=${HZ:-100} +scaleto100=${scaleto100:-no} extinfo="" -if egrep -q '^cpu +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+' /proc/stat; then +if grep -qE '^cpu +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+' /proc/stat; then extinfo="iowait irq softirq" - if egrep -q '^cpu +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+' /proc/stat; then + if grep -qE '^cpu +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+' /proc/stat; then extextinfo="steal" fi - if egrep -q '^cpu +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+' /proc/stat; then + if grep -qE '^cpu +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+ +[0-9]+' /proc/stat; then extextextinfo="guest" fi @@ -127,14 +129,14 @@ if [ "$1" = "config" ]; then - NCPU=$(egrep '^cpu[0-9]+ ' /proc/stat | wc -l) + NCPU=$(grep -E '^cpu[0-9]+ ' /proc/stat | wc -l) if [ "$scaleto100" = "yes" ]; then graphlimit=100 else - graphlimit=$(($NCPU * 100)) + graphlimit=$((NCPU * 100)) fi echo 'graph_title CPU usage' - echo "graph_order system user nice idle" $extinfo + echo "graph_order system user nice idle $extinfo" echo "graph_args --base 1000 -r --lower-limit 0 --upper-limit $graphlimit" echo 'graph_vlabel %' echo 'graph_scale no' @@ -145,7 +147,7 @@ echo 'system.draw AREA' echo 'system.min 0' echo 'system.type DERIVE' - echo "system.info CPU time spent by the kernel in system activities" + echo "system.info CPU time spent by the kernel in system activities" echo 'user.label user' echo 'user.draw STACK' echo 'user.min 0' @@ -172,7 +174,7 @@ echo "nice.cdef nice,$NCPU,/" echo "idle.cdef idle,$NCPU,/" fi - if [ ! -z "$extinfo" ] + if [ -n "$extinfo" ] then echo 'iowait.label iowait' echo 'iowait.draw STACK' @@ -199,7 +201,7 @@ done fi - if [ ! -z "$extextinfo" ] + if [ -n "$extextinfo" ] then echo 'steal.label steal' echo 'steal.draw STACK' @@ -209,12 +211,10 @@ if [ "$scaleto100" = "yes" ]; then echo "steal.cdef steal,$NCPU,/" fi - for field in steal; do - print_adjusted_thresholds "$field" "$graphlimit" - done + print_adjusted_thresholds "steal" "$graphlimit" fi - if [ ! -z "$extextextinfo" ] + if [ -n "$extextextinfo" ] then echo 'guest.label guest' echo 'guest.draw STACK' @@ -224,9 +224,7 @@ if [ "$scaleto100" = "yes" ]; then echo "guest.cdef guest,$NCPU,/" fi - for field in guest; do - print_adjusted_thresholds "$field" "$graphlimit" - done + print_adjusted_thresholds "guest" "$graphlimit" fi exit 0 @@ -235,12 +233,12 @@ # Note: Counters/derive need to report integer values. Also we need # to avoid 10e+09 and the like %.0f should do this. -if [ ! -z "$extextextinfo" ]; then - awk -v hz=$HZ '/^cpu / { printf "user.value %.0f\nnice.value %.0f\nsystem.value %.0f\nidle.value %.0f\niowait.value %.0f\nirq.value %.0f\nsoftirq.value %.0f\nsteal.value %.0f\nguest.value %.0f\n", $2*100/hz, $3*100/hz, $4*100/hz, $5*100/hz, $6*100/hz, $7*100/hz, $8*100/hz, $9*100/hz, $10*100/hz }' < /proc/stat -elif [ ! -z "$extextinfo" ]; then - awk -v hz=$HZ '/^cpu / { printf "user.value %.0f\nnice.value %.0f\nsystem.value %.0f\nidle.value %.0f\niowait.value %.0f\nirq.value %.0f\nsoftirq.value %.0f\nsteal.value %.0f\n", $2*100/hz, $3*100/hz, $4*100/hz, $5*100/hz, $6*100/hz, $7*100/hz, $8*100/hz, $9*100/hz }' < /proc/stat -elif [ ! -z "$extinfo" ]; then - awk -v hz=$HZ '/^cpu / { printf "user.value %.0f\nnice.value %.0f\nsystem.value %.0f\nidle.value %.0f\niowait.value %.0f\nirq.value %.0f\nsoftirq.value %.0f\n", $2*100/hz, $3*100/hz, $4*100/hz, $5*100/hz, $6*100/hz, $7*100/hz, $8*100/hz }' < /proc/stat +if [ -n "$extextextinfo" ]; then + awk -v "hz=$HZ" '/^cpu / { printf "user.value %.0f\nnice.value %.0f\nsystem.value %.0f\nidle.value %.0f\niowait.value %.0f\nirq.value %.0f\nsoftirq.value %.0f\nsteal.value %.0f\nguest.value %.0f\n", $2*100/hz, $3*100/hz, $4*100/hz, $5*100/hz, $6*100/hz, $7*100/hz, $8*100/hz, $9*100/hz, $10*100/hz }' < /proc/stat +elif [ -n "$extextinfo" ]; then + awk -v "hz=$HZ" '/^cpu / { printf "user.value %.0f\nnice.value %.0f\nsystem.value %.0f\nidle.value %.0f\niowait.value %.0f\nirq.value %.0f\nsoftirq.value %.0f\nsteal.value %.0f\n", $2*100/hz, $3*100/hz, $4*100/hz, $5*100/hz, $6*100/hz, $7*100/hz, $8*100/hz, $9*100/hz }' < /proc/stat +elif [ -n "$extinfo" ]; then + awk -v "hz=$HZ" '/^cpu / { printf "user.value %.0f\nnice.value %.0f\nsystem.value %.0f\nidle.value %.0f\niowait.value %.0f\nirq.value %.0f\nsoftirq.value %.0f\n", $2*100/hz, $3*100/hz, $4*100/hz, $5*100/hz, $6*100/hz, $7*100/hz, $8*100/hz }' < /proc/stat else - awk -v hz=$HZ '/^cpu / { printf "user.value %.0f\nnice.value %.0f\nsystem.value %.0f\nidle.value %.0f\n", $2*100/hz, $3*100/hz, $4*100/hz, $5*100/hz }' < /proc/stat + awk -v "hz=$HZ" '/^cpu / { printf "user.value %.0f\nnice.value %.0f\nsystem.value %.0f\nidle.value %.0f\n", $2*100/hz, $3*100/hz, $4*100/hz, $5*100/hz }' < /proc/stat fi diff -Nru munin-2.0.37/plugins/node.d.linux/cpuspeed.in munin-2.0.47/plugins/node.d.linux/cpuspeed.in --- munin-2.0.37/plugins/node.d.linux/cpuspeed.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/cpuspeed.in 2019-02-28 14:43:36.000000000 +0000 @@ -19,22 +19,34 @@ You can set one environment variable to modify the plugins behaviour: [cpuspeed] - env.scaleto100 1 + env.scaleto100 yes -Show the frequency as a percentage instead of absolute frequency. If -set the plugin sets up a CDEF to change the speed in Hz to percent. +Show the frequency as a percentage instead of absolute frequency. +If set the "yes" the plugin sets up a CDEF to change the speed in Hz +to percent. If you set or unset this the whole time series will be shown in the same way, either as Hz or percent (as the graphs are updated). =head1 INTERPRETATION -The plugin shows the average CPU speed in the measurement period as -represented by /sys/devices/system/cpu/*/cpufreq/stats/time_in_state. +The plugin supports two sources of information. -This is a counter plugin and represents the average. Many cpuspeed -plugins reports the "instant" CPU speed at the time the plugin runs. -This is not representative for this metric. +The optimal source of information is the "acpi-cpufreq" kernel module. +It provides access to the accumulated time a CPU spent in a specific +speed state (see /sys/devices/system/cpu/*/cpufreq/stats/time_in_state). +This value is fine-grained and represents the *average* CPU speed for +every data collection period. +This data is available only for non-Intel CPUs. + +An alternative (sub-optimal) source of information is provided by the +"intel_pstate" driver (typically built into a kernel). +This driver delivers only *instant* information about the CPU speed +(at the time of the munin data collection). This is not necessarily +representative for the real CPU speed history. +The "pstate" driver conflicts with "acpi-cpufreq". Thus hosts with an +Intel CPU are usually stuck with "intel_pstate" as a less optimal +source of frequency information. =head1 BUGS @@ -55,24 +67,31 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" + +scaleto100=${scaleto100:-no} +ACPI_CPUFREQ_INDICATOR_FILENAME=/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state +INTEL_PSTATE_INDICATOR_FILENAME=/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq + if [ "$1" = "autoconf" ]; then - if [ -r /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state ] ; then + if [ -r "$ACPI_CPUFREQ_INDICATOR_FILENAME" ]; then + # "acpi-cpufreq" is available + echo yes + elif [ -r "$INTEL_PSTATE_INDICATOR_FILENAME" ]; then + # the "intel_pstate" driver is available (no averaging, but at least snapshot values) echo yes - exit 0 else - echo "no (missing /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state)" - exit 0 + echo "no (neither $ACPI_CPUFREQ_INDICATOR_FILENAME nor $INTEL_PSTATE_INDICATOR_FILENAME is readable)" fi + exit 0 fi if [ "$1" = "config" ]; then - echo graph_title CPU frequency scaling - echo graph_args --base 1000 - echo graph_info This graph shows the average speeds at which the CPUs are running - echo graph_category system + echo "graph_title CPU frequency scaling" + echo "graph_args --base 1000" + echo "graph_category system" if [ "$scaleto100" = "yes" ]; then echo "graph_vlabel %" @@ -80,43 +99,60 @@ else echo "graph_vlabel Hz" fi + # the visualized data depends on the available data source + if [ -r "$ACPI_CPUFREQ_INDICATOR_FILENAME" ]; then + graph_info="This graph shows the average running speed of each CPU." + field_type="DERIVE" + elif [ -r "$INTEL_PSTATE_INDICATOR_FILENAME" ]; then + graph_info="This graph shows the current speed of the CPU at the time of the data retrieval (not its average). This is a limitiation of the 'intel_pstate' driver." + field_type="GAUGE" + else + graph_info="The properties of this data source are not documented." + field_type="DERIVE" + fi + echo "graph_info $graph_info" for c in /sys/devices/system/cpu/cpu[0-9]*; do N=${c##*/cpu} echo "cpu$N.label CPU $N" - echo "cpu$N.type DERIVE" + echo "cpu$N.type $field_type" - if [ -r $c/cpufreq/cpuinfo_max_freq ]; then + if [ -r "$c/cpufreq/cpuinfo_max_freq" ]; then - MAXHZ=$(cat $c/cpufreq/cpuinfo_max_freq) + MAXHZ=$(cat "$c/cpufreq/cpuinfo_max_freq") # Adding 10% to $MAXHZ, to cope with polling jitters # See bug D#615957 - MAXHZ=$(( $MAXHZ + $MAXHZ / 10 )) + MAXHZ=$(( MAXHZ + MAXHZ / 10 )) echo "cpu$N.max $MAXHZ" if [ "$scaleto100" = "yes" ]; then - echo "cpu$N.cdef cpu$N,1000,*,$MAXHZ,/" + echo "cpu$N.cdef cpu$N,1000,*,$MAXHZ,/" else - echo "cpu$N.cdef cpu$N,1000,*" + echo "cpu$N.cdef cpu$N,1000,*" fi - fi + fi - if [ -r $c/cpufreq/cpuinfo_min_freq ]; then - MINHZ=$(cat $c/cpufreq/cpuinfo_min_freq) + if [ -r "$c/cpufreq/cpuinfo_min_freq" ]; then + MINHZ=$(cat "$c/cpufreq/cpuinfo_min_freq") echo "cpu$N.min $MINHZ" - fi + fi - print_warning "cpu$N" - print_critical "cpu$N" + print_warning "cpu$N" + print_critical "cpu$N" done - exit 0; + if [ "${MUNIN_CAP_DIRTYCONFIG:-0}" != 1 ]; then exit 0; fi fi for c in /sys/devices/system/cpu/cpu[0-9]*; do N=${c##*/cpu} - awk -v cpu=$N '{ cycles += $1 * $2 } - END { printf "cpu%d.value %.0f\n", cpu, cycles / 100; }' \ - $c/cpufreq/stats/time_in_state + if [ -r "$ACPI_CPUFREQ_INDICATOR_FILENAME" ]; then + value=$(awk '{ cycles += $1 * $2 } END { print(cycles / 100); }' "$c/cpufreq/stats/time_in_state") + elif [ -r "$INTEL_PSTATE_INDICATOR_FILENAME" ]; then + value=$(cat "$c/cpufreq/scaling_cur_freq") + else + value="U" + fi + printf 'cpu%d.value %s\n' "$N" "$value" done diff -Nru munin-2.0.37/plugins/node.d.linux/df_abs.in munin-2.0.47/plugins/node.d.linux/df_abs.in --- munin-2.0.37/plugins/node.d.linux/df_abs.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/df_abs.in 2019-02-28 14:43:36.000000000 +0000 @@ -47,7 +47,7 @@ EOF -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" if [ "$1" = "autoconf" ]; then echo yes @@ -56,11 +56,11 @@ # Append $mnt in case $dev is not a real block device get_fieldname() { - dev="$1" - mnt="$2" + local dev="$1" + local mnt="$2" case "$dev" in /* ) - clean_fieldname $dev + clean_fieldname "$dev" ;; * ) clean_fieldname "$dev $mnt" @@ -71,7 +71,7 @@ total=${total:-on} exclude=${exclude:-iso9660} -exclude=$(echo $exclude | sed -r -e 's/ +/ -x /g' -e 's/^/-x /') +exclude=$(echo "$exclude" | sed -r -e 's/ +/ -x /g' -e 's/^/-x /') if [ "$1" = "config" ]; then @@ -82,24 +82,26 @@ if [ "$total" = "on" ]; then echo 'graph_total Total' fi - df -P -l $exclude | sed 1d | grep -v "//" | - while read dev size used avail cap mnt; do - name="$(get_fieldname $dev $mnt)" + # shellcheck disable=SC2086 + df -P -l $exclude | sed 1d | grep -v "//" | + while read -r dev size used avail cap mnt; do + name="$(get_fieldname "$dev" "$mnt")" echo "$name.label $mnt" echo "$name.cdef $name,1024,*" - warn=$(get_warning $name) - crit=$(get_critical $name) + warn=$(get_warning "$name") + crit=$(get_critical "$name") if [ -n "$warn" ]; then - echo "$name.warning $((size * $warn / 100))" + echo "$name.warning $((size * warn / 100))" fi if [ -n "$crit" ]; then - echo "$name.critical $((size * $crit / 100))" + echo "$name.critical $((size * crit / 100))" fi done exit 0 fi -df -P -l $exclude | sed 1d | grep -v "//" | - while read dev size used avail cap mnt; do - echo "$(get_fieldname $dev $mnt).value $used" -done +# shellcheck disable=SC2034,SC2086 +df -P -l $exclude | sed 1d | grep -v "//" | + while read -r dev size used avail cap mnt; do + echo "$(get_fieldname "$dev" "$mnt").value $used" + done diff -Nru munin-2.0.37/plugins/node.d.linux/df.in munin-2.0.47/plugins/node.d.linux/df.in --- munin-2.0.37/plugins/node.d.linux/df.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/df.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,9 @@ #!@@PERL@@ -w # -*- perl -*- +use strict; +use warnings; + =head1 NAME df - Munin plugin to monitor disk usage @@ -81,7 +84,6 @@ =cut -use strict; use Munin::Plugin; # For these devices use the mount point, the device is useless diff -Nru munin-2.0.37/plugins/node.d.linux/diskstat_.in munin-2.0.47/plugins/node.d.linux/diskstat_.in --- munin-2.0.37/plugins/node.d.linux/diskstat_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/diskstat_.in 2019-02-28 14:43:36.000000000 +0000 @@ -389,7 +389,7 @@ my $average_rq_size_in_kb = $total_ios - ? ( $rd_sectors + $wr_sectors ) + ? ( $rd_sectors + $wr_sectors ) * $bytes_per_sector / 1024 / $total_ios : 0; diff -Nru munin-2.0.37/plugins/node.d.linux/diskstats.in munin-2.0.47/plugins/node.d.linux/diskstats.in --- munin-2.0.37/plugins/node.d.linux/diskstats.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/diskstats.in 2019-02-28 14:43:36.000000000 +0000 @@ -427,8 +427,10 @@ my @elems = split /\s+/, $line; - croak "'$stats_file' doesn't contain exactly 11 values. Aborting" - if ( @elems != 11 ); + # before linux 4.19, /sys/block//stat had 11 fields. + # in 4.19, four fields for tracking DISCARDs have been added + croak "'$stats_file' contains the wrong amount of values. Aborting" + if ( @elems != 11 && @elems != 15 ); # Translate the devicename back before storing the information $cur_device =~ tr#!#/#; @@ -825,7 +827,7 @@ multigraph ${plugin_name}_iops graph_title Disk IOs per device graph_args --base 1000 -graph_vlabel IOs/\${graph_period} read (-) / write (+) +graph_vlabel IOs/\${graph_period} read (-) / write (+) graph_category disk graph_width $config_graph_width diff -Nru munin-2.0.37/plugins/node.d.linux/entropy.in munin-2.0.47/plugins/node.d.linux/entropy.in --- munin-2.0.37/plugins/node.d.linux/entropy.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/entropy.in 2019-02-28 14:43:36.000000000 +0000 @@ -26,7 +26,7 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" if [ "$1" = "autoconf" ]; then if [ -r /proc/sys/kernel/random/entropy_avail ]; then @@ -37,7 +37,7 @@ exit 0 fi fi - + if [ "$1" = "config" ]; then echo 'graph_title Available entropy' echo 'graph_args --base 1000 -l 0' diff -Nru munin-2.0.37/plugins/node.d.linux/forks.in munin-2.0.47/plugins/node.d.linux/forks.in --- munin-2.0.37/plugins/node.d.linux/forks.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/forks.in 2019-02-28 14:43:36.000000000 +0000 @@ -26,11 +26,11 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" if [ "$1" = "autoconf" ]; then if [ -r /proc/stat ]; then - echo yes + echo yes exit 0 else echo "no (/proc/stat not readable)" @@ -42,6 +42,7 @@ echo 'graph_title Fork rate' echo 'graph_args --base 1000 -l 0 ' + # shellcheck disable=SC2016 echo 'graph_vlabel forks / ${graph_period}' echo 'graph_category processes' echo 'graph_info This graph shows the number of forks (new processes started) per second.' @@ -57,6 +58,3 @@ echo -n "forks.value " awk '/processes/ {print $2}' /proc/stat - - - diff -Nru munin-2.0.37/plugins/node.d.linux/fw_conntrack.in munin-2.0.47/plugins/node.d.linux/fw_conntrack.in --- munin-2.0.37/plugins/node.d.linux/fw_conntrack.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/fw_conntrack.in 2019-02-28 14:43:36.000000000 +0000 @@ -75,7 +75,7 @@ if ( -x $conntrack or -r $nf_conntrack_file or -r $ip_conntrack_file) { print "yes\n"; } else { - print "no\n"; + print "no (command $conntrack or file $nf_conntrack_file or file $ip_conntrack_file not found)\n"; } exit 0; } diff -Nru munin-2.0.37/plugins/node.d.linux/fw_forwarded_local.in munin-2.0.47/plugins/node.d.linux/fw_forwarded_local.in --- munin-2.0.37/plugins/node.d.linux/fw_forwarded_local.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/fw_forwarded_local.in 2019-02-28 14:43:36.000000000 +0000 @@ -47,7 +47,7 @@ if ( -x $conntrack or -r $nf_conntrack_file or -r $ip_conntrack_file) { print "yes\n"; } else { - print "no\n"; + print "no (command $conntrack or file $nf_conntrack_file or file $ip_conntrack_file not found)\n"; } exit 0; } diff -Nru munin-2.0.37/plugins/node.d.linux/fw_packets.in munin-2.0.47/plugins/node.d.linux/fw_packets.in --- munin-2.0.37/plugins/node.d.linux/fw_packets.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/fw_packets.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,9 @@ #!@@PERL@@ -w # -*- perl -*- +use strict; +use warnings; + =head1 NAME fw_packets - Plugin to monitor the throuhgput of a firewall @@ -38,7 +41,7 @@ print "yes\n"; exit 0; } - print "no\n"; + print "no (file /proc/net/snmp not readable)\n"; exit 0; } elsif ( $ARGV[0] eq 'config' ) { @@ -69,9 +72,9 @@ while () { if (/^Ip: \d/) { - @ip = split; - $forwarded = $ip[6]; #forwarded - $received = $ip[3]; #received + my @ip = split; + my $forwarded = $ip[6]; #forwarded + my $received = $ip[3]; #received print "received.value $received\n"; print "forwarded.value $forwarded\n"; @@ -79,7 +82,7 @@ # destined for the firewall, then the difference is wrong. If # you firewall does not receive traffic itself it is correct # though. - # + # # print "rejected.value ", $received - $forwarded,"\n"; last; } diff -Nru munin-2.0.37/plugins/node.d.linux/if_err_.in munin-2.0.47/plugins/node.d.linux/if_err_.in --- munin-2.0.37/plugins/node.d.linux/if_err_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/if_err_.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,8 @@ #!@@GOODSH@@ # -*- sh -*- +set -e + : << =cut =head1 NAME @@ -42,7 +44,7 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" INTERFACE=${0##*/if_err_} @@ -67,6 +69,7 @@ echo "graph_order rcvd trans" echo "graph_title $INTERFACE errors" echo 'graph_args --base 1000' + # shellcheck disable=SC2016 echo 'graph_vlabel packets in (-) / out (+) per ${graph_period}' echo 'graph_category network' echo "graph_info This graph shows the amount of errors, packet drops, and collisions on the $INTERFACE network interface." @@ -94,20 +97,20 @@ fi; # Escape dots in the interface name (eg. vlans) before using it as a regex -if [ -r /sys/class/net/$INTERFACE/statistics/rx_bytes ]; then - echo "rcvd.value $(cat /sys/class/net/$INTERFACE/statistics/rx_errors)" - echo "trans.value $(cat /sys/class/net/$INTERFACE/statistics/tx_errors)" - echo "rxdrop.value $(cat /sys/class/net/$INTERFACE/statistics/rx_dropped)" - echo "txdrop.value $(cat /sys/class/net/$INTERFACE/statistics/tx_dropped)" - echo "collisions.value $(cat /sys/class/net/$INTERFACE/statistics/collisions)" +if [ -r "/sys/class/net/$INTERFACE/statistics/rx_bytes" ]; then + echo "rcvd.value $(cat "/sys/class/net/$INTERFACE/statistics/rx_errors")" + echo "trans.value $(cat "/sys/class/net/$INTERFACE/statistics/tx_errors")" + echo "rxdrop.value $(cat "/sys/class/net/$INTERFACE/statistics/rx_dropped")" + echo "txdrop.value $(cat "/sys/class/net/$INTERFACE/statistics/tx_dropped")" + echo "collisions.value $(cat "/sys/class/net/$INTERFACE/statistics/collisions")" else awk -v interface="$INTERFACE" \ - 'BEGIN { gsub(/\./, "\\.", interface) } \ + 'BEGIN { gsub(/\./, "\\.", interface) } $1 ~ "^" interface ":" { - split($0, a, /: */); $0 = a[2]; \ - print "rcvd.value " $3 "\ntrans.value " $11; \ - print "rxdrop.value " $4 "\ntxdrop.value " $12; \ - print "collisions.value " $14; \ + split($0, a, /: */); $0 = a[2]; + print "rcvd.value " $3 "\ntrans.value " $11; + print "rxdrop.value " $4 "\ntxdrop.value " $12; + print "collisions.value " $14; }' \ /proc/net/dev fi diff -Nru munin-2.0.37/plugins/node.d.linux/if_.in munin-2.0.47/plugins/node.d.linux/if_.in --- munin-2.0.37/plugins/node.d.linux/if_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/if_.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,8 @@ #!@@BASH@@ # -*- sh -*- +set -e + : << =cut =head1 NAME @@ -64,9 +66,10 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" INTERFACE=${0##*if_} +speed=${speed:-} # Who whould have thought it's so much work to determine the # maximum speed of a network interface. Buckle up! @@ -75,13 +78,13 @@ # wifi drivers use "eth*" names. IWLIST=$(type -p iwlist) if [[ -x "$IWLIST" ]]; then - SPEED=$($IWLIST $INTERFACE rate 2>&1 | + SPEED=$("$IWLIST" "$INTERFACE" rate 2>&1 | awk 'BEGIN { RATE="U" } { if ($2 == "Mb/s") RATE=$1; } END { print RATE; }') if [[ "$SPEED" != "U" ]]; then - echo $SPEED + echo "$SPEED" return fi fi @@ -89,28 +92,28 @@ # sysfs can report the speed if the driver supports it (but it # doesn't work as well for wireless cards, thus why we check for # iwlist first) - if [[ -r /sys/class/net/$INTERFACE/speed ]]; then - SPEED=$(cat /sys/class/net/$INTERFACE/speed 2>/dev/null) + if [[ -r "/sys/class/net/$INTERFACE/speed" ]]; then + SPEED=$(cat "/sys/class/net/$INTERFACE/speed" 2>/dev/null) if [[ "$SPEED" -gt 0 ]]; then - echo $SPEED + echo "$SPEED" return fi fi ETHTOOL=$(type -p ethtool) if [[ -x "$ETHTOOL" ]]; then - SPEED=$($ETHTOOL $INTERFACE 2>&1 | + SPEED=$("$ETHTOOL" "$INTERFACE" 2>&1 | awk '/Speed:/ { gsub(/[^0-9]*/,"",$2); print $2; }') if [[ $SPEED == [0-9]* ]]; then - echo $SPEED + echo "$SPEED" return fi fi MIITOOL=$(type -p mii-tool) - if [[ -x $MIITOOL ]]; then - case $($MIITOOL $INTERFACE 2>&1) in + if [[ -x "$MIITOOL" ]]; then + case $("$MIITOOL" "$INTERFACE" 2>&1) in *1000base*) echo 1000; return ;; *100base*) echo 100; return ;; *10base*) echo 10; return ;; @@ -128,7 +131,7 @@ fi if [[ -z "$SPEED" ]] || [[ "$SPEED" == "U" ]]; then - printf "up.info Traffic of the %s interface. Unable to determine interface speed." $INTERFACE + printf "up.info Traffic of the %s interface. Unable to determine interface speed." "$INTERFACE" if [[ $EUID -ne 0 ]]; then echo " Please run the plugin as root." else @@ -138,7 +141,7 @@ return fi - BPS=$(( $SPEED * 1000 * 1000 )) + BPS=$(( SPEED * 1000 * 1000 )) cat < $name, - rio => $3, + rio => $3, rsect => $4, - wio => $5, + wio => $5, wsect => $6 }; } @@ -181,7 +181,7 @@ $tmpnam =~ s/^([^\/]+)\//$1/; $tmpnam =~ s/\/disc$//; - $devs{"dev".$major."_".&get_disk_count($major)} = + $devs{"dev".$major."_".&get_disk_count($major)} = { major => $major, name => $tmpnam, diff -Nru munin-2.0.37/plugins/node.d.linux/iostat_ios.in munin-2.0.47/plugins/node.d.linux/iostat_ios.in --- munin-2.0.37/plugins/node.d.linux/iostat_ios.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/iostat_ios.in 2019-02-28 14:43:36.000000000 +0000 @@ -3,7 +3,7 @@ =head1 NAME -iostat_ios - Show IO-operation latency pr. device. +iostat_ios - Show IO-operation latency per low-level block device. =head1 APPLICABLE SYSTEMS @@ -22,9 +22,9 @@ The plugin shows the average time a IO-operation needs to complete for each disk or block device on the system. -Simple partitioned disks will only show as the whole disk. When/if -you use some device layer over that, such as LVM then LV devices will -show up individualy. +Simple partitioned disks will only show as the whole disk. +LVM volumes, RAID devices and other derived block devices are not tracked +individually. When the IO-operation time here increases it is to be expected that the iowait on the CPU graph increases, but please read about how @@ -97,12 +97,16 @@ sub filter { my ($major, $minor, $tmpnam) = @_; + + # ignore derived logical block devices if(defined($major)) { return 0 if ($major == 1); # RAM devices return 0 if ($major == 9); # MD devices return 0 if ($major == 58); # LVM devices - return 0 if ($major == 254); # LVM2 devices + return 0 if ($major == 253); # LVM2 devices } + + # ignore partitions (ending in a digit) if(defined($tmpnam)) { return 0 if ($tmpnam =~ /part\d+$/); return 0 if ($tmpnam =~ /^\s*(?:sd|hd|x?vd)[a-z]\d+\s*$/); diff -Nru munin-2.0.37/plugins/node.d.linux/ip_.in munin-2.0.47/plugins/node.d.linux/ip_.in --- munin-2.0.37/plugins/node.d.linux/ip_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/ip_.in 2019-02-28 14:43:36.000000000 +0000 @@ -116,11 +116,12 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" IP=${0##*/ip_} INPUT=${input:-INPUT} OUTPUT=${output:-OUTPUT} +hostname=${hostname:-} case $IP in *:*) # I know this! This is IPv6! @@ -134,7 +135,7 @@ if [[ "$1" == "autoconf" ]]; then if [[ -r /proc/net/dev ]]; then - if ! iptables -L ${INPUT} -v -n -w -x >/dev/null 2>/dev/null; then + if ! iptables -L "$INPUT" -v -n -w -x >/dev/null 2>/dev/null; then echo "no (could not run iptables as user $(whoami))" exit 0 else @@ -148,9 +149,9 @@ fi if [[ "$1" == "suggest" ]]; then - iptables -L ${INPUT} -v -n -x -w 2>/dev/null | awk --posix '$8 ~ /^([0-9]{1,3}\.){3}[0-9]{1,3}$/ { if (done[$8]!=1) {print $8; done[$8]=1;}}' + iptables -L "$INPUT" -v -n -x -w 2>/dev/null | awk --posix '$8 ~ /^([0-9]{1,3}\.){3}[0-9]{1,3}$/ { if (done[$8]!=1) {print $8; done[$8]=1;}}' if [[ -x /sbin/ip6tables ]]; then - ip6tables -L ${INPUT} -v -n -x -w 2>/dev/null | awk --posix '$7 ~ /\/128$/ { if (done[$7]!=1) {a=$7;gsub(/\/128$/, "", a); print a; done[$7]=1;}}' + ip6tables -L "$INPUT" -v -n -x -w 2>/dev/null | awk --posix '$7 ~ /\/128$/ { if (done[$7]!=1) {a=$7;gsub(/\/128$/, "", a); print a; done[$7]=1;}}' fi exit 0 fi @@ -164,6 +165,7 @@ fi echo "graph_title $title traffic" echo 'graph_args --base 1000' + # shellcheck disable=SC2016 echo 'graph_vlabel bits per ${graph_period}' echo 'graph_category network' echo 'out.label sent' @@ -182,6 +184,6 @@ fi; # Escape .'s so they don't match _everything_? -IP=$(echo $IP | sed 's~\.~\\.~g') -iptables -L ${INPUT} -v -n -x -w | awk "/$IP"'[ /]/ { print "in.value " $2; exit 0; }' -iptables -L ${OUTPUT} -v -n -x -w | awk "/$IP"'[ /]/ { print "out.value " $2; exit 0; }' +escaped_ip=${IP//./\\.} +iptables -L "$INPUT" -v -n -x -w | awk "/$escaped_ip"'[ /]/ { print "in.value " $2; exit 0; }' +iptables -L "$OUTPUT" -v -n -x -w | awk "/$escaped_ip"'[ /]/ { print "out.value " $2; exit 0; }' diff -Nru munin-2.0.37/plugins/node.d.linux/irqstats.in munin-2.0.47/plugins/node.d.linux/irqstats.in --- munin-2.0.37/plugins/node.d.linux/irqstats.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/irqstats.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,9 @@ #!@@PERL@@ -w # -*- cperl -*- +use strict; +use warnings; + =head1 NAME irqstats - Munin plugin to monitor individual interrupts on a Linux machine @@ -50,14 +53,13 @@ =cut use Munin::Plugin; -use strict; if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') { if(-r '/proc/interrupts') { print "yes\n"; exit(0); } else { - print "no\n"; + print "no (file /proc/interrupts not readable)\n"; exit(1); } } diff -Nru munin-2.0.37/plugins/node.d.linux/load.in munin-2.0.47/plugins/node.d.linux/load.in --- munin-2.0.37/plugins/node.d.linux/load.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/load.in 2019-02-28 14:43:36.000000000 +0000 @@ -43,7 +43,7 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" if [ "$1" = "autoconf" ]; then echo yes diff -Nru munin-2.0.37/plugins/node.d.linux/meminfo.in munin-2.0.47/plugins/node.d.linux/meminfo.in --- munin-2.0.37/plugins/node.d.linux/meminfo.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/meminfo.in 2019-02-28 14:43:36.000000000 +0000 @@ -46,7 +46,7 @@ Low and high memory - subj :) Slab objects size - subj :) Slabs size [GroupName1] v - ... - show slabs size. I try split fields by this types. + ... - show slabs size. I try split fields by this types. Slabs size [GroupNameX] ^ Slabs sizes of groups - "Groups" sizes Slab objects - Active/inactive objects @@ -93,7 +93,7 @@ Default: undefined Examples: - + env.applications_group ^(firefox|chrome|opera|konqu|arora):Browsers;(^lx|openbox|menu|gnome|slim|^X):X;^(hal|console-kit|syslog|cron|dhcp|udev|dbus|bluetoo|agett|login|automount):System; And you can select time to display data after application close (all @@ -108,7 +108,7 @@ =head2 PERMISSIONS NOTE -Please check, can your munin user read files such as +Please check, can your munin user read files such as /proc/meminfo /proc/slabinfo @@ -128,7 +128,7 @@ You can set warning and critical levels for *each* of the data series the plugin reports. -Template for limits: +Template for limits: env.limit_%field% (warning_num:crytical_num|critical_num)[kMG] @@ -1426,7 +1426,7 @@ 'VmSwap' => 'AREA', 'VmHWM' => 'LINE2', 'VmPeak' => 'LINE2' - + }, 'color' => { @@ -1969,10 +1969,9 @@ sub append_formula_field { - my ($field_name, $formula, $label, $info) = @_[0..4]; + my ($field_name, $formula, $label, $info) = @_[0..3]; unless (exists($fields_source->{$field_name})) { - $name = "$formula" unless defined $name && $name ne ''; $fields_source->{$field_name} = { 'src' => { 'calculated' => $formula }, diff -Nru munin-2.0.37/plugins/node.d.linux/memory.in munin-2.0.47/plugins/node.d.linux/memory.in --- munin-2.0.37/plugins/node.d.linux/memory.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/memory.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,9 @@ #!@@PERL@@ -w # -*- perl -*- +use strict; +use warnings; + =head1 NAME memory - Plugin to monitor memory usage @@ -99,48 +102,61 @@ print "apps.label apps\n"; print "apps.draw AREA\n"; print "apps.info Memory used by user-space applications.\n"; + print "apps.colour COLOUR0\n"; print "buffers.label buffers\n"; print "buffers.draw STACK\n"; print "buffers.info Block device (e.g. harddisk) cache. ", "Also where \"dirty\" blocks are stored until written.\n"; + print "buffers.colour COLOUR5\n"; print "swap.label swap\n"; print "swap.draw STACK\n"; print "swap.info Swap space used.\n"; + # Fixed color for swap: red. Otherwise the above conditional fields could + # lead to color shifts due to changes of the kernel or other environment + # situations. + print "swap.colour COLOUR7\n"; print "cached.label cache\n"; print "cached.draw STACK\n"; print "cached.info Parked file data (file content) cache.\n"; + print "cached.colour COLOUR4\n"; print "free.label unused\n"; print "free.draw STACK\n"; print "free.info Wasted memory. Memory that is not ", "used for anything at all.\n"; + print "free.colour COLOUR6\n"; if (exists $mems{'Shmem'}) { print "shmem.label shmem\n"; print "shmem.draw STACK\n"; print "shmem.info Shared Memory (SYSV SHM segments, tmpfs).\n"; + print "shmem.colour COLOUR9\n"; } if (exists $mems{'Slab'}) { print "slab.label slab_cache\n"; print "slab.draw STACK\n"; print "slab.info Memory used by the kernel (major users ", " are caches like inode, dentry, etc).\n"; + print "slab.colour COLOUR3\n"; } if (exists $mems{'SwapCached'}) { print "swap_cache.label swap_cache\n"; print "swap_cache.draw STACK\n"; print "swap_cache.info A piece of memory that keeps track of pages ", "that have been fetched from swap but not yet been modified.\n"; + print "swap_cache.colour COLOUR2\n"; } if (exists $mems{'PageTables'}) { print "page_tables.label page_tables\n"; print "page_tables.draw STACK\n"; print "page_tables.info Memory used to map between virtual and ", - "physical memory addresses.\n" + "physical memory addresses.\n"; + print "page_tables.colour COLOUR1\n"; } if (exists $mems{'VmallocUsed'}) { print "vmalloc_used.label vmalloc_used\n"; # print "vmalloc_used.draw STACK\n"; print "vmalloc_used.draw LINE2\n"; - print "vmalloc_used.info 'VMalloc' (kernel) memory used\n" + print "vmalloc_used.info 'VMalloc' (kernel) memory used\n"; + print "vmalloc_used.colour COLOUR8\n"; } if (exists $mems{'Committed_AS'}) { print "committed.label committed\n"; @@ -153,51 +169,61 @@ # print "committed.warning ", $mems{'SwapTotal'} + $mems{'MemTotal'}, "\n"; print "committed.info The amount of memory allocated to programs. ", "Overcommitting is normal, but may indicate memory leaks.\n"; + print "committed.colour COLOUR10\n"; } if (exists $mems{'Mapped'}) { print "mapped.label mapped\n"; print "mapped.draw LINE2\n"; print "mapped.info All mmap()ed pages.\n"; + print "mapped.colour COLOUR11\n"; } if (exists $mems{'Active'}) { print "active.label active\n"; print "active.draw LINE2\n"; print "active.info Memory recently used. Not reclaimed unless ", "absolutely necessary.\n"; + print "active.colour COLOUR12\n"; } if (exists $mems{'ActiveAnon'}) { print "active_anon.label active_anon\n"; print "active_anon.draw LINE1\n"; + print "active_anon.colour COLOUR13\n"; } if (exists $mems{'ActiveCache'}) { print "active_cache.label active_cache\n"; print "active_cache.draw LINE1\n"; + print "active_cache.colour COLOUR14\n"; } if (exists $mems{'Inactive'}) { print "inactive.label inactive\n"; print "inactive.draw LINE2\n"; print "inactive.info Memory not currently used.\n"; + print "inactive.colour COLOUR15\n"; } if (exists $mems{'Inact_dirty'}) { print "inact_dirty.label inactive_dirty\n"; print "inact_dirty.draw LINE1\n"; print "inact_dirty.info Memory not currently used, but in need of ", "being written to disk.\n"; + print "inact_dirty.colour COLOUR16\n"; } if (exists $mems{'Inact_laundry'}) { print "inact_laundry.label inactive_laundry\n"; print "inact_laundry.draw LINE1\n"; + print "inact_laundry.colour COLOUR17\n"; } if (exists $mems{'Inact_clean'}) { print "inact_clean.label inactive_clean\n"; print "inact_clean.draw LINE1\n"; print "inact_clean.info Memory not currently used.\n"; + print "inact_clean.colour COLOUR18\n"; } if (exists $mems{'KSM'}) { print "ksm_sharing.label KSM sharing\n"; print "ksm_sharing.draw LINE2\n"; print "ksm_sharing.colour FFBFFF\n"; print "ksm_sharing.info Memory saved by KSM sharing\n"; + print "ksm_sharing.colour COLOUR19\n"; } for my $field (qw(apps buffers swap cached free slab swap_cache page_tables vmalloc_used committed mapped active active_anon active_cache inactive inact_dirty inact_laundry inact_clean shmem)) { my ($warning, $critical) = get_thresholds($field); diff -Nru munin-2.0.37/plugins/node.d.linux/netstat.in munin-2.0.47/plugins/node.d.linux/netstat.in --- munin-2.0.37/plugins/node.d.linux/netstat.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/netstat.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,8 @@ #!@@GOODSH@@ # -*- sh -*- +set -e + : << =cut =head1 NAME @@ -39,74 +41,78 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" + + +NETSTAT_CMD=netstat + if [ "$1" = "autoconf" ]; then - if ( netstat -s 2>/dev/null >/dev/null ); then - echo yes - exit 0 - else - if [ $? -eq 127 ] - then - echo "no (netstat program not found)" - exit 0 - else - echo no - exit 0 - fi - fi + if ( "$NETSTAT_CMD" -s 2>/dev/null >/dev/null ); then + echo yes + exit 0 + else + if [ $? -eq 127 ] + then + echo "no (program $NETSTAT_CMD not found)" + exit 0 + else + echo "no (unknown netstat return value $?)" + exit 0 + fi + fi fi if [ "$1" = "config" ]; then - echo 'graph_title Netstat' - echo 'graph_args --base 1000 --logarithmic' - echo 'graph_vlabel TCP connections' - echo 'graph_category network' - echo 'graph_period second' - echo 'graph_info This graph shows the TCP activity of all the network interfaces combined.' - echo 'active.label active' - echo 'active.type DERIVE' - echo 'active.max 50000' - echo 'active.min 0' - echo 'active.info The number of active TCP openings per second.' - print_warning active - print_critical active - echo 'passive.label passive' - echo 'passive.type DERIVE' - echo 'passive.max 50000' - echo 'passive.min 0' - echo 'passive.info The number of passive TCP openings per second.' - print_warning passive - print_critical passive - echo 'failed.label failed' - echo 'failed.type DERIVE' - echo 'failed.max 50000' - echo 'failed.min 0' - echo 'failed.info The number of failed TCP connection attempts per second.' - print_warning failed - print_critical failed - echo 'resets.label resets' - echo 'resets.type DERIVE' - echo 'resets.max 50000' - echo 'resets.min 0' - echo 'resets.info The number of TCP connection resets.' - print_warning resets - print_critical resets - echo 'established.label established' - echo 'established.type GAUGE' - echo 'established.max 50000' - echo 'established.info The number of currently open connections.' - print_warning established - print_critical established - exit 0 + echo 'graph_title Netstat' + echo 'graph_args --base 1000 --logarithmic' + echo 'graph_vlabel TCP connections' + echo 'graph_category network' + echo 'graph_period second' + echo 'graph_info This graph shows the TCP activity of all the network interfaces combined.' + echo 'active.label active' + echo 'active.type DERIVE' + echo 'active.min 0' + echo 'active.max 50000' + echo 'active.info The number of active TCP openings per second.' + print_warning active + print_critical active + echo 'passive.label passive' + echo 'passive.type DERIVE' + echo 'passive.min 0' + echo 'passive.max 50000' + echo 'passive.info The number of passive TCP openings per second.' + print_warning passive + print_critical passive + echo 'failed.label failed' + echo 'failed.type DERIVE' + echo 'failed.min 0' + echo 'failed.max 50000' + echo 'failed.info The number of failed TCP connection attempts per second.' + print_warning failed + print_critical failed + echo 'resets.label resets' + echo 'resets.type DERIVE' + echo 'resets.min 0' + echo 'resets.max 50000' + echo 'resets.info The number of TCP connection resets.' + print_warning resets + print_critical resets + echo 'established.label established' + echo 'established.type GAUGE' + echo 'established.max 50000' + echo 'established.info The number of currently open connections.' + print_warning established + print_critical established + exit 0 fi # Newer versions of net tools' netstat have fixed the 'active connection # openings' string from plural connections to singular. The match hereby is for # both cases. # -netstat -s | awk ' +"$NETSTAT_CMD" -s | awk ' /active connection(s)? ope/ { print "active.value " $1 } /passive connection ope/ { print "passive.value " $1 } /failed connection/ { print "failed.value " $1 } diff -Nru munin-2.0.37/plugins/node.d.linux/netstat_multi.in munin-2.0.47/plugins/node.d.linux/netstat_multi.in --- munin-2.0.37/plugins/node.d.linux/netstat_multi.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/netstat_multi.in 2019-02-28 14:43:36.000000000 +0000 @@ -1123,7 +1123,7 @@ foreach $key (sort keys %aspects) { my $val; - print "multigraph $key\n"; + unless ( defined($ARGV[0]) and $ARGV[0] eq 'autoconf' ) { print "multigraph $key\n"; } if ( defined($ARGV[0]) and $ARGV[0] eq 'config' ) { foreach (@graph_parameters) { if (!defined($aspects{$key}{$_})) { diff -Nru munin-2.0.37/plugins/node.d.linux/nfs4_client.in munin-2.0.47/plugins/node.d.linux/nfs4_client.in --- munin-2.0.37/plugins/node.d.linux/nfs4_client.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/nfs4_client.in 2019-02-28 14:43:36.000000000 +0000 @@ -32,8 +32,7 @@ if [ "$1" = "autoconf" ]; then if [ -f "$NFS" ]; then - grep -q proc4 "$NFS" - if [ $? = 0 ]; then + if grep -q proc4 "$NFS"; then echo yes else echo "no (no proc4 in $NFS)" @@ -49,6 +48,7 @@ echo 'graph_title NFSv4 Client' echo 'graph_args --base 1000 -l 0' + # shellcheck disable=SC2016 echo 'graph_vlabel requests / ${graph_period}' echo 'graph_total total' echo 'graph_category NFS' diff -Nru munin-2.0.37/plugins/node.d.linux/nfs_client.in munin-2.0.47/plugins/node.d.linux/nfs_client.in --- munin-2.0.37/plugins/node.d.linux/nfs_client.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/nfs_client.in 2019-02-28 14:43:36.000000000 +0000 @@ -32,8 +32,7 @@ if [ "$1" = "autoconf" ]; then if [ -f "$NFS" ]; then - grep -q proc3 "$NFS" - if [ $? = 0 ]; then + if grep -q proc3 "$NFS"; then echo yes else echo "no (no proc3 in $NFS)" @@ -49,6 +48,7 @@ echo 'graph_title NFS Client' echo 'graph_args --base 1000 -l 0' + # shellcheck disable=SC2016 echo 'graph_vlabel requests / ${graph_period}' echo 'graph_total total' echo 'graph_category NFS' diff -Nru munin-2.0.37/plugins/node.d.linux/nfsd4.in munin-2.0.47/plugins/node.d.linux/nfsd4.in --- munin-2.0.37/plugins/node.d.linux/nfsd4.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/nfsd4.in 2019-02-28 14:43:36.000000000 +0000 @@ -38,8 +38,7 @@ if [ "$1" = "autoconf" ]; then if [ -f "$NFSD" ]; then - grep -q proc4ops "$NFSD" - if [ $? = 0 ]; then + if grep -q proc4ops "$NFSD"; then echo yes else echo "no (no proc4ops in $NFSD)" @@ -60,6 +59,7 @@ echo 'graph_title NFSv4 Server' echo 'graph_args --base 1000 -l 0' + # shellcheck disable=SC2016 echo 'graph_vlabel requests / ${graph_period}' echo 'graph_total total' echo 'graph_category NFS' @@ -74,5 +74,5 @@ grep proc4ops $NFSD \ | cut -f $i -d ' ' \ | awk '{print $1}' - i=$(expr $i + 1) + i=$((i + 1)) done diff -Nru munin-2.0.37/plugins/node.d.linux/nfsd.in munin-2.0.47/plugins/node.d.linux/nfsd.in --- munin-2.0.37/plugins/node.d.linux/nfsd.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/nfsd.in 2019-02-28 14:43:36.000000000 +0000 @@ -33,7 +33,7 @@ if [ "$1" = "autoconf" ]; then if [ -f "$NFSD" ]; then grep -q proc3 "$NFSD" - if [ $? = 0 ]; then + if grep -q proc3 "$NFSD"; then echo yes else echo "no (no proc3 in $NFSD)" @@ -49,6 +49,7 @@ echo 'graph_title NFS Server' echo 'graph_args --base 1000 -l 0' + # shellcheck disable=SC2016 echo 'graph_vlabel requests / ${graph_period}' echo 'graph_total total' echo 'graph_category NFS' diff -Nru munin-2.0.37/plugins/node.d.linux/open_files.in munin-2.0.47/plugins/node.d.linux/open_files.in --- munin-2.0.37/plugins/node.d.linux/open_files.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/open_files.in 2019-02-28 14:43:36.000000000 +0000 @@ -26,7 +26,7 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" if [ "$1" = "autoconf" ]; then if [ -r /proc/sys/fs/file-nr ]; then @@ -51,8 +51,8 @@ computed_critical=$(awk '{printf "%d", $3*0.98}' < /proc/sys/fs/file-nr) p_warning=$(print_warning used) p_critical=$(print_critical used) - [ -z "$p_warning" ] && echo "used.warning $computed_warning" || echo $p_warning - [ -z "$p_critical" ] && echo "used.critical $computed_critical" || echo $p_critical + [ -z "$p_warning" ] && echo "used.warning $computed_warning" || echo "$p_warning" + [ -z "$p_critical" ] && echo "used.critical $computed_critical" || echo "$p_critical" echo 'max.label max open files' echo 'max.info The maximum supported number of open files. Tune by modifying /proc/sys/fs/file-max.' print_warning max diff -Nru munin-2.0.37/plugins/node.d.linux/open_inodes.in munin-2.0.47/plugins/node.d.linux/open_inodes.in --- munin-2.0.37/plugins/node.d.linux/open_inodes.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/open_inodes.in 2019-02-28 14:43:36.000000000 +0000 @@ -26,7 +26,7 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" if [ "$1" = "autoconf" ]; then if [ -r /proc/sys/fs/inode-nr ]; then diff -Nru munin-2.0.37/plugins/node.d.linux/proc.in munin-2.0.47/plugins/node.d.linux/proc.in --- munin-2.0.37/plugins/node.d.linux/proc.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/proc.in 2019-02-28 14:43:36.000000000 +0000 @@ -6,17 +6,17 @@ # # Author: Trygve Vea # Author: Kristian Lyngstøl -# +# # This program 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 program 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 program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. @@ -27,13 +27,13 @@ =head1 APPLICABLE SYSTEMS -Processes running under Linux for a longer timespan. +Processes running under Linux for a longer timespan. =head1 CONFIGURATION The plugin needs to be able to parse the /proc-filesystem. -The plugin is configured by supplying a pipe-delimitered list of parameters +The plugin is configured by supplying a pipe-delimitered list of parameters through environment variables. [proc] env.procname proc1|proc2|proc3 @@ -42,10 +42,10 @@ env.procaspect cpu|memory|ctxt_switches|threads|processes|io -env.procname defines the processname as seen inside the paranthesis of the +env.procname defines the processname as seen inside the paranthesis of the second column in /proc/pid/stat. If you don't get the data you expect, you -can check if the value is what you expect here. This is what's used for the -first filter, and args/user-filters are then applied on top of this filter. +can check if the value is what you expect here. This is what's used for the +first filter, and args/user-filters are then applied on top of this filter. env.procargs defines a string which is matched against the command line of the process. It's a wildcard match, so you don't have to provide the entire @@ -54,7 +54,7 @@ env.procuser defines the user the process has to run as. If nothing is provided, processes ran by any user are included. -env.procaspect defines which graphs to render. Per default, all graphs are +env.procaspect defines which graphs to render. Per default, all graphs are included. You don't have to set this unless you want to exclude graphs. =head1 INTERPRETATION @@ -89,8 +89,8 @@ =head1 THANKS -Thanks to Kristian Lyngstol, I stole most of the initial code in this plugin -from his varnish_-plugin, which is a really nice outline of how a +Thanks to Kristian Lyngstol, I stole most of the initial code in this plugin +from his varnish_-plugin, which is a really nice outline of how a wildcardplugin should look like. I've added some weird hacks to make it output multigraph. It's pretty ugly, but it works. @@ -140,13 +140,13 @@ 'colour', 'info', 'type', 'negative'); # Data structure that defines all possible graphs (aspects) and how they # are to be plotted. Every top-level entry is a graph/aspect. Each top-level graph -# MUST have title set and 'values'. -# +# MUST have title set and 'values'. +# # 'rpn' on values allows easy access to graphs consisting of multiple # values from procstats. (Reverse polish notation). The RPN # implementation only accepts +-*/ and procstats-values. # -# Any value left undefined will be left up to Munin to define/ignore/yell +# Any value left undefined will be left up to Munin to define/ignore/yell # about. # # See munin documentation or rrdgraph/rrdtool for more information. @@ -404,7 +404,7 @@ } # Walk through the relevant aspect and print all top-level configuration -# values and value-definitions. +# values and value-definitions. sub get_config { my $graph = $_[0]; @@ -550,7 +550,7 @@ } } -# Read and verify the aspect ($self). +# Read and verify the aspect ($self). sub set_aspect { $self = $0; @@ -651,7 +651,7 @@ foreach (@procname) { if ( $asp eq 'cpu' ) { print "$procuniq[$i].value " . - ($procstats{$procuniq[$i]}{'utime'} + + ($procstats{$procuniq[$i]}{'utime'} + $procstats{$procuniq[$i]}{'stime'})."\n"; } if ( $asp eq 'ctxt_switches' ) { diff -Nru munin-2.0.37/plugins/node.d.linux/proc_pri.in munin-2.0.47/plugins/node.d.linux/proc_pri.in --- munin-2.0.37/plugins/node.d.linux/proc_pri.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/proc_pri.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,8 @@ #!@@GOODSH@@ # -*- sh -*- +set -e + : << =cut =head1 NAME @@ -27,9 +29,14 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" +PS=$(which ps 2>/dev/null) || true if [ "$1" = "autoconf" ]; then + if ! [ -x "$PS" ]; then + echo "no (command ps not found)" + exit 0 + fi echo yes exit 0 fi @@ -60,8 +67,8 @@ fi echo -n "high.value " -ps --no-header -eo stat | grep \< | wc -l +"$PS" --no-header -eo stat | grep \< | wc -l echo -n "low.value " -ps --no-header -eo stat | grep N | wc -l +"$PS" --no-header -eo stat | grep N | wc -l echo -n "locked.value " -ps --no-header -eo stat | grep L | wc -l +"$PS" --no-header -eo stat | grep L | wc -l diff -Nru munin-2.0.37/plugins/node.d.linux/quota_usage_.in munin-2.0.47/plugins/node.d.linux/quota_usage_.in --- munin-2.0.37/plugins/node.d.linux/quota_usage_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/quota_usage_.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,26 +1,71 @@ #!@@PERL@@ # -# Plugin to monitor quota on a specified device. Needs repquota and root privs -# -# Usage: place in /etc/munin/node.d/quota-usage_ (or link it there using -# ln -s), for example quota-usage_hda3. Use underscores instead of slashes, for -# example to monitor /dev/mapper/vol-foo, name this quota-usage_mapper_vol-foo -# -# Parameters understood: -# -# config (required) -# -#%# family=manual + +=head1 NAME + +quota_usage_ - Plugin to monitor quota on a specified device. + +=head1 APPLICABLE SYSTEMS + +Needs repquota and root privs + +=head1 USAGE + +Create Service Link /etc/munin/plugins/quota_usage_ +for example C. Use underscores instead of slashes, for +example to monitor C, name this C + +For backwards compatibility the prefix C is also acceptable +(instead of C). + +This plugin uses the soft and hard quota data for warning and critical +levels respectively. + +=head1 MAGIC MARKERS + + #%# family=manual + +=head1 AUTHOR + +Unknown author + +Source: L + +L + +=head1 LICENSE + +GPLv2 + +=cut use strict; use warnings; use Munin::Plugin; +use File::Spec::Functions qw(splitdir); # We do some magic to allow device strings with underscore to mean a / -# So to monitor /dev/mapper/vol-foo use quota-usage_mapper_vol-foo -my @tmp = split(/_/, $0); -shift @tmp; -my $dev = join("/", @tmp); +# So to monitor /dev/mapper/vol-foo use "quota_usage_mapper_vol-foo" or +# "quota-usage_mapper_vol-foo". The latter was advertised as the default usage previously, but it +# is confusing since it does not match the name of the plugin exactly. +# See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=730030 +my @path_tokens = splitdir($0); +my $basename = $path_tokens[-1]; +# partial name of the device (it will be prefixed with "/dev/") +my $dev; +if ($basename =~ /^quota_usage_(.+)$/) { + # The plugin was called with the basename "quota_usage_*". + $dev = $1; + $dev =~ s#_#/#g; +} else { + # The plugin was called with the basename "quota-usage_*" (or another prefix without an + # underscore). + # This approach was documented for this plugin. But it conflicts with the common style of + # using the exact plugin name (instead of a slight variation) for symlinks. + my @tmp = split(/_/, $basename); + shift @tmp; + $dev = join("/", @tmp); +} my %users; open (REP, "/usr/sbin/repquota /dev/$dev |") or exit 22; @@ -28,7 +73,14 @@ chomp; if (/^-+$/../^$/) { my @data = split(/ +/); - $users{$data[0]} = $data[2] if (@data > 2 && $data[2] > 0); + + next if !$data[0] || $data[0] =~ /^#/; + + if ( @data > 2 && $data[2] > 0 ) { + $users{$data[0]}[0] = $data[2]; # current usage + $users{$data[0]}[1] = $data[3]; # Soft quota + $users{$data[0]}[2] = $data[4]; # Hard quota + } } } close REP; @@ -42,19 +94,28 @@ print "graph_category disk\n"; for my $user (@users_by_usage) { my ($uid, $name) = (getpwnam($user))[2,6]; + my $id = clean_fieldname($user); $name = $user if (length($name) < length($user)); - $user = clean_fieldname($user); $name = (split(/,/, $name))[0]; - printf "%s.label %s\n", $user, $name; - printf "%s.cdef %s,1024,*\n", $user, $user; - printf "%s.graph no\n", $user if ($uid < 1000); + + printf "%s.label %s\n", $id, $name; + printf "%s.cdef %s,1024,*\n", $id, $id; + + if ($users{$user}[1] && $users{$user}[1] > 0) { + printf "%s.warning %s\n", $id, $users{$user}[1]; + } + if ($users{$user}[2] && $users{$user}[2] > 0) { + printf "%s.critical %s\n", $id, $users{$user}[2]; + } + + if ($uid < 200) { + printf "%s.graph no\n", $id + } } } else { for my $user (@users_by_usage) { my $esc = $user; $esc = clean_fieldname($esc); - printf "%s.value %s\n", $esc, $users{$user}; + printf "%s.value %s\n", $esc, $users{$user}[0]; } } - -# vim: set ts=4 sw=4: diff -Nru munin-2.0.37/plugins/node.d.linux/selinux_avcstat.in munin-2.0.47/plugins/node.d.linux/selinux_avcstat.in --- munin-2.0.37/plugins/node.d.linux/selinux_avcstat.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/selinux_avcstat.in 2019-02-28 14:43:36.000000000 +0000 @@ -21,7 +21,7 @@ fi if [ "$1" = "autoconf" ]; then - if [ -r $AVCSTATS ]; then + if [ -r "$AVCSTATS" ]; then echo yes else echo "no (missing $AVCSTATS file)" @@ -88,17 +88,20 @@ exit 0 fi -if [ -r $AVCSTATS ]; then - { read HEADER - while read lookups hits misses allocations reclaims frees; do - LOOKUPS=$(($LOOKUPS + $lookups)) - HITS=$(($HITS + $hits)) - MISSES=$(($MISSES + $misses)) - ALLOCATIONS=$(($ALLOCATIONS + $allocations)) - RECLAIMS=$(($RECLAIMS + $reclaims)) - FREES=$(($FREES + $frees)) +if [ -r "$AVCSTATS" ]; then + { + # consume (and ignore) the header + # shellcheck disable=SC2034 + read -r HEADER + while read -r lookups hits misses allocations reclaims frees; do + LOOKUPS=$((LOOKUPS + lookups)) + HITS=$((HITS + hits)) + MISSES=$((MISSES + misses)) + ALLOCATIONS=$((ALLOCATIONS + allocations)) + RECLAIMS=$((RECLAIMS + reclaims)) + FREES=$((FREES + frees)) done - } < $AVCSTATS + } < "$AVCSTATS" echo "lookups.value $LOOKUPS" echo "hits.value $HITS" echo "misses.value $MISSES" diff -Nru munin-2.0.37/plugins/node.d.linux/sensors_.in munin-2.0.47/plugins/node.d.linux/sensors_.in --- munin-2.0.37/plugins/node.d.linux/sensors_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/sensors_.in 2019-02-28 14:43:36.000000000 +0000 @@ -42,7 +42,7 @@ =head1 MAGIC MARKERS - #%# family=manual + #%# family=auto #%# capabilities=autoconf suggest =cut diff -Nru munin-2.0.37/plugins/node.d.linux/swap.in munin-2.0.47/plugins/node.d.linux/swap.in --- munin-2.0.37/plugins/node.d.linux/swap.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/swap.in 2019-02-28 14:43:36.000000000 +0000 @@ -26,7 +26,7 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" if [ "$1" = "autoconf" ]; then if [ -r /proc/stat ]; then @@ -42,6 +42,7 @@ echo 'graph_title Swap in/out' echo 'graph_args -l 0 --base 1000' + # shellcheck disable=SC2016 echo 'graph_vlabel pages per ${graph_period} in (-) / out (+)' echo 'graph_category system' echo 'swap_in.label swap' @@ -62,7 +63,7 @@ fi if [ -f /proc/vmstat ]; then - awk '/pswpin/ { print "swap_in.value " $2 } /pswpout/ { print "swap_out.value " $2 }' < /proc/vmstat + awk '/pswpin/ { print "swap_in.value " $2 } /pswpout/ { print "swap_out.value " $2 }' < /proc/vmstat else - awk '/swap/ { print "swap_in.value " $2 "\nswap_out.value " $3 }' < /proc/stat + awk '/swap/ { print "swap_in.value " $2 "\nswap_out.value " $3 }' < /proc/stat fi diff -Nru munin-2.0.37/plugins/node.d.linux/tcp.in munin-2.0.47/plugins/node.d.linux/tcp.in --- munin-2.0.37/plugins/node.d.linux/tcp.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/tcp.in 2019-02-28 14:43:36.000000000 +0000 @@ -54,20 +54,20 @@ fin_wait2 time_wait close close_wait last_ack \ listen closing do - echo ${i}.label $i - echo ${i}.info Sockets in state $i + echo "${i}.label $i" + echo "${i}.info Sockets in state $i" done exit 0 ;; autoconf) - if [ -f /proc/net/tcp -o -f /proc/net/tcp6 ] + if [ -f /proc/net/tcp ] || [ -f /proc/net/tcp6 ] then echo yes exit 0 else echo no - exit 1 + exit 0 fi esac diff -Nru munin-2.0.37/plugins/node.d.linux/threads.in munin-2.0.47/plugins/node.d.linux/threads.in --- munin-2.0.37/plugins/node.d.linux/threads.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/threads.in 2019-02-28 14:43:36.000000000 +0000 @@ -2,6 +2,8 @@ # -*- sh -*- # vim: ft=sh +set -e + : << =cut =head1 NAME @@ -28,7 +30,7 @@ =cut if [ "$1" = "autoconf" ]; then - grep -q '^Threads' /proc/$$/status && echo "yes" || echo "no" + grep -q '^Threads' /proc/$$/status && echo "yes" || echo "no (/proc/$$/status not readable)" exit 0 fi @@ -43,8 +45,13 @@ exit 0 fi -# -s suppresses errors about files that vanished before they could -# be read. It isn't entirely portable, but GNU grep should be a given on -# Linux. Sadly awk has no such equivalent option or we could skip grep -# altogether -grep -s '^Threads' /proc/[0-9]*/status | awk '{ sum += $2; } END { print "threads.value", sum; }' +# Discard find's stderr, since SELinux or others may prevent us from parsing +# proc directories (e.g. "find: '/proc/fs/nfsd': Permission denied"). +# grep's -s suppresses errors about files that vanished before they could be +# read. It isn't entirely portable, but GNU grep should be a given on Linux. +# Sadly awk has no such equivalent option or we could skip grep altogether. +find /proc/ -mindepth 2 -maxdepth 2 -type f -name status -print0 2>/dev/null \ + | xargs -0 --no-run-if-empty --max-args=1000 grep -sh '^Threads:' \ + | awk 'BEGIN { sum = 0; } + { sum += $2; } + END { print "threads.value", sum; }' diff -Nru munin-2.0.37/plugins/node.d.linux/uptime.in munin-2.0.47/plugins/node.d.linux/uptime.in --- munin-2.0.37/plugins/node.d.linux/uptime.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/uptime.in 2019-02-28 14:43:36.000000000 +0000 @@ -26,7 +26,7 @@ =cut -. $MUNIN_LIBDIR/plugins/plugin.sh +. "$MUNIN_LIBDIR/plugins/plugin.sh" if [ "$1" = "autoconf" ]; then echo yes diff -Nru munin-2.0.37/plugins/node.d.linux/vlan_.in munin-2.0.47/plugins/node.d.linux/vlan_.in --- munin-2.0.37/plugins/node.d.linux/vlan_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/vlan_.in 2019-02-28 14:43:36.000000000 +0000 @@ -16,7 +16,7 @@ #%# family=manual #%# capabilities=autoconf suggest -INTERFACE=$(basename $0 | sed 's/^vlan_//g' | tr '_' '.') +INTERFACE=$(basename "$0" | sed 's/^vlan_//g' | tr '_' '.') if [ "$1" = "autoconf" ]; then if [ ! -d /proc/net/vlan ] ; then @@ -39,7 +39,7 @@ if [ "$1" = "suggest" ]; then for file in /proc/net/vlan/*; do if [ ! "$file" = "/proc/net/vlan/config" ]; then - basename $file | tr '.' '_' + basename "$file" | tr '.' '_' fi done exit 0 @@ -49,6 +49,7 @@ echo "graph_order received transmitted" echo "graph_title VLAN $INTERFACE Traffic" echo 'graph_args --base 1024' + # shellcheck disable=SC2016 echo 'graph_vlabel bits per ${graph_period} in (-) / out (+)' echo 'graph_category network' echo 'received.label bps' @@ -66,5 +67,4 @@ exit 0 fi -awk "/bytes received/ { print \"received.value \" \$4 } /bytes transmitted/ { print \"transmitted.value \" \$4 }" < /proc/net/vlan/$INTERFACE - +awk '/bytes received/ { print "received.value " $4 } /bytes transmitted/ { print "transmitted.value " $4 }' <"/proc/net/vlan/$INTERFACE" diff -Nru munin-2.0.37/plugins/node.d.linux/vlan_inetuse_.in munin-2.0.47/plugins/node.d.linux/vlan_inetuse_.in --- munin-2.0.37/plugins/node.d.linux/vlan_inetuse_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/vlan_inetuse_.in 2019-02-28 14:43:36.000000000 +0000 @@ -9,8 +9,8 @@ # The interface must also have an accounting iptables rules defined, _before_ # any action rules. E.g., in /etc/network/vlan-firewall.d/eth1-200-out, you # will find: -# -# --out-interface eth0 -p tcp --sport http +# +# --out-interface eth0 -p tcp --sport http # --out-interface eth0 -p tcp --sport smtp # --out-interface eth0 -p tcp --sport ssh # --out-interface eth0 -p tcp --sport domain @@ -96,65 +96,65 @@ if (@in_fields) { - push (@out , "$in.draw STACK\n"); + push (@out , "$in.draw STACK\n"); } else { - push (@out , "$in.draw AREA\n"); + push (@out , "$in.draw AREA\n"); } push (@in_fields, "$in"); - push (@out , "$in.label $label\n"); - push (@out , "$in.cdef $in,8,*\n"); - push (@out , "$in.graph no\n"); - push (@out , "$in.type DERIVE\n"); - push (@out , "$in.min 0\n"); + push (@out , "$in.label $label\n"); + push (@out , "$in.cdef $in,8,*\n"); + push (@out , "$in.graph no\n"); + push (@out , "$in.type DERIVE\n"); + push (@out , "$in.min 0\n"); if (@out_fields) { - push (@out , "$out.draw STACK\n"); + push (@out , "$out.draw STACK\n"); } else { - push (@out , "$out.draw AREA\n"); + push (@out , "$out.draw AREA\n"); } push (@out_fields, "$out"); - push (@out , "$out.label $label\n"); - push (@out , "$out.cdef $out,8,*\n"); - push (@out , "$out.negative $in\n"); - push (@out , "$out.type DERIVE\n"); - push (@out , "$out.min 0\n"); + push (@out , "$out.label $label\n"); + push (@out , "$out.cdef $out,8,*\n"); + push (@out , "$out.negative $in\n"); + push (@out , "$out.type DERIVE\n"); + push (@out , "$out.min 0\n"); } } if (@in_fields) { - push (@out , "in_other.draw STACK\n"); + push (@out , "in_other.draw STACK\n"); } else { - push (@out , "in_other.draw AREA\n"); + push (@out , "in_other.draw AREA\n"); } push (@in_fields, "in_other"); - push (@out , "in_other.label other\n"); - push (@out , "in_other.cdef in_other,8,*\n"); - push (@out , "in_other.graph no\n"); - push (@out , "in_other.type DERIVE\n"); - push (@out , "in_other.min 0\n"); + push (@out , "in_other.label other\n"); + push (@out , "in_other.cdef in_other,8,*\n"); + push (@out , "in_other.graph no\n"); + push (@out , "in_other.type DERIVE\n"); + push (@out , "in_other.min 0\n"); if (@out_fields) { - push (@out , "out_other.draw STACK\n"); + push (@out , "out_other.draw STACK\n"); } else { - push (@out , "out_other.draw AREA\n"); + push (@out , "out_other.draw AREA\n"); } push (@out_fields, "out_other"); - push (@out , "out_other.label other\n"); - push (@out , "out_other.cdef out_other,8,*\n"); - push (@out , "out_other.negative in_other\n"); - push (@out , "out_other.type DERIVE\n"); - push (@out , "out_other.min 0\n"); + push (@out , "out_other.label other\n"); + push (@out , "out_other.cdef out_other,8,*\n"); + push (@out , "out_other.negative in_other\n"); + push (@out , "out_other.type DERIVE\n"); + push (@out , "out_other.min 0\n"); print "graph_order ", join (' ', @in_fields, @out_fields), "\n"; diff -Nru munin-2.0.37/plugins/node.d.linux/vlan_linkuse_.in munin-2.0.47/plugins/node.d.linux/vlan_linkuse_.in --- munin-2.0.37/plugins/node.d.linux/vlan_linkuse_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/vlan_linkuse_.in 2019-02-28 14:43:36.000000000 +0000 @@ -8,8 +8,8 @@ # # The interface must also have an accounting iptables rule defined, _before_ # any action rules. E.g., in /etc/network/vlan-firewall.d/eth1-200-out, you -# will find: -# +# will find: +# # --out-interface eth0 # # ...which will make the out-traffic graphable. (Both in and out-files must @@ -45,11 +45,11 @@ print "graph_args --base 1000\n"; print "graph_category network\n"; print "graph_vlabel bits per \${graph_period} in (-) / out (+)\n"; - print "in.label bps\n"; - print "in.cdef in,8,*\n"; - print "in.graph no\n"; - print "in.type DERIVE\n"; - print "in.min 0\n"; + print "in.label bps\n"; + print "in.cdef in,8,*\n"; + print "in.graph no\n"; + print "in.type DERIVE\n"; + print "in.min 0\n"; } else { @@ -71,11 +71,11 @@ next unless (($proto eq "all") and (!$comment)); if ($ARGV[0] and $ARGV[0] eq "config") { - print "out.label bps\n"; - print "out.cdef out,8,*\n"; - print "out.negative in\n"; - print "out.type DERIVE\n"; - print "out.min 0\n"; + print "out.label bps\n"; + print "out.cdef out,8,*\n"; + print "out.negative in\n"; + print "out.type DERIVE\n"; + print "out.min 0\n"; } else { diff -Nru munin-2.0.37/plugins/node.d.linux/vserver_cpu_.in munin-2.0.47/plugins/node.d.linux/vserver_cpu_.in --- munin-2.0.37/plugins/node.d.linux/vserver_cpu_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/vserver_cpu_.in 2019-02-28 14:43:36.000000000 +0000 @@ -117,84 +117,90 @@ # fi -VSERVERS="$vservers" +VSERVERS="${vservers:-}" -INFO=(`sed 's/.*:\t//' /proc/virtual/info 2>/dev/null || echo ''`) -KCIN="$[ 16#${INFO[2]} ]"; +# shellcheck disable=SC2207 +INFO=($(sed 's/.*:\t//' /proc/virtual/info 2>/dev/null || echo '')) +KCIN=$(( 16#${INFO[2]} )) # If this is 1, then VCI_SPACES is present in the kernel (new in 2.6.19) -if [ $[ (KCIN >> 10) & 1 ] -eq 1 ] -then +if [ $(( (KCIN >> 10) & 1 )) -eq 1 ] +then NAMELOC="nsproxy" -else +else NAMELOC="cvirt" fi if [ -z "$VSERVERS" ] ; then - XIDS=`find /proc/virtual/* -type d -exec basename {} \;` + XIDS=$(find /proc/virtual/* -type d -exec basename {} \;) else # it's really more performant to specify vservers by ids or by linking but not in the configuration-file by name XIDS="" for i in $VSERVERS ; do - if [ -d /proc/virtual/$i ] ; then - XIDS="${XIDS}${i} " - else - for j in `find /proc/virtual/* -type d -exec basename {} \;` ; do - if [ "$i" = "`cat /proc/virtual/$j/$NAMELOC |grep NodeName |cut -f2`" ] ; then - XIDS="${XIDS}${j} " - fi - done - fi + if [ -d "/proc/virtual/$i" ]; then + XIDS="${XIDS}${i} " + else + # shellcheck disable=SC2044 + for j in $(find /proc/virtual/* -type d -exec basename {} \;); do + if [ "$i" = "$(grep "NodeName" "/proc/virtual/$j/$NAMELOC" | cut -f 2)" ] ; then + XIDS="${XIDS}${j} " + fi + done + fi done fi if [ "$1" = "suggest" ]; then if [ -r /proc/virtual/info ]; then for i in $XIDS ; do - LABEL=`cat /proc/virtual/$i/$NAMELOC |grep NodeName |cut -f2` - echo $LABEL + LABEL=$(grep "NodeName" "/proc/virtual/$i/$NAMELOC" | cut -f 2) + echo "$LABEL" done exit 0 fi fi -BASEPARAM=`basename $0 | sed 's/^vserver_//'` -MODE=`echo $BASEPARAM | sed 's/^hold.*//'` +# shellcheck disable=SC2001 +BASEPARAM=$(basename "$0" | sed 's/^vserver_//') +# shellcheck disable=SC2001 +MODE=$(echo "$BASEPARAM" | sed 's/^hold.*//') -#debug=true +debug=${debug:-} if [ -z "$MODE" ] ; then MODE=hold - TARGET=`echo $BASEPARAM | sed 's/^hold_//'` -else + # shellcheck disable=SC2001 + TARGET=$(echo "$BASEPARAM" | sed 's/^hold_//') +else MODE=cpu - TARGET=`echo $BASEPARAM | sed 's/^cpu_//'` + # shellcheck disable=SC2001 + TARGET=$(echo "$BASEPARAM" | sed 's/^cpu_//') fi CPU1=0 if [ -n "$TARGET" ] ; then - if [ "${#TARGET}" == 1 ] ; then - if [ $debug ] ; then echo $MODE, only on cpu $TARGET, for all vservers ; fi + if [ "${#TARGET}" == 1 ] ; then + if [ -n "$debug" ]; then echo "$MODE, only on cpu $TARGET, for all vservers"; fi WHAT=ALLVSERVER CPU1=$TARGET - else - if [ $debug ] ; then echo $MODE on all cpus together, only for vserver $TARGET ; fi + else + if [ -n "$debug" ]; then echo "$MODE on all cpus together, only for vserver $TARGET"; fi WHAT=VSERVER fi else - if [ $debug ] ; then echo $MODE for all cpus, for all vservers ; fi + if [ -n "$debug" ] ; then echo "$MODE for all cpus, for all vservers"; fi WHAT=ALLVSERVER fi -CPUS=$[ `grep ^processor /proc/cpuinfo|wc -l` -1 ] -CPUS=`seq $CPU1 $CPUS` +CPUS=$(( $(grep ^processor /proc/cpuinfo | wc -l) - 1 )) +CPUS=$(seq "$CPU1" "$CPUS") -if [ $debug ] ; then - echo cpus= $CPUS - echo baseparam= $BASEPARAM - echo mode= $MODE - echo target= $TARGET - echo what= $WHAT +if [ -n "$debug" ] ; then + echo "cpus= $CPUS" + echo "baseparam= $BASEPARAM" + echo "mode= $MODE " + echo "target= $TARGET" + echo "what= $WHAT" fi if [ "$1" = "config" ]; then @@ -202,29 +208,31 @@ echo 'graph_args --base 1000' if [ "$MODE" == "cpu" ] ; then echo 'graph_title Vserver cpu usage' + # shellcheck disable=SC2016 echo 'graph_vlabel jiffies used per cpu per ${graph_period}' echo 'graph_info Shows jiffies used per cpu on each vserver.' else echo 'graph_title Vserver cpu on hold' + # shellcheck disable=SC2016 echo 'graph_vlabel jiffies on hold per cpu per ${graph_period}' echo 'graph_info Shows jiffies on hold used per cpu on each vserver.' fi - for j in $CPUS ; do + for j in $CPUS ; do A=0 - for i in $XIDS ; do - LABEL=`cat /proc/virtual/$i/$NAMELOC |grep NodeName |cut -f2` + for i in $XIDS ; do + LABEL=$(grep "NodeName" "/proc/virtual/$i/$NAMELOC" | cut -f 2) if [ "$WHAT" == "ALLVSERVER" ] || [ "$TARGET" == "$LABEL" ] ; then - NAME=`echo $LABEL | cut -d. -f1 | tr '-' '_'` + NAME=$(echo "$LABEL" | cut -d. -f1 | tr '-' '_') if [ "$MODE" == "cpu" ] ; then echo "${NAME}_$j.label cpu usage for cpu $j on $LABEL" echo "${NAME}_$j.info cpu usage for cpu $j on $LABEL." - else + else echo "${NAME}_$j.label on hold for cpu $j on $LABEL" echo "${NAME}_$j.info on hold for cpu $j on $LABEL." fi echo "${NAME}_$j.type COUNTER" - if [ "$A" == 0 ] ; then + if [ "$A" == 0 ] ; then echo "${NAME}_$j.draw AREA" A=1 else @@ -236,19 +244,19 @@ exit 0 fi -for j in $CPUS ; do +for j in $CPUS ; do for i in $XIDS ; do - LABEL=`cat /proc/virtual/$i/$NAMELOC |grep NodeName |cut -f2` + LABEL=$(grep "NodeName" "/proc/virtual/$i/$NAMELOC" | cut -f 2) if [ "$WHAT" == "ALLVSERVER" ] || [ "$TARGET" == "$LABEL" ] ; then - NAME=`echo $LABEL | cut -d. -f1 | tr '-' '_'` + NAME=$(echo "$LABEL" | cut -d. -f1 | tr '-' '_') echo -n "${NAME}_$j.value " if [ "$MODE" == "cpu" ] ; then - USERCPU=`cat /proc/virtual/$i/sched |grep "cpu $j:"| cut -d' ' -f3` - SYSCPU=`cat /proc/virtual/$i/sched |grep "cpu $j:"| cut -d' ' -f4` - echo $[$USERCPU + $SYSCPU] + USERCPU=$(grep "cpu $j:" "/proc/virtual/$i/sched" | cut -d' ' -f 3) + SYSCPU=$(grep "cpu $j:" "/proc/virtual/$i/sched" | cut -d' ' -f 4) + echo $((USERCPU + SYSCPU)) else - cat /proc/virtual/$i/sched |grep "cpu $j:"| cut -d' ' -f5 + grep "cpu $j:" "/proc/virtual/$i/sched" | cut -d ' ' -f 5 fi - fi + fi done done diff -Nru munin-2.0.37/plugins/node.d.linux/vserver_loadavg.in munin-2.0.47/plugins/node.d.linux/vserver_loadavg.in --- munin-2.0.37/plugins/node.d.linux/vserver_loadavg.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/vserver_loadavg.in 2019-02-28 14:43:36.000000000 +0000 @@ -76,39 +76,41 @@ fi # if vservers are specified, use them; the default is to use all. -VSERVERS="$vservers" +VSERVERS="${vservers:-}" -INFO=(`sed 's/.*:\t//' /proc/virtual/info 2>/dev/null || echo ''`) -KCIN="$[ 16#${INFO[2]} ]"; +# shellcheck disable=SC2207 +INFO=($(sed 's/.*:\t//' /proc/virtual/info 2>/dev/null || echo '')) +KCIN=$(( 16#${INFO[2]} )) # If this is 1, then VCI_SPACES is present in the kernel (new in 2.6.19) -if [ $[ (KCIN >> 10) & 1 ] -eq 1 ] -then +if [ $(( (KCIN >> 10) & 1 )) -eq 1 ] +then NAMELOC="nsproxy" -else +else NAMELOC="cvirt" fi if [ -z "$VSERVERS" ] ; then - XIDS=`find /proc/virtual/* -type d -exec basename {} \;` + XIDS=$(find /proc/virtual/* -type d -exec basename {} \;) else # it's really more performant to specify vservers by ids or not at all XIDS="" for i in $VSERVERS ; do - if [ -d /proc/virtual/$i ] ; then - XIDS="${XIDS}${i} " - else - for j in `find /proc/virtual/* -type d -exec basename {} \;` ; do - if [ "$i" = "`cat /proc/virtual/$j/$NAMELOC |grep NodeName |cut -f2`" ] ; then - XIDS="${XIDS}${j} " - fi - done - fi + if [ -d "/proc/virtual/$i" ] ; then + XIDS="${XIDS}${i} " + else + # shellcheck disable=SC2044 + for j in $(find /proc/virtual/* -type d -exec basename {} \;); do + if [ "$i" = "$(grep "NodeName" "/proc/virtual/$j/$NAMELOC" | cut -f 2)" ] ; then + XIDS="${XIDS}${j} " + fi + done + fi done fi - + # If run with the "config"-parameter, give out information on how the -# graphs should look. +# graphs should look. if [ "$1" = "config" ]; then # The title of the graph echo 'graph_title loadavg of vserver' @@ -126,19 +128,19 @@ echo 'graph_category vserver' for xid in $XIDS ; do # Specify the vservers - LABEL=`cat /proc/virtual/$xid/$NAMELOC |grep NodeName |cut -f2` - NAME=`echo $LABEL | cut -d. -f1 | tr '-' '_'` + LABEL=$(grep "NodeName" "/proc/virtual/$xid/$NAMELOC" | cut -f 2) + NAME=$(echo "$LABEL" | cut -d. -f1 | tr '-' '_') echo "$NAME.label $LABEL: load average" echo "$NAME.info $NAME average load for the past 5 minutes" - done + done # Last, if run with the "config"-parameter, quit here (don't # display any data) exit 0 fi for xid in $XIDS ; do - LABEL=`cat /proc/virtual/$xid/$NAMELOC |grep NodeName |cut -f2` - NAME=`echo $LABEL | cut -d. -f1 | tr '-' '_'` - echo -n "$NAME.value "; - cat /proc/virtual/$xid/cvirt | grep loadavg: | cut -d' ' -f2 + LABEL=$(grep "NodeName" "/proc/virtual/$xid/$NAMELOC" | cut -f 2) + NAME=$(echo "$LABEL" | cut -d. -f1 | tr '-' '_') + echo -n "$NAME.value " + grep "loadavg:" "/proc/virtual/$xid/cvirt" | cut -d ' ' -f 2 done diff -Nru munin-2.0.37/plugins/node.d.linux/vserver_resources.in munin-2.0.47/plugins/node.d.linux/vserver_resources.in --- munin-2.0.37/plugins/node.d.linux/vserver_resources.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.linux/vserver_resources.in 2019-02-28 14:43:36.000000000 +0000 @@ -55,7 +55,7 @@ [vserver_resources] user root - env.vservers vserver5 + env.vservers vserver5 env.resource ALL env.limits 0 @@ -180,36 +180,38 @@ exit 0 fi -VSERVERS="$vservers" -LIMITS="$limits" -RESOURCE="$resource" - -INFO=(`sed 's/.*:\t//' /proc/virtual/info 2>/dev/null || echo ''`) -KCIN="$[ 16#${INFO[2]} ]"; +VSERVERS="${vservers:-}" +LIMITS="${limits:-}" +RESOURCE="${resource:-}" + +# shellcheck disable=SC2207 +INFO=($(sed 's/.*:\t//' /proc/virtual/info 2>/dev/null || echo '')) +KCIN=$(( 16#${INFO[2]} )) # If this is 1, then VCI_SPACES is present in the kernel (new in 2.6.19) -if [ $[ (KCIN >> 10) & 1 ] -eq 1 ] -then +if [ $(( (KCIN >> 10) & 1 )) -eq 1 ] +then NAMELOC="nsproxy" -else +else NAMELOC="cvirt" fi if [ -z "$VSERVERS" ] ; then - XIDS=`find /proc/virtual/* -type d -exec basename {} \;` + XIDS=$(find /proc/virtual/* -type d -exec basename {} \;) else # it's really more performant to specify vservers by ids or not at all XIDS="" for i in $VSERVERS ; do - if [ -d /proc/virtual/$i ] ; then - XIDS="${XIDS}${i} " - else - for j in `find /proc/virtual/* -type d -exec basename {} \;` ; do - if [ "$i" = "`cat /proc/virtual/$j/$NAMELOC |grep NodeName |cut -f2`" ] ; then - XIDS="${XIDS}${j} " - fi - done - fi + if [ -d "/proc/virtual/$i" ] ; then + XIDS="${XIDS}${i} " + else + # shellcheck disable=SC2044 + for j in $(find /proc/virtual/* -type d -exec basename {} \;) ; do + if [ "$i" = "$(grep "NodeName" "/proc/virtual/$j/$NAMELOC" | cut -f 2)" ]; then + XIDS="${XIDS}${j} " + fi + done + fi done fi @@ -288,14 +290,14 @@ esac echo 'graph_category vserver' - + # do not assume we are on i386 where pagesize is 4096... - pagesize=`perl -MPOSIX -e 'print POSIX::sysconf(_SC_PAGESIZE), "\n";'` - + pagesize=$(perl -MPOSIX -e 'print POSIX::sysconf(_SC_PAGESIZE), "\n";') + for xid in $XIDS ; do - - LABEL=`cat /proc/virtual/$xid/$NAMELOC |grep NodeName |cut -f2` - NAME=`echo $LABEL | cut -d. -f1 | tr '-' '_'` + + LABEL=$(grep "NodeName" "/proc/virtual/$xid/$NAMELOC" | cut -f 2) + NAME=$(echo "$LABEL" | cut -d. -f1 | tr '-' '_') case "$RESOURCE" in PROC) @@ -352,10 +354,10 @@ exit 1 ;; esac - - if [ ! -z "$LIMITS" -a "$LIMITS" = 1 ]; then - LIMIT=`cat /proc/virtual/$xid/limit | grep $RESOURCE | cut -f4` - if [ ${LIMIT:-0} -gt 0 ]; then + + if [ -n "$LIMITS" ] && [ "$LIMITS" = 1 ]; then + LIMIT=$(grep "$RESOURCE" "/proc/virtual/$xid/limit" | cut -f 4) + if [ "${LIMIT:-0}" -gt 0 ]; then echo "$NAME.critical $LIMIT" fi fi @@ -365,10 +367,10 @@ for xid in $XIDS ; do - LABEL=`cat /proc/virtual/$xid/$NAMELOC |grep NodeName |cut -f2` - NAME=`echo $LABEL | cut -d. -f1 | tr '-' '_'` - cat /proc/virtual/$xid/limit | awk -v name="${NAME}" -v resource="${RESOURCE}:" \ - '{ if ( $1 == resource ) - printf "%s.value %d\n", name, $2 }' + LABEL=$(grep "NodeName" "/proc/virtual/$xid/$NAMELOC" | cut -f 2) + NAME=$(echo "$LABEL" | cut -d. -f1 | tr '-' '_') + awk -v name="${NAME}" -v resource="${RESOURCE}:" \ + '{ if ( $1 == resource ) printf "%s.value %d\n", name, $2 }' \ + "/proc/virtual/$xid/limit" done diff -Nru munin-2.0.37/plugins/node.d.netbsd/cpu.in munin-2.0.47/plugins/node.d.netbsd/cpu.in --- munin-2.0.37/plugins/node.d.netbsd/cpu.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/cpu.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/sh +#!@@GOODSH@@ # # Plugin to monitor CPU usage. # @@ -78,8 +78,8 @@ echo 'system.max 5000' echo 'system.type DERIVE' echo 'system.min 0' -# echo "system.warning $SYSWARNING" -# echo "system.critical $SYSCRITICAL" +# echo "system.warning $SYSWARNING" +# echo "system.critical $SYSCRITICAL" echo 'system.info CPU time spent by the kernel in system activities' echo "system.cdef system,$CDEF" diff -Nru munin-2.0.37/plugins/node.d.netbsd/df.in munin-2.0.47/plugins/node.d.netbsd/df.in --- munin-2.0.37/plugins/node.d.netbsd/df.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/df.in 2019-02-28 14:43:36.000000000 +0000 @@ -41,10 +41,10 @@ /bin/df -P -t $TYPES | tail +2 | grep -v "//" | while read i; do case $i in mfs:*) name=mfs$mfs; mfs=`expr $mfs + 1`;; - *) name=`echo $i | awk '{ gsub("[^a-zA-Z0-9_]", "_", $1); print $1 }'` ;; + *) name=`echo "$i" | awk '{ gsub("[^a-zA-Z0-9_]", "_", $1); print $1 }'` ;; esac echo -n "$name.label " - echo $i | awk '{ print $6 }' + echo "$i" | awk '{ print $6 }' echo "$name.warning ${warning:-92}" echo "$name.critical ${critical:-98}" done @@ -55,8 +55,8 @@ /bin/df -P -t $TYPES | tail +2 | grep -v "//" | while read i; do case $i in mfs:*) name=mfs$mfs; mfs=`expr $mfs + 1`;; - *) name=`echo $i | awk '{ gsub("[^a-zA-Z0-9_]", "_", $1); print $1 }'` ;; + *) name=`echo "$i" | awk '{ gsub("[^a-zA-Z0-9_]", "_", $1); print $1 }'` ;; esac echo -n "$name.value " - echo $i | awk '{ print $5 }' | cut -f1 -d% + echo "$i" | awk '{ print $5 }' | cut -f1 -d% done diff -Nru munin-2.0.37/plugins/node.d.netbsd/df_inode.in munin-2.0.47/plugins/node.d.netbsd/df_inode.in --- munin-2.0.37/plugins/node.d.netbsd/df_inode.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/df_inode.in 2019-02-28 14:43:36.000000000 +0000 @@ -8,7 +8,7 @@ # autoconf (optional - used by munin-config) # # $Id$ -# +# # Magic markers (optional - used by munin-config and installation # scripts): # @@ -23,12 +23,12 @@ while read i; do case $i in mfs:*) name=mfs$mfs; mfs=`expr $mfs + 1`;; - *) name=`echo $i | awk '{ + *) name=`echo "$i" | awk '{ gsub("[^a-zA-Z0-9_]", "_", $1); print $1 }'` ;; esac echo -n "$name.value " - echo $i | awk '{ print $8 }' | cut -f1 -d% + echo "$i" | awk '{ print $8 }' | cut -f1 -d% done } diff -Nru munin-2.0.37/plugins/node.d.netbsd/forks.in munin-2.0.47/plugins/node.d.netbsd/forks.in --- munin-2.0.37/plugins/node.d.netbsd/forks.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/forks.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/sh +#!@@GOODSH@@ # # Plugin to monitor the number of forks per second on the machine. # @@ -31,7 +31,7 @@ if [ "$1" = "autoconf" ]; then if [ -x /usr/bin/vmstat ]; then - echo yes + echo yes exit 0 else echo "no (no /usr/bin/vmstat executable)" diff -Nru munin-2.0.37/plugins/node.d.netbsd/if_errcoll_.in munin-2.0.47/plugins/node.d.netbsd/if_errcoll_.in --- munin-2.0.37/plugins/node.d.netbsd/if_errcoll_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/if_errcoll_.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/sh +#!@@GOODSH@@ # # Wildcard-plugin to monitor network interfaces. To monitor an # interface, link if_ to this file. E.g. diff -Nru munin-2.0.37/plugins/node.d.netbsd/if_.in munin-2.0.47/plugins/node.d.netbsd/if_.in --- munin-2.0.37/plugins/node.d.netbsd/if_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/if_.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/sh +#!@@GOODSH@@ # # Wildcard-plugin to monitor network interfaces. To monitor an # interface, link if_ to this file. E.g. @@ -53,7 +53,7 @@ if [ "$1" = "config" ]; then - echo "graph_order rbytes obytes" + echo "graph_order rbytes obytes" echo "graph_title $INTERFACE traffic" echo 'graph_args --base 1000' echo 'graph_vlabel bits per ${graph_period} in (-) / out (+)' @@ -61,12 +61,12 @@ echo "graph_info This graph shows the traffic of the $INTERFACE network interface. Please note that the traffic is shown in bits per second, not bytes." echo 'rbytes.label received' - echo 'rbytes.type DERIVE' - echo 'rbytes.graph no' - echo 'rbytes.cdef rbytes,8,*' + echo 'rbytes.type DERIVE' + echo 'rbytes.graph no' + echo 'rbytes.cdef rbytes,8,*' echo 'rbytes.min 0' - echo 'obytes.label bps' + echo 'obytes.label bps' echo 'obytes.type DERIVE' echo 'obytes.negative rbytes' echo 'obytes.cdef obytes,8,*' diff -Nru munin-2.0.37/plugins/node.d.netbsd/interrupts.in munin-2.0.47/plugins/node.d.netbsd/interrupts.in --- munin-2.0.37/plugins/node.d.netbsd/interrupts.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/interrupts.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,6 +1,6 @@ -#!/bin/sh -# -# Plugin to monitor the number of interrupts and context switches on a system. +#!@@GOODSH@@ +# +# Plugin to monitor the number of interrupts and context switches on a system. # # Idea and base from Ragnar Wisløff. # @@ -37,8 +37,8 @@ fi # If run with the "config"-parameter, give out information on how the -# graphs should look. - +# graphs should look. + if [ "$1" = "config" ]; then # The title of the graph echo 'graph_title Interrupts & context switches' @@ -59,7 +59,7 @@ echo 'ctx.info A context switch occurs when a multitasking operatings system suspends the currently running process, and starts executing another.' # The fields. "label" is used in the legend. "label" is the only - # required subfield. + # required subfield. echo 'devint.label device interrupts' echo 'softint.label software interrupts' echo 'ctx.label context switches' diff -Nru munin-2.0.37/plugins/node.d.netbsd/iostat.in munin-2.0.47/plugins/node.d.netbsd/iostat.in --- munin-2.0.37/plugins/node.d.netbsd/iostat.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/iostat.in 2019-02-28 14:43:36.000000000 +0000 @@ -28,7 +28,7 @@ if [ "$1" = "autoconf" ]; then if [ -x /usr/sbin/iostat ]; then - echo yes + echo yes exit 0 else echo "no (no /usr/sbin/iostat executable)" diff -Nru munin-2.0.37/plugins/node.d.netbsd/iostat_ops.in munin-2.0.47/plugins/node.d.netbsd/iostat_ops.in --- munin-2.0.37/plugins/node.d.netbsd/iostat_ops.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/iostat_ops.in 2019-02-28 14:43:36.000000000 +0000 @@ -30,7 +30,7 @@ if [ "$1" = "autoconf" ]; then if [ -x /usr/sbin/iostat ]; then - echo yes + echo yes exit 0 else echo "no (no /usr/sbin/iostat executable)" diff -Nru munin-2.0.37/plugins/node.d.netbsd/irqstats.in munin-2.0.47/plugins/node.d.netbsd/irqstats.in --- munin-2.0.37/plugins/node.d.netbsd/irqstats.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/irqstats.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,5 +1,5 @@ -#! /bin/sh -# +#!@@GOODSH@@ +# # Plugin to monitor the individual interrupt sources. # # Usage: Link or copy into /etc/munin/node.d/ @@ -48,8 +48,8 @@ } # If run with the "config"-parameter, give out information on how the -# graphs should look. - +# graphs should look. + if [ "$1" = "config" ]; then echo 'graph_title Individual interrupts' diff -Nru munin-2.0.37/plugins/node.d.netbsd/load.in munin-2.0.47/plugins/node.d.netbsd/load.in --- munin-2.0.37/plugins/node.d.netbsd/load.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/load.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,5 +1,5 @@ -#!/bin/sh -# +#!@@GOODSH@@ +# # Plugin to monitor the load average on a system. # # Usage: Link or copy into /etc/munin/node.d/ @@ -53,8 +53,8 @@ if [ $? != 0 ]; then NCPU=1; fi # If run with the "config"-parameter, give out information on how the -# graphs should look. - +# graphs should look. + if [ "$1" = "config" ]; then # The host name this plugin is for. (Can be overridden to have # one machine answer for several) @@ -72,7 +72,7 @@ # The category of the plugin. Defaults to "other". echo 'graph_category system' # The fields. "label" is used in the legend. "label" is the only - # required subfield. + # required subfield. echo 'load.label load' # These two are optional. They are only used if you have # configured your munin to tell a Nagios-server about any diff -Nru munin-2.0.37/plugins/node.d.netbsd/memory.in munin-2.0.47/plugins/node.d.netbsd/memory.in --- munin-2.0.37/plugins/node.d.netbsd/memory.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/memory.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/sh +#!@@GOODSH@@ # # Plugin to monitor memory usage. # diff -Nru munin-2.0.37/plugins/node.d.netbsd/memory_pools.in munin-2.0.47/plugins/node.d.netbsd/memory_pools.in --- munin-2.0.37/plugins/node.d.netbsd/memory_pools.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/memory_pools.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#! /bin/sh +#!@@GOODSH@@ # # Plugin to monitor NetBSD kernel memory pool usage. # diff -Nru munin-2.0.37/plugins/node.d.netbsd/memory_types.in munin-2.0.47/plugins/node.d.netbsd/memory_types.in --- munin-2.0.37/plugins/node.d.netbsd/memory_types.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/memory_types.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#! /bin/sh +#!@@GOODSH@@ # # Plugin to monitor memory usage by type. # diff -Nru munin-2.0.37/plugins/node.d.netbsd/nfs_client.in munin-2.0.47/plugins/node.d.netbsd/nfs_client.in --- munin-2.0.37/plugins/node.d.netbsd/nfs_client.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/nfs_client.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/sh +#!@@GOODSH@@ : << =cut @@ -39,7 +39,7 @@ =cut # -# +# # # # diff -Nru munin-2.0.37/plugins/node.d.netbsd/nfsd.in munin-2.0.47/plugins/node.d.netbsd/nfsd.in --- munin-2.0.37/plugins/node.d.netbsd/nfsd.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/nfsd.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/sh +#!@@GOODSH@@ # # Plugin to monitor NFS server traffic # diff -Nru munin-2.0.37/plugins/node.d.netbsd/open_files.in munin-2.0.47/plugins/node.d.netbsd/open_files.in --- munin-2.0.37/plugins/node.d.netbsd/open_files.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/open_files.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,9 +1,9 @@ -#!/bin/sh -# +#!@@GOODSH@@ +# # Plugin to monitor the number of open files in the system. # # Parameters: -# +# # config (required) # autoconf (optional - used by munin-config) # diff -Nru munin-2.0.37/plugins/node.d.netbsd/sensors_.in munin-2.0.47/plugins/node.d.netbsd/sensors_.in --- munin-2.0.37/plugins/node.d.netbsd/sensors_.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/sensors_.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/sh +#!@@GOODSH@@ # # Plugin to monitor various environment sensors provided by envstat(8) # on NetBSD @@ -44,7 +44,7 @@ exit 0 fi fi - + if [ "$1" = "suggest" ]; then /usr/sbin/envstat -r | awk ' diff -Nru munin-2.0.37/plugins/node.d.netbsd/swap.in munin-2.0.47/plugins/node.d.netbsd/swap.in --- munin-2.0.37/plugins/node.d.netbsd/swap.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/swap.in 2019-02-28 14:43:36.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/sh +#!@@GOODSH@@ # # Plugin to monitor swap IO in number of blocks per second. # diff -Nru munin-2.0.37/plugins/node.d.netbsd/uptime.in munin-2.0.47/plugins/node.d.netbsd/uptime.in --- munin-2.0.37/plugins/node.d.netbsd/uptime.in 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/node.d.netbsd/uptime.in 2019-02-28 14:43:36.000000000 +0000 @@ -45,7 +45,7 @@ boottime=`/sbin/sysctl -n kern.boottime` now=`/bin/date +%s` -awk -v boottime=$boottime -v now=$now [0] eq 'head1'; next unless grep { $_ eq $section->[2] } @sections; - + push @headings, $section->[2]; } diff -Nru munin-2.0.37/plugins/t/munin_plugin_snmp.t munin-2.0.47/plugins/t/munin_plugin_snmp.t --- munin-2.0.37/plugins/t/munin_plugin_snmp.t 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/plugins/t/munin_plugin_snmp.t 2019-02-28 14:43:36.000000000 +0000 @@ -319,7 +319,7 @@ eval { Munin::Plugin::SNMP->session(); }; like($@, qr/./, 'Unknown SNMP version causes an exception.'); } - + # Unable to create session { no warnings; diff -Nru munin-2.0.37/RELEASE munin-2.0.47/RELEASE --- munin-2.0.37/RELEASE 2018-03-28 19:37:35.000000000 +0000 +++ munin-2.0.47/RELEASE 2019-02-28 14:45:50.000000000 +0000 @@ -1 +1 @@ -2.0.37 +2.0.47 diff -Nru munin-2.0.37/.travis.yml munin-2.0.47/.travis.yml --- munin-2.0.37/.travis.yml 2018-03-28 19:36:43.000000000 +0000 +++ munin-2.0.47/.travis.yml 2019-02-28 14:43:36.000000000 +0000 @@ -1,12 +1,10 @@ +dist: xenial language: perl perl: - "5.20" - "5.18" - "5.16" - "5.14" - - "5.12" - - "5.10" - - "5.8" branches: only: - stable-2.0 @@ -21,16 +19,23 @@ - libfile-slurp-perl - libhtml-template-perl - libio-socket-inet6-perl + - libio-stringy-perl + - liblist-moreutils-perl - liblog-dispatch-perl + - liblog-log4perl-perl - libmodule-build-perl - libnet-server-perl - libnet-snmp-perl - libnet-ssleay-perl + - librrds-perl - libtest-deep-perl - libtest-differences-perl + - libtest-exception-perl - libtest-longstring-perl - libtest-mockmodule-perl - libtest-mockobject-perl + - python3-flake8 + - shellcheck notifications: email: false irc: @@ -52,7 +57,7 @@ cpanm -n Devel::Cover::Report::Coveralls script: - make && make test - -# Using the container-based infrastructure -sudo: false + - make + # the old travis environment requires an old flake8 invocation + - PYTHON_LINT_CALL="python3 -m flake8.main" make lint + - make test
 
 
 
 
 
+ This field has the following extra information:
[0-9]* of [0-9]* [0-9]* of [0-9]* WU WU