Skip to content

Commit

Permalink
Merge pull request #54 from djs55/audit-python
Browse files Browse the repository at this point in the history
Audit and restructure package hiearchy
  • Loading branch information
djs55 committed Sep 11, 2015
2 parents 78276b7 + c925525 commit 1306477
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 133 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ python/build
python/d.py
python/v.py
python/p.py
*.pyc
*.pyo
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ default: build
build:
(cd generator; make)
mkdir -p ocaml/examples
mkdir -p python/xapi
mkdir -p python/xapi/storage/api
./generator/main.native
make -C ocaml
make -C python
Expand Down
2 changes: 1 addition & 1 deletion generator/src/main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ let _ =

List.iter
(fun api ->
with_output_file (Printf.sprintf "python/xapi/%s.py" api.Interfaces.name)
with_output_file (Printf.sprintf "python/xapi/storage/api/%s.py" api.Interfaces.name)
(fun oc ->
let idents, api = resolve_refs_in_api api in
output_string oc (Python.of_interfaces idents api |> Python.string_of_ts)
Expand Down
4 changes: 2 additions & 2 deletions python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
description='Xapi storage interface',
author='David Scott',
author_email='[email protected]',
url='https://github.com/djs55/xapi-storage/',
packages=['xapi'],
url='https://github.com/xapi-project/xapi-storage/',
packages=['xapi', 'xapi.storage', 'xapi.storage.api'],
)
129 changes: 0 additions & 129 deletions python/xapi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,6 @@

import os, sys, time, socket, traceback, syslog, json, argparse

log_f = os.fdopen(os.dup(sys.stdout.fileno()), "aw")
pid = None
use_syslog = False

def reopenlog(log_file):
global log_f
if log_f:
log_f.close()
if log_file and log_file <> "stdout:":
log_f = open(log_file, "aw")
elif log_file and log_file == "stdout:":
log_f = os.fdopen(os.dup(sys.stdout.fileno()), "aw")

def log(txt):
global log_f, pid, use_syslog
if use_syslog:
syslog.syslog(txt)
return
if not pid:
pid = os.getpid()
t = time.strftime("%Y%m%dT%H:%M:%SZ", time.gmtime())
print >>log_f, "%s [%d] %s" % (t, pid, txt)
log_f.flush()

def success(result):
return { "Status": "Success", "Value": result }

Expand Down Expand Up @@ -116,108 +92,3 @@ def __call__(self, parser, namespace, values, option_string=None):
getattr(namespace, self.dest)[k] = v
else:
setattr(namespace, self.dest, { k: v })

# Helper function to daemonise ##############################################
def daemonize():
def fork():
try:
if os.fork() > 0:
# parent
os._exit(0)
except OSError, e:
print >>sys.stderr, "fork() failed: %s" % e
traceback.print_exc()
raise
fork()
os.umask(0)
os.chdir("/")
os.setsid()
fork()
devnull = open("/dev/null", "r")
os.dup2(devnull.fileno(), sys.stdin.fileno())
devnull = open("/dev/null", "aw")
os.dup2(devnull.fileno(), sys.stdout.fileno())
os.dup2(devnull.fileno(), sys.stderr.fileno())

from SocketServer import UnixStreamServer
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler, SimpleXMLRPCDispatcher
from xmlrpclib import ServerProxy, Fault, Transport
from socket import socket, SOL_SOCKET, SO_REUSEADDR, AF_UNIX, SOCK_STREAM

# Server XMLRPC from any HTTP POST path #####################################

class RequestHandler(SimpleXMLRPCRequestHandler):
rpc_paths = []
def do_OPTIONS(self):
log("running options thingy")
self.send_response(200, "ok")
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'POST, OPTIONS, GET')
self.send_header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')


class UnixServer(UnixStreamServer, SimpleXMLRPCDispatcher):
def __init__(self, addr, requestHandler=RequestHandler):
self.logRequests = 0
if os.path.exists(addr):
os.unlink(addr)
dir = os.path.dirname(addr)
if not(os.path.exists(dir)):
os.makedirs(dir)
SimpleXMLRPCDispatcher.__init__(self)
UnixStreamServer.__init__(self, addr, requestHandler)

class TCPServer(SimpleXMLRPCServer):
def __init__(self, ip, port, requestHandler=RequestHandler):
SimpleXMLRPCServer.__init__(self, (ip, port), requestHandler=requestHandler)
def server_bind(self):
self.socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
SimpleXMLRPCServer.server_bind(self)

# This is a hack to patch slow socket.getfqdn calls that
# BaseHTTPServer (and its subclasses) make.
# See: http://bugs.python.org/issue6085
# See: http://www.answermysearches.com/xmlrpc-server-slow-in-python-how-to-fix/2140/
import BaseHTTPServer

def _bare_address_string(self):
host, port = self.client_address[:2]
return '%s' % host

BaseHTTPServer.BaseHTTPRequestHandler.address_string = \
_bare_address_string

# This is a hack to allow_none by default, which only became settable in
# python 2.5's SimpleXMLRPCServer

import xmlrpclib

original_dumps = xmlrpclib.dumps
def dumps(params, methodname=None, methodresponse=None, encoding=None,
allow_none=1):
return original_dumps(params, methodname, methodresponse, encoding, allow_none)
xmlrpclib.dumps = dumps

# Well-known feature flags understood by xapi ##############################
# XXX: add an enum to the IDL?

feature_sr_probe = "SR_PROBE"
feature_sr_update = "SR_UPDATE"
feature_sr_supports_local_caching = "SR_SUPPORTS_LOCAL_CACHING"
feature_vdi_create = "VDI_CREATE"
feature_vdi_delete = "VDI_DELETE"
feature_vdi_attach = "VDI_ATTACH"
feature_vdi_detach = "VDI_DETACH"
feature_vdi_resize = "VDI_RESIZE"
feature_vdi_resize_online = "VDI_RESIZE_ONLINE"
feature_vdi_clone = "VDI_CLONE"
feature_vdi_snapshot = "VDI_SNAPSHOT"
feature_vdi_activate = "VDI_ACTIVATE"
feature_vdi_deactivate = "VDI_DEACTIVATE"
feature_vdi_update = "VDI_UPDATE"
feature_vdi_introduce = "VDI_INTRODUCE"
feature_vdi_generate_config = "VDI_GENERATE_CONFIG"
feature_vdi_reset_on_boot = "VDI_RESET_ON_BOOT"

def connect():
return xmlrpclib.Server("http://localhost:80")
1 change: 1 addition & 0 deletions python/xapi/storage/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#!/usr/bin/env python
1 change: 1 addition & 0 deletions python/xapi/storage/api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#!/usr/bin/env python
28 changes: 28 additions & 0 deletions python/xapi/storage/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env python

from xapi.storage import log
import xapi
import subprocess


# [call dbg cmd_args] executes [cmd_args]
# if [error] and exit code != expRc, log and throws a BackendError
# if [simple], returns only stdout


def call(dbg, cmd_args, error=True, simple=True, expRc=0):
log.debug("%s: Running cmd %s" % (dbg, cmd_args))
p = subprocess.Popen(
cmd_args,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
close_fds=True)
stdout, stderr = p.communicate()
if error and p.returncode != expRc:
log.error("%s: %s exitted with code %d: %s" %
(dbg, " ".join(cmd_args), p.returncode, stderr))
raise xapi.InternalError("%s exitted with non-zero code %d: %s"
% (" ".join(cmd_args), p.returncode, stderr))
if simple:
return stdout
return stdout, stderr, p.returncode
70 changes: 70 additions & 0 deletions python/xapi/storage/log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import logging
import logging.handlers
import sys
import xapi


LOG_LEVEL = logging.DEBUG
# LOG to local2 which is currently mapped to /var/log/SMlog for SM
LOG_SYSLOG_FACILITY = logging.handlers.SysLogHandler.LOG_LOCAL2
LOG_TO_STDERR = False


def configure_logging():
_LOGGER.setLevel(LOG_LEVEL)

formatter = logging.Formatter(
'%(asctime)s - [%(process)d] - %(levelname)s - %(message)s',
'%Y-%m-%d %H:%M:%S')

handlers = []

# Log to syslog
handlers.append(logging.handlers.SysLogHandler(
address='/dev/log',
facility=LOG_SYSLOG_FACILITY))

if LOG_TO_STDERR:
# Write to stderr
handlers.append(logging.StreamHandler(sys.stderr))

# Configure and add handlers
for handler in handlers:
handler.setLevel(LOG_LEVEL)
handler.setFormatter(formatter)
_LOGGER.addHandler(handler)


def debug(message, *args, **kwargs):
_LOGGER.debug(message, *args, **kwargs)


def info(message, *args, **kwargs):
_LOGGER.info(message, *args, **kwargs)


def error(message, *args, **kwargs):
_LOGGER.error(message, *args, **kwargs)


def log_call_argv():
info("called as: %s" % (sys.argv))


def handle_unhandled_exceptions(exception_type, exception_value,
exception_traceback):
if not issubclass(exception_type, KeyboardInterrupt):
if issubclass(exception_type, xapi.XenAPIException):
info("Returned exception to XAPI", exc_info=(exception_type,
exception_value,
exception_traceback))
else:
error("Unhandled exception", exc_info=(exception_type,
exception_value,
exception_traceback))
sys.__excepthook__(exception_type, exception_value, exception_traceback)


_LOGGER = logging.getLogger()
configure_logging()
sys.excepthook = handle_unhandled_exceptions

0 comments on commit 1306477

Please sign in to comment.