mirror of
				https://github.com/mail-in-a-box/mailinabox.git
				synced 2025-11-03 19:30:54 +00:00 
			
		
		
		
	merge #674 - Support munin's cgi dynazoom
This commit is contained in:
		
						commit
						546d6f0026
					
				@ -1,6 +1,13 @@
 | 
			
		||||
CHANGELOG
 | 
			
		||||
=========
 | 
			
		||||
 | 
			
		||||
In Development
 | 
			
		||||
--------------
 | 
			
		||||
 | 
			
		||||
Control panel:
 | 
			
		||||
 | 
			
		||||
* Munin system monitoring graphs are now zoomable.
 | 
			
		||||
 | 
			
		||||
v0.17b (March 1, 2016)
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,10 @@
 | 
			
		||||
#!/usr/bin/python3
 | 
			
		||||
 | 
			
		||||
import os, os.path, re, json
 | 
			
		||||
 | 
			
		||||
import subprocess
 | 
			
		||||
from functools import wraps
 | 
			
		||||
 | 
			
		||||
from flask import Flask, request, render_template, abort, Response, send_from_directory
 | 
			
		||||
from flask import Flask, request, render_template, abort, Response, send_from_directory, make_response
 | 
			
		||||
 | 
			
		||||
import auth, utils, multiprocessing.pool
 | 
			
		||||
from mailconfig import get_mail_users, get_mail_users_ex, get_admins, add_mail_user, set_mail_password, remove_mail_user
 | 
			
		||||
@ -504,6 +504,64 @@ def munin(filename=""):
 | 
			
		||||
	if filename == "": filename = "index.html"
 | 
			
		||||
	return send_from_directory("/var/cache/munin/www", filename)
 | 
			
		||||
 | 
			
		||||
@app.route('/munin/cgi-graph/<path:filename>')
 | 
			
		||||
@authorized_personnel_only
 | 
			
		||||
def munin_cgi(filename):
 | 
			
		||||
	""" Relay munin cgi dynazoom requests
 | 
			
		||||
	/usr/lib/munin/cgi/munin-cgi-graph is a perl cgi script in the munin package
 | 
			
		||||
	that is responsible for generating binary png images _and_ associated HTTP
 | 
			
		||||
	headers based on parameters in the requesting URL. All output is written
 | 
			
		||||
	to stdout which munin_cgi splits into response headers and binary response
 | 
			
		||||
	data.
 | 
			
		||||
	munin-cgi-graph reads environment variables as well as passed input to determine
 | 
			
		||||
	what it should do. It expects a path to be in the env-var PATH_INFO, and a
 | 
			
		||||
	querystring to be in the env-var QUERY_STRING as well as passed as input to the
 | 
			
		||||
	command.
 | 
			
		||||
	munin-cgi-graph has several failure modes. Some write HTTP Status headers and
 | 
			
		||||
	others return nonzero exit codes.
 | 
			
		||||
	Situating munin_cgi between the user-agent and munin-cgi-graph enables keeping
 | 
			
		||||
	the cgi script behind mailinabox's auth mechanisms and avoids additional
 | 
			
		||||
	support infrastructure like spawn-fcgi.
 | 
			
		||||
	"""
 | 
			
		||||
 | 
			
		||||
	COMMAND = 'su - munin --preserve-environment --shell=/bin/bash -c /usr/lib/munin/cgi/munin-cgi-graph "%s"'
 | 
			
		||||
	# su changes user, we use the munin user here
 | 
			
		||||
	# --preserve-environment retains the environment, which is where Popen's `env` data is
 | 
			
		||||
	# --shell=/bin/bash ensures the shell used is bash
 | 
			
		||||
	# -c "/usr/lib/munin/cgi/munin-cgi-graph" passes the command to run as munin
 | 
			
		||||
	# "%s" is a placeholder for where the request's querystring will be added
 | 
			
		||||
 | 
			
		||||
	if filename == "":
 | 
			
		||||
		return ("a path must be specified", 404)
 | 
			
		||||
 | 
			
		||||
	query_str = request.query_string.decode("utf-8", 'ignore')
 | 
			
		||||
 | 
			
		||||
	env = {'PATH_INFO': '/%s/' % filename, 'QUERY_STRING': query_str}
 | 
			
		||||
	cmd = COMMAND % query_str
 | 
			
		||||
	code, binout = utils.shell('check_output',
 | 
			
		||||
							   cmd.split(' ', 5),
 | 
			
		||||
							   # Using a maxsplit of 5 keeps the last 2 arguments together
 | 
			
		||||
							   input=query_str.encode('UTF-8'),
 | 
			
		||||
							   env=env,
 | 
			
		||||
							   return_bytes=True,
 | 
			
		||||
							   trap=True)
 | 
			
		||||
 | 
			
		||||
	if code != 0:
 | 
			
		||||
		# nonzero returncode indicates error
 | 
			
		||||
		app.logger.error("munin_cgi: munin-cgi-graph returned nonzero exit code, %s", process.returncode)
 | 
			
		||||
		return ("error processing graph image", 500)
 | 
			
		||||
 | 
			
		||||
	# /usr/lib/munin/cgi/munin-cgi-graph returns both headers and binary png when successful.
 | 
			
		||||
	# A double-Windows-style-newline always indicates the end of HTTP headers.
 | 
			
		||||
	headers, image_bytes = binout.split(b'\r\n\r\n', 1)
 | 
			
		||||
	response = make_response(image_bytes)
 | 
			
		||||
	for line in headers.splitlines():
 | 
			
		||||
		name, value = line.decode("utf8").split(':', 1)
 | 
			
		||||
		response.headers[name] = value
 | 
			
		||||
	if 'Status' in response.headers and '404' in response.headers['Status']:
 | 
			
		||||
		app.logger.warning("munin_cgi: munin-cgi-graph returned 404 status code. PATH_INFO=%s", env['PATH_INFO'])
 | 
			
		||||
	return response
 | 
			
		||||
 | 
			
		||||
# APP
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,8 @@ source /etc/mailinabox.conf # load global vars
 | 
			
		||||
 | 
			
		||||
# install Munin
 | 
			
		||||
echo "Installing Munin (system monitoring)..."
 | 
			
		||||
apt_install munin munin-node
 | 
			
		||||
apt_install munin munin-node libcgi-fast-perl
 | 
			
		||||
# libcgi-fast-perl is needed by /usr/lib/munin/cgi/munin-cgi-graph
 | 
			
		||||
 | 
			
		||||
# edit config
 | 
			
		||||
cat > /etc/munin/munin.conf <<EOF;
 | 
			
		||||
@ -19,6 +20,9 @@ tmpldir /etc/munin/templates
 | 
			
		||||
 | 
			
		||||
includedir /etc/munin/munin-conf.d
 | 
			
		||||
 | 
			
		||||
# path dynazoom uses for requests
 | 
			
		||||
cgiurl_graph /admin/munin/cgi-graph
 | 
			
		||||
 | 
			
		||||
# a simple host tree
 | 
			
		||||
[$PRIMARY_HOSTNAME]
 | 
			
		||||
address 127.0.0.1
 | 
			
		||||
@ -29,6 +33,10 @@ contact.admin.command mail -s "Munin notification ${var:host}" administrator@$PR
 | 
			
		||||
contact.admin.always_send warning critical
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
# The Debian installer touches these files and chowns them to www-data:adm for use with spawn-fcgi
 | 
			
		||||
chown munin. /var/log/munin/munin-cgi-html.log
 | 
			
		||||
chown munin. /var/log/munin/munin-cgi-graph.log
 | 
			
		||||
 | 
			
		||||
# ensure munin-node knows the name of this machine
 | 
			
		||||
tools/editconf.py /etc/munin/munin-node.conf -s \
 | 
			
		||||
	host_name=$PRIMARY_HOSTNAME
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user