extras-buildsys/common Commands.py, NONE, 1.1 HTTPServer.py, 1.12, 1.13 Makefile, 1.11, 1.12 URLopener.py, 1.1, 1.2
Daniel Williams (dcbw)
fedora-extras-commits at redhat.com
Fri Apr 28 03:17:43 UTC 2006
- Previous message (by thread): extras-buildsys/builder Builder.py, NONE, 1.1 BuilderMock.py, NONE, 1.1 main.py, NONE, 1.1 Config.py, 1.2, 1.3 Makefile, 1.4, 1.5 builder.py, 1.54, NONE
- Next message (by thread): extras-buildsys/server BuildMaster.py, 1.39, 1.40 Builder.py, 1.33, 1.34 BuilderManager.py, 1.21, 1.22 Config.py, 1.16, 1.17 main.py, 1.20, 1.21
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: dcbw
Update of /cvs/fedora/extras-buildsys/common
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv5292/common
Modified Files:
HTTPServer.py Makefile URLopener.py
Added Files:
Commands.py
Log Message:
2006-04-27 Dan Williams <dcbw at redhat.com>
Commit partial rework of builder<->server communcation.
--- NEW FILE Commands.py ---
# 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Copyright 2006 Dan Williams <dcbw at redhat.com> and Red Hat, Inc.
""" Common functions and constants for command parsing, receiving, and sending """
import threading
CMD_NAME_ERROR = "Error"
CMD_NAME_NOP = "NOP"
CMD_NAME_TARGETS = "Targets"
CMD_NAME_SLOTS = "Slots"
CMD_NAME_NEW_JOB_REQ = "NewJob"
CMD_NAME_NEW_JOB_ACK = "NewJobAck"
class SequenceGenerator(object):
"""An class that atomically increments a number."""
def __init__(self):
self._lock = threading.Lock()
self._seq = 0
def __del__(self):
del self._lock
del self._seq
def next(self):
"""Returns the next number in the object's sequence."""
self._lock.acquire()
num = self._seq = self._seq + 1
self._lock.release()
return num
def serialize_to_command_stream(cmds):
stream = []
for cmd in cmds:
stream.append(cmd.serialize())
return stream
def deserialize_command_stream(cmd_stream):
""" Converts a command stream into a list of command objects.
Argument is a python list of serialized command objects, each
represented by a python dict.
Return value is a python list of command objects.
"""
cmds = []
for item in cmd_stream:
cmd = PlgCommand.deserialize(item)
cmds.append(cmd)
return cmds
class PlgCommand(object):
"""Abstract base class for all builder<->server command
objects."""
_need_ack = False
def __init__(self, name, seq=0):
"""Initialize the command object. Not used directly,
but called by subclasses.
The NAME argument is the name (type) of the command.
The SEQ argument is the command's sequence number, which
should be unique among all commands the program sends.
"""
self._name = name
self._seq = seq
def deserialize(cmd_stream):
"""Class method that deserializes a command stream into
a particular subclass of command object.
The CMD_STREAM argument is a python dict representing the
serialized state of the command.
Return value is the command object.
"""
cmd = name = args = seq = None
try:
# Pull out required fields
name = cmd_stream['name']
args = cmd_stream['args']
seq = cmd_stream['sequence']
except (KeyError, TypeError), e:
print "PlgCommand deserialize error: %s" % e
return None
# Create the specific command object from the command's name
if name == CMD_NAME_ERROR:
cmd = PlgCommandError._deserialize(args)
elif name == CMD_NAME_TARGETS:
cmd = PlgCommandTargets._deserialize(args)
elif name == CMD_NAME_SLOTS:
cmd = PlgCommandSlots._deserialize(args)
elif name == CMD_NAME_NEW_JOB_REQ:
cmd = PlgCommandNewJobReq._deserialize(args)
elif name == CMD_NAME_NEW_JOB_ACK:
cmd = PlgCommandNewJobAck._deserialize(args)
# If command creation was successful, set the sequence
# number from the command stream on the command. We don't
# want to expose the sequence number to subclasses because
# they should never need it.
if cmd:
cmd._seq = seq
return cmd
deserialize = staticmethod(deserialize)
def name(self):
"""Returns the command's name."""
return self._name
def seq(self):
"""Returns the command's sequece number."""
return self._seq
def need_ack(self):
"""Returns a boolean stating whether this command requires
an acknowledgement command or not."""
return self._need_ack
def _serialize(self, args):
"""Serializes the basic command information into the command
stream, returning a python dict. Should only be called by
subclasses, after determining the arguments the subclass wishes
to serialize into the command.
Argument ARGS is a python dict containing the subclass-specific
command's arguments.
"""
if not args:
raise ValueError("args cannot be None")
cmd = {}
cmd['name'] = self._name
cmd['sequence'] = self._seq
cmd['args'] = args
return cmd
def __str__(self):
return "%s(seq: %d)" % (self._name, self._seq)
__repr__ = __str__
class PlgCommandAck(PlgCommand):
"""Abstract base class for acknowledgement commands."""
def __init__(self, name, acked_seq, seq=0):
PlgCommand.__init__(self, name, seq)
self._acked_seq = acked_seq
def _deserialize_acked_seq(args):
try:
acked_seq = args['acked_seq']
except KeyError, TypeError:
raise ValueError("No 'acked_seq' argument found.")
return acked_seq
_deserialize_acked_seq = staticmethod(_deserialize_acked_seq)
def _serialize(self, args):
args['acked_seq'] = self._acked_seq
return PlgCommand._serialize(self, args)
def acked_seq(self):
return self._acked_seq
class PlgCommandNop(PlgCommand):
def __init__(self, seq=0):
PlgCommand.__init__(self, CMD_NAME_NOP, seq)
def _deserialize(args):
return PlgCommandNop()
_deserialize = staticmethod(_deserialize)
def serialize(self):
return PlgCommand._serialize(self, {})
class PlgCommandError(PlgCommand):
def __init__(self, reason, seq=0):
PlgCommand.__init__(self, CMD_NAME_ERROR, seq)
self._reason = reason
def _deserialize(args):
try:
reason = args['reason']
except KeyError, TypeError:
raise ValueError("No 'reason' argument found.")
return PlgCommandError(reason)
_deserialize = staticmethod(_deserialize)
def serialize(self):
args = {}
args['reason'] = self._reason
return PlgCommand._serialize(self, args)
def reason(self):
return self._reason
def __str__(self):
return "%s(seq: %d, reason: %s)" % (self._name, self._seq, self._reason)
class PlgCommandSlots(PlgCommand):
def __init__(self, free, maximum, seq=0):
PlgCommand.__init__(self, CMD_NAME_SLOTS, seq)
self._free_slots = free
self._max_slots = maximum
def _deserialize(args):
try:
free = args['free']
except ValueError, TypeError:
raise ValueError("No 'free' argument found.")
try:
maximum = args['max']
except KeyError, TypeError:
raise ValueError("No 'max' argument found.")
return PlgCommandSlots(free, maximum)
_deserialize = staticmethod(_deserialize)
def serialize(self):
args = {}
args['free'] = self._free_slots
args['max'] = self._max_slots
return PlgCommand._serialize(self, args)
def free_slots(self):
return self._free_slots
def max_slots(self):
return self._max_slots
def __str__(self):
return "%s(seq: %d, slots: (%d of %d))" % (self._name, self._seq, self._free_slots, self._max_slots)
class PlgCommandTargets(PlgCommand):
def __init__(self, targets, seq=0):
PlgCommand.__init__(self, CMD_NAME_TARGETS, seq)
self._targets = targets
def _deserialize(args):
try:
targets = args['targets']
except KeyError, TypeError:
raise ValueError("No 'targets' argument found.")
# Sanity checking on targets argument
if type(targets) != type([]):
raise ValueError("'targets' argument was not a list.")
for target in targets:
try:
distro = target['distro']
tg = target['target']
basearch = target['arch']
repo = target['repo']
suparch = target['supported_arches']
except KeyError, e:
raise ValueError("Required item '%s' not found in a target." % e)
return PlgCommandTargets(targets)
_deserialize = staticmethod(_deserialize)
def serialize(self):
args = {}
args['targets'] = self._targets
return PlgCommand._serialize(self, args)
def targets(self):
return self._targets
def __str__(self):
return "%s(seq: %d, targets: %s)" % (self._name, self._seq, self._targets)
class PlgCommandNewJobReq(PlgCommand):
_need_ack = True
def __init__(self, parent_job, target_dict, srpm_url, seq=0):
PlgCommand.__init__(self, CMD_NAME_NEW_JOB_REQ, seq)
self._parent_job = parent_job # doesn't get serialized
self._target_dict = target_dict
self._srpm_url = srpm_url
def _deserialize(args):
try:
target_dict = args['target_dict']
except KeyError, TypeError:
raise ValueError("No 'target_dict' argument found.")
try:
srpm_url = args['srpm_url']
except KeyError, TypeError:
raise ValueError("No 'srpm_url' argument found.")
return PlgCommandNewJobReq(None, target_dict, srpm_url)
_deserialize = staticmethod(_deserialize)
def serialize(self):
args = {}
args['target_dict'] = self._target_dict
args['srpm_url'] = self._srpm_url
return PlgCommand._serialize(self, args)
def parent_job(self):
return self._parent_job
def target_dict(self):
return self._target_dict
def srpm_url(self):
return self._srpm_url
def __str__(self):
return "%s(seq: %d, target_dict: %s, srpm_url: %s)" % (self._name, self._seq, self._target_dict, self._srpm_url)
class PlgCommandNewJobAck(PlgCommandAck):
def __init__(self, archjob_id, msg, req_seq, seq=0):
PlgCommandAck.__init__(self, CMD_NAME_NEW_JOB_ACK, req_seq, seq)
self._archjob_id = archjob_id
self._msg = msg
def _deserialize(args):
try:
archjob_id = args['archjob_id']
msg = args['msg']
except KeyError, TypeError:
raise ValueError("No 'archjob_id' argument found.")
req_seq = PlgCommandAck._deserialize_acked_seq(args)
return PlgCommandNewJobAck(archjob_id, msg, req_seq)
_deserialize = staticmethod(_deserialize)
def serialize(self):
args = {}
args['archjob_id'] = self._archjob_id
args['msg'] = self._msg
return PlgCommandAck._serialize(self, args)
def archjob_id(self):
return self._archjob_id
def message(self):
return self._msg
Index: HTTPServer.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/common/HTTPServer.py,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- HTTPServer.py 27 Mar 2006 15:45:39 -0000 1.12
+++ HTTPServer.py 28 Apr 2006 03:17:40 -0000 1.13
@@ -183,8 +183,11 @@
self._server.stop()
t = time.time()
while not self._stopped:
- if time.time() > t + 2:
- break
+ try:
+ if time.time() > t + 2:
+ break
+ except KeyboardInterrupt:
+ pass
###########################################################
Index: Makefile
===================================================================
RCS file: /cvs/fedora/extras-buildsys/common/Makefile,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- Makefile 22 Jan 2006 02:08:56 -0000 1.11
+++ Makefile 28 Apr 2006 03:17:40 -0000 1.12
@@ -9,18 +9,20 @@
FILES = \
ArchUtils.py \
+ AuthedXMLRPCServer.py \
BaseConfig.py \
+ Commands.py \
CommonErrors.py \
+ daemonize.py \
DebugUtils.py \
ExecUtils.py \
FileDownloader.py \
- HTTPSURLopener.py \
+ FileUploader.py \
HTTPServer.py \
- AuthedXMLRPCServer.py \
SSLCommon.py \
SSLConnection.py \
+ URLopener.py \
XMLRPCServerProxy.py \
- daemonize.py \
__init__.py
clean:
Index: URLopener.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/common/URLopener.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- URLopener.py 27 Mar 2006 04:12:11 -0000 1.1
+++ URLopener.py 28 Apr 2006 03:17:40 -0000 1.2
@@ -40,7 +40,7 @@
buffer += '\r\n'
buffer += str(v) + '\r\n'
if sock:
- sock.send(buffer)
+ sock.send(buffer)
l += len(buffer)
for (k, v) in v_files:
fd = v
@@ -49,7 +49,7 @@
buffer=''
buffer += '--%s\r\n' % boundary
buffer += 'Content-Disposition: form-data; name="%s"; filename="%s"\r\n' \
- % (k, name)
+ % (k, name)
buffer += 'Content-Type: %s\r\n' % get_content_type(name)
buffer += 'Content-Length: %s\r\n' % file_size
buffer += '\r\n'
@@ -163,14 +163,14 @@
raise IOError(e)
if data is not None:
- if len(v_files) > 0:
- l = send_data(v_vars, v_files, boundary, h)
- elif len(v_vars) > 0:
- # if data is passed as dict ...
- data = urllib.urlencode(v_vars)
- h.send(data)
- else:
- h.send(data)
+ if len(v_files) > 0:
+ l = send_data(v_vars, v_files, boundary, h)
+ elif len(v_vars) > 0:
+ # if data is passed as dict ...
+ data = urllib.urlencode(v_vars)
+ h.send(data)
+ else:
+ h.send(data)
# close files
if data is not None:
- Previous message (by thread): extras-buildsys/builder Builder.py, NONE, 1.1 BuilderMock.py, NONE, 1.1 main.py, NONE, 1.1 Config.py, 1.2, 1.3 Makefile, 1.4, 1.5 builder.py, 1.54, NONE
- Next message (by thread): extras-buildsys/server BuildMaster.py, 1.39, 1.40 Builder.py, 1.33, 1.34 BuilderManager.py, 1.21, 1.22 Config.py, 1.16, 1.17 main.py, 1.20, 1.21
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-extras-commits
mailing list