extras-buildsys/client client.py, NONE, 1.1 Makefile, 1.1, 1.2 CONFIG.py, 1.9, NONE buildclient.py, 1.19, NONE

Daniel Williams (dcbw) fedora-extras-commits at redhat.com
Mon Jun 27 21:29:23 UTC 2005


Author: dcbw

Update of /cvs/fedora/extras-buildsys/client
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv17983/client

Modified Files:
	Makefile 
Added Files:
	client.py 
Removed Files:
	CONFIG.py buildclient.py 
Log Message:
2005-06-26  Dan Williams <dcbw at redhat.com>

    * Move stuff around.  The client that package maintainers will use
        to submit jobs is now in client/, and the actual build daemon
        has moved to builder/




--- NEW FILE client.py ---
#!/usr/bin/python
#
# 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 Dan Williams <dcbw at redhat.com> and Red Hat, Inc.

import sys, os
from plague import SSLXMLRPCServerProxy
import ConfigParser
import M2Crypto
import M2Crypto.m2xmlrpclib
import M2Crypto.X509
import socket


config = ConfigParser.ConfigParser()
config.add_section('Certs')
config.set('Certs', 'user-cert', '~/.fedora.cert')
config.set('Certs', 'user-key', '')
config.set('Certs', 'user-ca-cert', '~/.fedora-upload-ca.cert')
config.set('Certs', 'server-ca-cert', '~/.fedora-server-ca.cert')

config.add_section('Server')
config.set('Server', 'use_ssl', 'True')
config.set('Server', 'address', 'https://127.0.0.1:8887')

config.add_section('User')
config.set('User', 'email', 'foo at it.com')


config_file_path = os.path.expanduser('~/.package-builder.cfg')
config.read([config_file_path])


class ServerException:
    def __init__(self, message):
        self.message = message

class CommandException:
    def __init__(self, message):
        self.message = message


def enqueue(server, email, args):
    """ Enqueue a package on the server by CVS tag """

    if len(args) != 3:
        raise CommandException("Invalid command.  The 'enqueue' command only takes 3 arguments.")
    package = args[0]
    tag = args[1]
    target = args[2]
    use_ssl = config.get('Server', 'use_ssl')
    if use_ssl.lower() == 'true':
        (e, msg,) = server.enqueue(package, tag, target)
    else:
        (e, msg) = server.enqueue(email, package, tag, target)
    if e == -1:
        print "Server returned an error: %s" % msg
    else:
        print "Package %s enqueued." % package


def enqueue_srpm(server, email, args):
    """ Enqueue a package on the server by SRPM """

    if len(args) != 3:
        raise CommandException("Invalid command.  The 'enqueue_srpm' command only takes 3 arguments.")
    package = args[0]
    srpm = args[1]
    target = args[2]
    use_ssl = config.get('Server', 'use_ssl')
    if use_ssl.lower() == 'true':
        (e, msg) = server.enqueue_srpm(package, srpm, target)
    else:
        (e, msg) = server.enqueue_srpm(email, package, srpm, target)
    if e == -1:
        print "Server returned an error: %s" % msg
    else:
        print "Package %s enqueued." % package


def list_own_jobs(server, email):
    """
    Get a list of the jobs the current user owns.
    """

    try:
        args = { 'email' : email }
        jobs = server.list_jobs(args)
    except (M2Crypto.SSL.SSLError, socket.error), e:
        print "Error connecting to build server: '%s'" % e
        return

    for job in jobs:
        print job


def print_clients(banner, client_list):
        print "\n%s:" % banner
        print "-" * 70
        for client in client_list:
            string = "  " + client['address']
            string = string + " " * (40 - len(client['address']))
            for arch in client['arches']:
                string = string + arch + " "
            string = string + "    " + client['status']
            print string
        print ""


def update_clients(server, email):
    """
    Tell the build server to requery its build client list and re-add dropped
    clients that are now alive.
    """

    try:
        (e, msg, client_list) = server.update_clients()
        if len(client_list) > 0:
            print_clients("New Build Clients", client_list)
        else:
            print "No new build clients found."
    except (M2Crypto.SSL.SSLError, socket.error), e:
        print "Error connecting to build server: '%s'" % e


def list_clients(server, email):
    """
    Get a list of currently active build clients.
    """

    try:
        (e, msg, client_list) = server.list_clients()
        if len(client_list) > 0:
            print_clients("Active Build Clients", client_list)
        else:
            print "No active build clients found."
    except (M2Crypto.SSL.SSLError, socket.error), e:
        print "Error connecting to build server: '%s'" % e


def getXMLRPCServerProxy(use_ssl):
    """
    Return an XMLRPC server proxy object, either one that uses SSL with certificates
    for verification, or one that doesn't do any authentication/encryption at all.
    """

    server = None
    addr = config.get('Server', 'address')
    use_ssl = use_ssl.lower()
    if use_ssl == 'true':
        if addr.startswith("http:"):
            raise ServerException("Error: '%s' is not an SSL server, but the use_ssl config option set to True.  See %s" % (addr, config_file_path))
        else:
            certs = {}
            certs['cert'] = os.path.expanduser(config.get('Certs', 'user-cert'))
            client_key = config.get('Certs', 'user-key')
            # If client-key is empty, key assumed to be in user-cert
            certs['key'] = None
            if len(client_key) > 0:
                certs['key'] = os.path.expanduser(client_key)
            certs['ca_cert'] = os.path.expanduser(config.get('Certs', 'user-ca-cert'))
            certs['peer_ca_cert'] = os.path.expanduser(config.get('Certs', 'server-ca-cert'))
            server = SSLXMLRPCServerProxy.SSLXMLRPCServerProxy(certs, config.get('Server', 'address'))
    elif use_ssl == 'false':
        if addr.startswith("https:"):
            raise ServerException("Error: '%s' is an SSL server, but the use_ssl config option set to False.  See %s" % (addr, config_file_path))
        else:
            server = M2Crypto.m2xmlrpclib.ServerProxy(addr)
    else:
        raise ServerException("Unrecognized value for config '%s' option use_ssl.  See %s" % (use_ssl, config_file_path))

    return server


def getEmailAddress():
    """ Get email address either from certificate of config file """
    config_email = config.get('User', 'email')

    use_ssl = config.get('Server', 'use_ssl')
    if use_ssl.lower() == 'true':
        certfile = config.get('Certs', 'user-cert')
        certfile = os.path.expanduser(certfile)
        if not os.access(certfile, os.R_OK):
            print "%s does not exist or is not readable." % certfile
            sys.exit(1)
        cert = M2Crypto.X509.load_cert(certfile)
        # m2crypto 0.9 only has 'Email', so fall through to that
        # if 'emailAddress' fails
        try:
            cert_email = cert.get_subject().emailAddress
        except AttributeError:
            cert_email = cert.get_subject().Email
        if cert_email != config_email:
            print "Error: certificate's email address does not match the email address in the config file."
            sys.exit(1)

    return config_email



if __name__ == '__main__':
    if len(sys.argv) < 2:
        print "Usage:\npackage-builder.py <command>\n"
        print "      <command> is one of:"
        print "      build [package_name] [cvs_tag | srpm_path] [target]"
        print "      list"
        print "      update_clients"
        print "      list_clients"
	print ""
        sys.exit(1)

    # Write out config file if it doesn't exist
    if not os.path.exists(config_file_path):
        f = open(config_file_path, "w+")
        config.write(f)
        f.close()

    cmd = sys.argv[1]
    email = getEmailAddress()

    try:
        server = getXMLRPCServerProxy(config.get('Server', 'use_ssl'))
    except ServerException, e:
        print e.message
        sys.exit(1)

    if cmd == 'build':
        item = sys.argv[3]
        try:
            if item.endswith(".src.rpm") and os.path.exists(item):
                enqueue_srpm(server, email, sys.argv[2:])
            else:
                enqueue(server, email, sys.argv[2:])
        except CommandException, e:
            print e.message
    elif cmd == 'list':
        list_own_jobs(server, email)
    elif cmd == 'update_clients':
        update_clients(server, email)
    elif cmd == 'list_clients':
        list_clients(server, email)
    else:
        print "Unknown command."
        sys.exit(1)



Index: Makefile
===================================================================
RCS file: /cvs/fedora/extras-buildsys/client/Makefile,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Makefile	26 Jun 2005 14:52:24 -0000	1.1
+++ Makefile	27 Jun 2005 21:29:21 -0000	1.2
@@ -7,11 +7,6 @@
 clean:
 	rm -f *.pyc *.pyo *~ *.bak
 
-INSTDIR=$(DESTDIR)/$(BINDIR)/$(PKGNAME)/client
-CONFIGDIR=$(DESTDIR)/$(ETCDIR)/$(PKGNAME)/client
-
 install:
-	$(MKDIR) -p $(INSTDIR)
-	$(INSTALL) -m 755 buildclient.py $(INSTDIR)/$(PKGNAME)-client
-	$(MKDIR) -p $(CONFIGDIR)
-	$(INSTALL) -m 755 CONFIG.py $(CONFIGDIR)/CONFIG.py
+	$(MKDIR) -p $(DESTDIR)/$(BINDIR)
+	$(INSTALL) -m 755 client.py $(DESTDIR)/$(BINDIR)/$(PKGNAME)-client


--- CONFIG.py DELETED ---


--- buildclient.py DELETED ---




More information about the fedora-extras-commits mailing list