Skip to content
Fetching contributors…
Cannot retrieve contributors at this time
executable file 393 lines (327 sloc) 11.3 KB
#!/usr/bin/env python2
# -*- coding: utf-8; mode: python -*-
#
# Cherokee-admin
#
# Authors:
# Alvaro Lopez Ortega <alvaro@alobbs.com>
#
# Copyright (C) 2001-2013 Alvaro Lopez Ortega
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
# License as published by the Free Software Foundation.
#
# 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.
#
import os
import re
import sys
import urllib2
APP_NAME = "Cherokee Tweak"
APP_COPY_NOTICE = \
"Written by Alvaro Lopez Ortega <alvaro@alobbs.com>\n\n" \
"Copyright (C) 2001-2013 Alvaro Lopez Ortega.\n" \
"This is free software; see the source for copying conditions. There is NO\n" \
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
USAGE = \
"Usage:\n" \
" cherokee-tweak [options] URL info \n" \
" cherokee-tweak [options] URL purge \n" \
" cherokee-tweak [options] URL sources \n" \
" cherokee-tweak [options] URL kill-source ID \n" \
" cherokee-tweak [options] URL logrotate PATH \n" \
" cherokee-tweak [options] URL trace TRACE \n\n" \
" Commands:\n" \
" info Prints info about the server status\n" \
" trace Manipulates the tracing mechanism\n" \
" logrotate Rotates a local log file\n" \
" sources Prints a list of the info. sources\n" \
" kill-source Kill a remote information source\n" \
" purge Purge objects from the cache\n\n" \
" Parameters:\n" \
" -h, --help Print this help\n" \
" -V, --version Print version and exit\n\n" \
" Options:\n" \
" -u, --user=STRING User name\n" \
" -p, --password=STRING Password\n\n" \
"Report bugs to http://bugs.cherokee-project.com\n"
command = None
url = None
user = None
password = None
log = None
trace = None
ksource = None
def parse_args():
global command, url
global user, password
global log, trace, ksource
if '-h' in sys.argv or '--help' in sys.argv:
print USAGE
raise SystemExit
if '-v' in sys.argv or '--version' in sys.argv:
print APP_NAME
print APP_COPY_NOTICE
raise SystemExit
# Check length
if len(sys.argv) < 3:
print USAGE
raise SystemExit
# Parse parameters
argn = 1
while argn < len(sys.argv):
arg = sys.argv[argn]
if arg.startswith('--user='):
user = arg[7:]
argn += 1
continue
elif arg == '-u':
user = sys.argv[argn+1]
argn += 2
continue
elif arg.startswith('--password='):
password = arg[11:]
argn += 1
continue
elif arg == '-p':
password = sys.argv[argn+1]
argn += 2
continue
else:
if arg.startswith('-'):
print USAGE
raise SystemExit
break
# Mandatory parameter
url = sys.argv[argn]
command = sys.argv[argn + 1]
argn += 2
# Check command
if command == 'info':
None
elif command == 'purge':
None
elif command == 'trace':
trace = sys.argv[argn]
argn += 1
elif command == 'logrotate':
log = sys.argv[argn]
argn += 1
elif command == 'sources':
None
elif command == 'kill-source':
ksource = sys.argv[argn]
argn += 1
else:
print USAGE
raise SystemExit
def http_request (url_py, post_info=None, method=None):
# Authtentication
if user or password:
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password (None, url, user, password)
authhandler_digest = urllib2.HTTPDigestAuthHandler (passman)
authhandler_basic = urllib2.HTTPBasicAuthHandler (passman)
opener = urllib2.build_opener (authhandler_digest, authhandler_basic)
urllib2.install_opener (opener)
else:
opener = urllib2.build_opener (urllib2.HTTPHandler)
# Request
request = urllib2.Request (url_py, post_info)
if method:
request.get_method = lambda: method
# Perform
try:
conn = urllib2.urlopen (url_py, post_info)
except urllib2.HTTPError, e:
if e.code == 401:
print >> sys.stderr, "Error in Authentication"
raise SystemExit
raise
return conn.read()
def request (commands):
tmp = url + '/py'
url_py = tmp[:7] + tmp[7:].replace('//','/')
post_info = "%s\n" %('\n'.join(commands))
return http_request (url_py, post_info)
def eval_safe (txt):
try:
return eval(txt)
except:
print "Failed to evaluate: ========"
print txt
print "============================"
raise
#
# Sources
#
def print_sources():
# Query
responses_str = request (['get server.sources'])
responses = eval_safe(responses_str)
sources = responses[0]
# Print
for source in sources:
type_ = source.get('type')
print "\tID: %s" %(source.get('id'))
print "\tType: %s" %(type_)
print "\tBind: %s" %(source.get('bind') or '')
if type_ == 'interpreter':
print "\tPID: %d" %(source.get('PID') or '')
print "\tTimeout: %d" %(source.get('timeout') or '')
print "\tDebug: %s" %(('No','Yes')[int(source.get('debug'))])
print "\tInterpreter: %s" %(source.get('interpreter') or '')
if sources.index(source) < len(sources)-1:
print "\t---------------------"
print
def kill_source():
# Query
responses_str = request (['kill server.source %s'%(ksource)])
responses = eval_safe(responses_str)
# Report
print "Source %s: %s" %(ksource, responses[0]['source'])
print
#
# Info
#
def print_info():
# Query
info_str = request (['get server.ports',
'get server.traffic',
'get server.thread_num',
'get server.connections'])
info = eval_safe(info_str)
ports = info[0]
traffic = info[1]
threads = info[2]
conns = info[3]
# General
print "General:"
print "\tThread number: %d" %(threads.get('thread_num'))
print
# Traffic
if traffic.get('tx') != -1 and traffic.get('rx') != -1:
print "Traffic:"
print "\tTX: %d" %(traffic.get('tx'))
print "\tTX formatted: %s" %(traffic.get('tx_formatted') or '')
print "\tRX: %d" %(traffic.get('rx'))
print "\tRX formatted: %s" %(traffic.get('rx_formatted') or '')
print
# Incoming Ports
print "Ports:"
for port in ports:
print "\tID: %d" %(port.get('id'))
print "\tPort: %d" %(port.get('port'))
print "\tTLS: %s" %(('No','Yes')[int(port.get('tls'))])
print "\tBind: %s" %(port.get('bind') or '')
if ports.index(port) < len(ports)-1:
print "\t---------------------"
print
# Connection details
print "Connections:"
for conn in conns:
print "\tRequest: %s" %(conn.get('request',''))
print "\tHandler: %s" %(conn.get('handler'))
print "\tPhase: %s" %(conn.get('phase'))
print "\tIncoming IP: %s" %(conn.get('ip'))
print "\tRX: %s" %(conn.get('rx'))
print "\tTX: %s" %(conn.get('tx'))
if conns.index(conn) < len(conns)-1:
print "\t---------------------"
print
#
# Trace
#
def print_trace():
trace_str = request (['get server.trace'])
traces = eval_safe(trace_str)
print "Trace: %s" %(traces[0].get('trace') or 'Disabled')
print
def set_trace():
trace_str = request (['set server.trace %s'%(trace)])
traces = eval_safe(trace_str)
print "Trace set: %s" %(('Failed', 'Succeed')[int(traces[0].get('set'))])
print
#
# Log Rotation
#
def do_logrotate():
# Look for the new log name
dirname = os.path.dirname (log) or '.'
basename = os.path.basename (log)
num = 0
new_logname = None
similar = filter (lambda x: x.startswith(basename), os.listdir(dirname))
for filename in similar:
tmp = re.findall ('%s\.(\d)+'%(basename), filename)
if tmp:
num = max (int(tmp[0]), num)
dot = basename.rfind('.')
if dot != -1:
if basename[dot:].isdigit():
new_logname = '%s.%d' %(basename[dot:], num+1)
if not new_logname:
new_logname = '%s.%d' %(basename, num+1)
new_logpath = os.path.join (dirname, new_logname)
# Enable Backup-mode
print "Enabling Back-up mode.."
backup_str = request (['set server.backup_mode on'])
backup = eval_safe(backup_str)
assert backup[0]['backup_mode'], "Couldn't set backup mode"
# Rotate the log
print "Moving %s to %s" %(log, new_logpath)
os.rename (log, new_logpath)
# Enable Backup-mode
print "Disabling Back-up mode.."
backup_str = request (['set server.backup_mode off'])
backup = eval_safe(backup_str)
assert not backup[0]['backup_mode'], "Couldn't unset backup mode"
#
# Purge from Cache
#
def do_purge():
try:
response_py = http_request (url, method="PURGE")
except urllib2.HTTPError, e:
if e.code == 404:
print >> sys.stderr, "Object not found in the cache"
sys.exit(1)
raise
def main():
parse_args()
if command == 'info':
print_info()
elif command == 'purge':
do_purge()
elif command == 'sources':
print_sources()
elif command == 'kill-source':
if ksource:
kill_source()
else:
print "ERROR: Missing source ID parameter"
elif command == 'trace':
if trace:
set_trace()
else:
print_trace()
elif command == 'logrotate':
if log:
do_logrotate()
else:
print "ERROR: Missing LOG parameter"
else:
print "ERROR: Command not found: %s\n" %(command)
print USAGE
raise SystemExit
if __name__ == "__main__":
main()
Jump to Line
Something went wrong with that request. Please try again.