extras-buildsys-temp/automation2/client archwelder.py, NONE, 1.1 archwelder_config.py, NONE, 1.1
Daniel Williams (dcbw)
fedora-extras-commits at redhat.com
Wed May 11 19:48:59 UTC 2005
- Previous message (by thread): extras-buildsys-temp/automation2/server - New directory
- Next message (by thread): extras-buildsys-temp/automation2/server aw_manager.py, NONE, 1.1 bm_server.py, NONE, 1.1 bm_server_config.py, NONE, 1.1 buildjob.py, NONE, 1.1 buildmaster.py, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: dcbw
Update of /cvs/fedora/extras-buildsys-temp/automation2/client
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv488/automation2/client
Added Files:
archwelder.py archwelder_config.py
Log Message:
2005-05-11 Dan Williams <dcbw at redhat.com>
* First cut of reworked build system. Please see the soon-to-be
committed README file for more details on how it works.
--- NEW FILE archwelder.py ---
#!/usr/bin/python -t
# 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 2005 Duke University
# written by Seth Vidal
# TODO: xml-rpc communication using 2-way ssl-cert-verified xmlrpc connection
# TODO: config from file not cli
import SimpleXMLRPCServer
import xmlrpclib
import socket
import os
import popen2
import sha
import time
import base64
import sys
import string
import time
from archwelder_config import CONFIG
DEBUG = False
def debugprint(stuff=''):
if DEBUG:
print stuff
def log(stuff=''):
print stuff
def is_done_status(status):
if status == 'done' or status == 'killed' or status == 'failed':
return True
return False
class ArchWelderMach:
"""puts things together for an arch - baseclass for handling builds for
other arches"""
def __init__(self, uniqid, srpm, target, mydir):
self._status = 'init'
self.target = target
self.mydir = mydir
self._output = []
self.srpm = srpm
self.uniqid = uniqid
def die(self, sig=15):
try:
os.kill(self.pobj.pid, sig)
except Exception, e:
print "Couldn't kill process %d: %s" % (self.pobj.pid, e)
self._status = 'killed'
return True
def _unlock(self):
print "%s: starting step 'unlocking'" % self.uniqid
cmd = '%s %s -r %s unlock' % (self.arch_command,
CONFIG('mach_cmd'), self.buildroot)
self.pobj = popen2.Popen4(cmd=cmd)
self._status = 'unlocking'
def _clean(self):
print "%s: starting step 'cleaning'" % self.uniqid
cmd = '%s %s -r %s clean' % (self.arch_command,
CONFIG('mach_cmd'), self.buildroot)
self.pobj = popen2.Popen4(cmd=cmd)
self._status = 'cleaning'
def _prep(self):
print "%s: starting step 'prepping'" % self.uniqid
cmd = '%s /%s -r %s setup prep' % (self.arch_command,
CONFIG('mach_cmd'), self.buildroot)
self.pobj = popen2.Popen4(cmd=cmd)
self._status = 'prepping'
def _build(self):
print "%s: starting step 'building'" % self.uniqid
os.chdir(self.mydir + '/' + self.buildarch)
cmd = '%s %s -r %s -c rebuild %s' % (self.arch_command,
CONFIG('mach_cmd'), self.buildroot, self.srpm)
self.pobj = popen2.Popen4(cmd=cmd)
self._status = 'building'
def start(self):
# check for existence of srpm before going on
self._unlock()
def process(self):
if not is_done_status(self._status):
# If we're done with a step, advance to next one
exit_status = self.pobj.poll()
if exit_status == 0:
if self._status == 'unlocking':
self._clean()
elif self._status == 'cleaning':
self._prep()
elif self._status == 'prepping':
self._build()
elif self._status == 'building':
print "%s: Job done." % self.uniqid
self._status = 'done'
else:
print "Bad status %s encountered!" % self._status
elif exit_status > 0:
print "%s: job failed!\n" % self.uniqid
self._status = 'failed'
else:
# mach process still running
pass
def status(self):
return self._status
def logs(self):
self._output.extend(self.pobj.fromchild.readlines())
return self._output
class i386Arch(ArchWelderMach):
def __init__(self, uniqid, srpm, target, mydir, buildarch='i386'):
self.buildroot = '%s-%s-i386-%s' % (target, CONFIG('distro_name'),
CONFIG('repo_name'))
self.buildarch = buildarch
self.arch_command = '/usr/bin/setarch i686'
ArchWelderMach.__init__(self, uniqid, srpm, target, mydir)
class x86_64Arch(ArchWelderMach):
def __init__(self, uniqid, srpm, target, mydir, buildarch='x86_64'):
self.buildroot = '%s-%s-x86_64-%s' % (target, CONFIG('distro_name'),
CONFIG('repo_name'))
self.buildarch = buildarch
self.arch_command = ''
ArchWelderMach.__init__(self, uniqid, srpm, target, mydir)
class PPCArch(ArchWelderMach):
def __init__(self, uniqid, srpm, target, mydir, buildarch='ppc'):
self.buildroot = '%s-%s-ppc-%s' % (target, CONFIG('distro_name'),
CONFIG('repo_name'))
self.buildarch = buildarch
self.arch_command = ''
ArchWelderMach.__init__(self, uniqid, srpm, target, mydir)
class PPC64Arch(ArchWelderMach):
def __init__(self, uniqid, srpm, target, mydir, buildarch='ppc64'):
self.buildroot = '%s-%s-ppc64-%s' % (target, CONFIG('distro_name'),
CONFIG('repo_name'))
self.buildarch = buildarch
self.arch_command = ''
ArchWelderMach.__init__(self, uniqid, srpm, target, mydir)
# Keep this global scope, used in __main__
welder_dict = { 'i386':i386Arch,
'i486':i386Arch,
'i586':i386Arch,
'i686':i386Arch,
'athlon':i386Arch,
'x86_64':x86_64Arch,
'amd64':x86_64Arch,
'ia32e':x86_64Arch,
'ppc':PPCArch,
'ppc32':PPCArch,
'ppc64':PPC64Arch,
}
def getArchWelder(uniqid, srpm, target, mydir, buildarch, localarches):
"""hand it an arch it hands you back the archwelder instance you need"""
if not welder_dict.has_key(buildarch):
# raise an exception here bitching about no place to build for that arch
pass
if buildarch == 'noarch':
if len(localarches) > 0:
welder = welder_dict[localarches[0]]
else:
if buildarch in localarches:
welder = welder_dict[buildarch]
awp = welder(uniqid, srpm, target, mydir, buildarch)
return awp
class XMLRPCArchWelderServer:
def __init__(self, localarches):
self.ids = {} # unique id => awclass instance
self.localarches = localarches
self.cur_job = 0
def _process(self):
# Give jobs some time to update their status and do their thing
job = 0
for (uniqid, awp) in self.ids.iteritems():
awp.process()
if not is_done_status(awp.status()):
job = uniqid
self.cur_job = job # Update current job
def start(self, srpm, target, stagedir, buildarch):
if self.cur_job != 0:
print "Tried to build '%s' when already buiding something" % srpm
return 0
cur_time = time.time()
check = '%d %s %s %s' % (cur_time, srpm, target, buildarch)
sum = sha.new()
sum.update(check)
uniqid = sum.hexdigest()
awp = getArchWelder(uniqid, srpm, target, stagedir, buildarch, self.localarches)
if awp != None:
self.ids[uniqid] = awp
awp.start()
log("%s: started %s on %s arch %s at time %d" % (uniqid, srpm,
target, buildarch, cur_time))
else:
log("%s: Failed request for %s on %s UNSUPPORTED arch %s at time %d" %
(uniqid, srpm, target, buildarch, cur_time))
uniqid = 0
self.cur_job = uniqid
return uniqid
def status(self, uniqid=None):
awp = self.ids[uniqid]
if not awp:
return ''
return awp.status()
def die(self, uniqid=None):
awp = self.ids[uniqid]
return awp.die()
def logs(self, uniqid=None):
awp = self.ids[uniqid]
result = []
for line in awp.logs():
enc = base64.encodestring(line)
result.append(enc)
return result
def listjobs(self):
return self.ids.keys()
def get_cur_job(self):
""" Are we currently building something? """
return self.cur_job
def supported_arches(self):
return self.localarches
class MyXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):
""" XMLRPC server subclass that turns on SO_REUSEADDR """
def __init__(self, address):
SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self, addr=address, logRequests=False)
def server_bind(self):
self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
self.socket.bind(self.server_address)
if __name__ == '__main__':
if len(sys.argv) < 3:
print "Usage:\n"
print " %s <hostname> <archlist>\n" % sys.argv[0]
print " <hostname> - hostname or IP address of this machine"
print " <archlist> - space-separated list of arches this machine can build"
# pretty-print the available archlist
archlist = ""
avail_arches = welder_dict.keys()
avail_arches.sort()
for a in avail_arches:
archlist = archlist + a
if a != avail_arches[len(avail_arches)-1]:
archlist = archlist + ", "
print " Available arches: [ %s ]\n" % archlist
sys.exit(1)
hostname = sys.argv[1]
localarches = sys.argv[2:]
print "Binding to address '%s' with arches: [%s]" % (hostname, string.join(localarches))
server = MyXMLRPCServer((hostname, 8888))
aws = XMLRPCArchWelderServer(localarches)
server.register_instance(aws)
last_time = time.time()
while True:
server.handle_request()
cur_time = time.time()
if cur_time >= last_time + 10:
# do some work every 10s or so
aws._process()
last_time = time.time()
--- NEW FILE archwelder_config.py ---
# Configuration file for archwelder.py
config_opts = {}
config_opts['mach_cmd'] = "/usr/bin/mach"
config_opts['distro_name'] = "fedora"
config_opts['repo_name'] = "extras"
def CONFIG (key):
return config_opts[key]
- Previous message (by thread): extras-buildsys-temp/automation2/server - New directory
- Next message (by thread): extras-buildsys-temp/automation2/server aw_manager.py, NONE, 1.1 bm_server.py, NONE, 1.1 bm_server_config.py, NONE, 1.1 buildjob.py, NONE, 1.1 buildmaster.py, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-extras-commits
mailing list