summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2010-02-27 15:46:03 -0500
committerColin Walters <walters@verbum.org>2010-02-27 15:46:03 -0500
commita8902aa1928f719d173a0ed10498939bb85b8604 (patch)
tree14995d57e6c2b645bf1effad0572b5273edfa608
parentc3e20536051ef4c7b32fe4c6820bbab1dcaca472 (diff)
downloadfedpkg-make-pull-a8902aa1928f719d173a0ed10498939bb85b8604.tar.gz
fedpkg-make-pull-a8902aa1928f719d173a0ed10498939bb85b8604.tar.xz
fedpkg-make-pull-a8902aa1928f719d173a0ed10498939bb85b8604.zip
[fedpkg-autobuilder] New script, suitable for running from supervisor
-rwxr-xr-xfedpkg-autobuilder191
1 files changed, 191 insertions, 0 deletions
diff --git a/fedpkg-autobuilder b/fedpkg-autobuilder
new file mode 100755
index 0000000..00e0670
--- /dev/null
+++ b/fedpkg-autobuilder
@@ -0,0 +1,191 @@
+#!/usr/bin/python
+
+# fedpkg-autobuilder:
+# Daemon which runs fedpkg-pull-build-chain continually.
+#
+# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php)
+# Copyright (C) 2010 Red Hat, Inc.
+# Written by Colin Walters <walters@verbum.org>
+
+import getopt
+import os
+import sys
+import subprocess
+import shutil
+import logging
+import xml.dom.minidom
+import ConfigParser
+
+import dbus, dbus.service
+import glib
+import gobject
+from dbus.mainloop.glib import DBusGMainLoop
+DBusGMainLoop(set_as_default=True)
+
+PULLBUILD_SERVICE = 'org.fedoraproject.FedpkgPullBuildChain'
+PULLBUILD_OBJPATH = '/org/fedoraproject/FedpkgPullBuildChain'
+
+# First ensure we have a bus
+if not 'DBUS_SESSION_BUS_ADDRESS' in os.environ:
+ args = ['dbus-launch']
+ args.extend(sys.argv)
+ sys.execvp('dbus-launch', args)
+
+def check_call_verbose(*args, **kwargs):
+ print "Running: %r" % (args[0], )
+ subprocess.check_call(*args, **kwargs)
+
+STATE_BURNING = 'burning'
+STATE_SUCCESS = 'success'
+
+STATUS_ACTIVE = 'active'
+STATUS_IDLE = 'idle'
+
+class Autobuilder(dbus.service.Object):
+ def __init__(self, config):
+ dbus.service.Object.__init__(self, dbus.SessionBus(), '/org/fedoraproject/FedpkgAutoBuilder')
+ self._config = config
+
+ self._resultdir = config.get('build', 'resultdir')
+ self._release = config.get('build', 'release')
+
+ try:
+ self._architectures = config.get('build', 'architectures').split()
+ except ConfigParser.NoOptionError, e:
+ self._architectures = None
+
+ modules = config.get('build', 'modules')
+ self._modules = modules.split()
+
+ self._pullbuild_pid = None
+
+ bus = dbus.SessionBus()
+ self._bus_proxy = dbus.Interface(bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus'),
+ 'org.freedesktop.DBus')
+ self._bus_proxy.connect_to_signal('NameOwnerChanged', self.__on_name_owner_changed)
+ self._pullbuild_proxy = None
+
+ self._status = STATUS_IDLE
+
+ self._state = STATE_BURNING
+ self._statedata = {}
+ self._reread_state()
+
+ @dbus.service.signal(dbus_interface='org.fedoraproject.FedpkgAutoBuilder',
+ signature='sa{sv}')
+ def StateChanged(self, state, statedata):
+ pass
+
+ @dbus.service.signal(dbus_interface='org.fedoraproject.FedpkgAutoBuilder',
+ signature='s')
+ def StatusChanged(self, status):
+ pass
+
+ @dbus.service.method(dbus_interface='org.fedoraproject.FedpkgAutoBuilder',
+ in_signature='', out_signature='sa{sv}')
+ def GetState(self):
+ return (self._state, self._statedata)
+
+ @dbus.service.method(dbus_interface='org.fedoraproject.FedpkgAutoBuilder',
+ in_signature='', out_signature='s')
+ def GetStatus(self):
+ return self._status
+
+ def _reread_state(self):
+ self._state = STATE_SUCCESS
+ self._statedata = {}
+ for module in self._modules:
+ lastbuild_path = os.path.join('_build', module, 'lastbuild-status')
+ if not os.path.exists(lastbuild_path):
+ self._state = STATE_BURNING
+ self._statedata['failed'] = module
+ break
+ f = open(lastbuild_path)
+ status = f.read()
+ f.close()
+ if status != 'success':
+ self._state = STATE_BURNING
+ self._statedata['failed'] = odule
+ break
+ self.StateChanged(self._state, self._statedata)
+
+ def initiate_build(self):
+ if self._pullbuild_pid is not None:
+ logging.info("Can't initiate build, one is in progress")
+ return
+ args = ['fedpkg-pull-build-chain', '--resultdir=' + self._resultdir, '--release=' + self._release]
+ if self._architectures is not None:
+ for arch in self._architectures:
+ args.append('--arch=' + arch)
+
+ args.extend(self._modules)
+
+ (self._pullbuild_pid, _, _, _) = glib.spawn_async(args, flags=glib.SPAWN_DO_NOT_REAP_CHILD|glib.SPAWN_SEARCH_PATH)
+ logging.info("started builder, pid=%d" % (self._pullbuild_pid, ))
+ self._status = STATUS_ACTIVE
+ self.StatusChanged(self._status)
+ glib.child_watch_add(self._pullbuild_pid, self.__on_builder_exited)
+
+ def __on_name_owner_changed(self, name, prev_owner, new_owner):
+ if name != PULLBUILD_SERVICE:
+ return
+ if new_owner == '':
+ del self._pullbuild_proxy
+ self._pullbuild_proxy = None
+ return
+ logging.debug("NameOwnerChanged %r %r %r" % (name, prev_owner, new_owner))
+ bus = dbus.SessionBus()
+ proxy = bus.get_object(PULLBUILD_SERVICE, PULLBUILD_OBJPATH)
+ self._pullbuild_proxy = dbus.Interface(proxy, PULLBUILD_SERVICE)
+ self._pullbuild_proxy.connect_to_signal('StateChanged', self.__on_builder_state_changed)
+
+ def __on_builder_state_changed(self, state, statedata):
+ logging.info("builder state=%s statedata=%r" % (state, statedata))
+
+ def __on_builder_exited(self, pid, condition):
+ logging.info("builder pid=%d exited, condition=%r", pid, condition)
+ self._pullbuild_pid = None
+ self._status = STATUS_IDLE
+ self.StatusChanged(self._status)
+
+ def start(self):
+ self.initiate_build()
+
+def main():
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], '', ['conf='])
+ except Getopt.GetoptError, e:
+ print unicode(e)
+ print "Usage: fedpkg-autobuilder --conf=file.conf"
+
+ conf = None
+ for o, a in opts:
+ if o in ('-c', '--conf'):
+ conf = a
+
+ if not conf:
+ print "Must specify --conf=file.conf"
+ sys.exit(1)
+
+ logging.basicConfig(level=logging.INFO)
+
+ parser = ConfigParser.SafeConfigParser()
+ parser.read(conf)
+ build_time = int(parser.get('autobuild', 'time'))
+
+ f = open('session-address', 'w')
+ f.write(os.environ['DBUS_SESSION_BUS_ADDRESS'])
+ f.close()
+ bus = dbus.SessionBus()
+ bus_name = dbus.service.BusName('org.fedoraproject.FedpkgAutobuilder', bus=bus)
+
+ loop = gobject.MainLoop()
+
+ builder = Autobuilder(parser)
+ builder.initiate_build()
+ glib.timeout_add(build_time * 1000, lambda: builder.initiate_build() or True)
+
+ loop.run()
+
+if __name__ == '__main__':
+ main()