Skip to content

Commit 1306477

Browse files
committed
Merge pull request #54 from djs55/audit-python
Audit and restructure package hiearchy
2 parents 78276b7 + c925525 commit 1306477

File tree

9 files changed

+106
-133
lines changed

9 files changed

+106
-133
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ python/build
2727
python/d.py
2828
python/v.py
2929
python/p.py
30+
*.pyc
31+
*.pyo

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ default: build
55
build:
66
(cd generator; make)
77
mkdir -p ocaml/examples
8-
mkdir -p python/xapi
8+
mkdir -p python/xapi/storage/api
99
./generator/main.native
1010
make -C ocaml
1111
make -C python

generator/src/main.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ let _ =
2121

2222
List.iter
2323
(fun api ->
24-
with_output_file (Printf.sprintf "python/xapi/%s.py" api.Interfaces.name)
24+
with_output_file (Printf.sprintf "python/xapi/storage/api/%s.py" api.Interfaces.name)
2525
(fun oc ->
2626
let idents, api = resolve_refs_in_api api in
2727
output_string oc (Python.of_interfaces idents api |> Python.string_of_ts)

python/setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
description='Xapi storage interface',
55
author='David Scott',
66
author_email='dave@recoil.org',
7-
url='https://github.com/djs55/xapi-storage/',
8-
packages=['xapi'],
7+
url='https://github.com/xapi-project/xapi-storage/',
8+
packages=['xapi', 'xapi.storage', 'xapi.storage.api'],
99
)

python/xapi/__init__.py

Lines changed: 0 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,6 @@
22

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

5-
log_f = os.fdopen(os.dup(sys.stdout.fileno()), "aw")
6-
pid = None
7-
use_syslog = False
8-
9-
def reopenlog(log_file):
10-
global log_f
11-
if log_f:
12-
log_f.close()
13-
if log_file and log_file <> "stdout:":
14-
log_f = open(log_file, "aw")
15-
elif log_file and log_file == "stdout:":
16-
log_f = os.fdopen(os.dup(sys.stdout.fileno()), "aw")
17-
18-
def log(txt):
19-
global log_f, pid, use_syslog
20-
if use_syslog:
21-
syslog.syslog(txt)
22-
return
23-
if not pid:
24-
pid = os.getpid()
25-
t = time.strftime("%Y%m%dT%H:%M:%SZ", time.gmtime())
26-
print >>log_f, "%s [%d] %s" % (t, pid, txt)
27-
log_f.flush()
28-
295
def success(result):
306
return { "Status": "Success", "Value": result }
317

@@ -116,108 +92,3 @@ def __call__(self, parser, namespace, values, option_string=None):
11692
getattr(namespace, self.dest)[k] = v
11793
else:
11894
setattr(namespace, self.dest, { k: v })
119-
120-
# Helper function to daemonise ##############################################
121-
def daemonize():
122-
def fork():
123-
try:
124-
if os.fork() > 0:
125-
# parent
126-
os._exit(0)
127-
except OSError, e:
128-
print >>sys.stderr, "fork() failed: %s" % e
129-
traceback.print_exc()
130-
raise
131-
fork()
132-
os.umask(0)
133-
os.chdir("/")
134-
os.setsid()
135-
fork()
136-
devnull = open("/dev/null", "r")
137-
os.dup2(devnull.fileno(), sys.stdin.fileno())
138-
devnull = open("/dev/null", "aw")
139-
os.dup2(devnull.fileno(), sys.stdout.fileno())
140-
os.dup2(devnull.fileno(), sys.stderr.fileno())
141-
142-
from SocketServer import UnixStreamServer
143-
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler, SimpleXMLRPCDispatcher
144-
from xmlrpclib import ServerProxy, Fault, Transport
145-
from socket import socket, SOL_SOCKET, SO_REUSEADDR, AF_UNIX, SOCK_STREAM
146-
147-
# Server XMLRPC from any HTTP POST path #####################################
148-
149-
class RequestHandler(SimpleXMLRPCRequestHandler):
150-
rpc_paths = []
151-
def do_OPTIONS(self):
152-
log("running options thingy")
153-
self.send_response(200, "ok")
154-
self.send_header('Access-Control-Allow-Origin', '*')
155-
self.send_header('Access-Control-Allow-Methods', 'POST, OPTIONS, GET')
156-
self.send_header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
157-
158-
159-
class UnixServer(UnixStreamServer, SimpleXMLRPCDispatcher):
160-
def __init__(self, addr, requestHandler=RequestHandler):
161-
self.logRequests = 0
162-
if os.path.exists(addr):
163-
os.unlink(addr)
164-
dir = os.path.dirname(addr)
165-
if not(os.path.exists(dir)):
166-
os.makedirs(dir)
167-
SimpleXMLRPCDispatcher.__init__(self)
168-
UnixStreamServer.__init__(self, addr, requestHandler)
169-
170-
class TCPServer(SimpleXMLRPCServer):
171-
def __init__(self, ip, port, requestHandler=RequestHandler):
172-
SimpleXMLRPCServer.__init__(self, (ip, port), requestHandler=requestHandler)
173-
def server_bind(self):
174-
self.socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
175-
SimpleXMLRPCServer.server_bind(self)
176-
177-
# This is a hack to patch slow socket.getfqdn calls that
178-
# BaseHTTPServer (and its subclasses) make.
179-
# See: http://bugs.python.org/issue6085
180-
# See: http://www.answermysearches.com/xmlrpc-server-slow-in-python-how-to-fix/2140/
181-
import BaseHTTPServer
182-
183-
def _bare_address_string(self):
184-
host, port = self.client_address[:2]
185-
return '%s' % host
186-
187-
BaseHTTPServer.BaseHTTPRequestHandler.address_string = \
188-
_bare_address_string
189-
190-
# This is a hack to allow_none by default, which only became settable in
191-
# python 2.5's SimpleXMLRPCServer
192-
193-
import xmlrpclib
194-
195-
original_dumps = xmlrpclib.dumps
196-
def dumps(params, methodname=None, methodresponse=None, encoding=None,
197-
allow_none=1):
198-
return original_dumps(params, methodname, methodresponse, encoding, allow_none)
199-
xmlrpclib.dumps = dumps
200-
201-
# Well-known feature flags understood by xapi ##############################
202-
# XXX: add an enum to the IDL?
203-
204-
feature_sr_probe = "SR_PROBE"
205-
feature_sr_update = "SR_UPDATE"
206-
feature_sr_supports_local_caching = "SR_SUPPORTS_LOCAL_CACHING"
207-
feature_vdi_create = "VDI_CREATE"
208-
feature_vdi_delete = "VDI_DELETE"
209-
feature_vdi_attach = "VDI_ATTACH"
210-
feature_vdi_detach = "VDI_DETACH"
211-
feature_vdi_resize = "VDI_RESIZE"
212-
feature_vdi_resize_online = "VDI_RESIZE_ONLINE"
213-
feature_vdi_clone = "VDI_CLONE"
214-
feature_vdi_snapshot = "VDI_SNAPSHOT"
215-
feature_vdi_activate = "VDI_ACTIVATE"
216-
feature_vdi_deactivate = "VDI_DEACTIVATE"
217-
feature_vdi_update = "VDI_UPDATE"
218-
feature_vdi_introduce = "VDI_INTRODUCE"
219-
feature_vdi_generate_config = "VDI_GENERATE_CONFIG"
220-
feature_vdi_reset_on_boot = "VDI_RESET_ON_BOOT"
221-
222-
def connect():
223-
return xmlrpclib.Server("http://localhost:80")

python/xapi/storage/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#!/usr/bin/env python
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#!/usr/bin/env python

python/xapi/storage/common.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python
2+
3+
from xapi.storage import log
4+
import xapi
5+
import subprocess
6+
7+
8+
# [call dbg cmd_args] executes [cmd_args]
9+
# if [error] and exit code != expRc, log and throws a BackendError
10+
# if [simple], returns only stdout
11+
12+
13+
def call(dbg, cmd_args, error=True, simple=True, expRc=0):
14+
log.debug("%s: Running cmd %s" % (dbg, cmd_args))
15+
p = subprocess.Popen(
16+
cmd_args,
17+
stdout=subprocess.PIPE,
18+
stderr=subprocess.PIPE,
19+
close_fds=True)
20+
stdout, stderr = p.communicate()
21+
if error and p.returncode != expRc:
22+
log.error("%s: %s exitted with code %d: %s" %
23+
(dbg, " ".join(cmd_args), p.returncode, stderr))
24+
raise xapi.InternalError("%s exitted with non-zero code %d: %s"
25+
% (" ".join(cmd_args), p.returncode, stderr))
26+
if simple:
27+
return stdout
28+
return stdout, stderr, p.returncode

python/xapi/storage/log.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import logging
2+
import logging.handlers
3+
import sys
4+
import xapi
5+
6+
7+
LOG_LEVEL = logging.DEBUG
8+
# LOG to local2 which is currently mapped to /var/log/SMlog for SM
9+
LOG_SYSLOG_FACILITY = logging.handlers.SysLogHandler.LOG_LOCAL2
10+
LOG_TO_STDERR = False
11+
12+
13+
def configure_logging():
14+
_LOGGER.setLevel(LOG_LEVEL)
15+
16+
formatter = logging.Formatter(
17+
'%(asctime)s - [%(process)d] - %(levelname)s - %(message)s',
18+
'%Y-%m-%d %H:%M:%S')
19+
20+
handlers = []
21+
22+
# Log to syslog
23+
handlers.append(logging.handlers.SysLogHandler(
24+
address='/dev/log',
25+
facility=LOG_SYSLOG_FACILITY))
26+
27+
if LOG_TO_STDERR:
28+
# Write to stderr
29+
handlers.append(logging.StreamHandler(sys.stderr))
30+
31+
# Configure and add handlers
32+
for handler in handlers:
33+
handler.setLevel(LOG_LEVEL)
34+
handler.setFormatter(formatter)
35+
_LOGGER.addHandler(handler)
36+
37+
38+
def debug(message, *args, **kwargs):
39+
_LOGGER.debug(message, *args, **kwargs)
40+
41+
42+
def info(message, *args, **kwargs):
43+
_LOGGER.info(message, *args, **kwargs)
44+
45+
46+
def error(message, *args, **kwargs):
47+
_LOGGER.error(message, *args, **kwargs)
48+
49+
50+
def log_call_argv():
51+
info("called as: %s" % (sys.argv))
52+
53+
54+
def handle_unhandled_exceptions(exception_type, exception_value,
55+
exception_traceback):
56+
if not issubclass(exception_type, KeyboardInterrupt):
57+
if issubclass(exception_type, xapi.XenAPIException):
58+
info("Returned exception to XAPI", exc_info=(exception_type,
59+
exception_value,
60+
exception_traceback))
61+
else:
62+
error("Unhandled exception", exc_info=(exception_type,
63+
exception_value,
64+
exception_traceback))
65+
sys.__excepthook__(exception_type, exception_value, exception_traceback)
66+
67+
68+
_LOGGER = logging.getLogger()
69+
configure_logging()
70+
sys.excepthook = handle_unhandled_exceptions

0 commit comments

Comments
 (0)