#!/usr/bin/python import sys import os import argparse import json import build_functions print os.environ.get("USER") ####################################################### parser = argparse.ArgumentParser(description='Program to automate nss builds using mock.', version = '0.9 beta', add_help=True, conflict_handler='resolve', epilog='This program is designed to be used both on the command line or by cron') #parser = argparse.ArgumentParser(description='Program to automate nss builds using mock.', version = '0.9 beta')#, add_help=True) parser.add_argument("-d", "--debug", action="store_true", default=True, help="show debug output") parser.add_argument("-t", "--test", action="store_true", default=False, help="test mode (for debugging)") parser.add_argument( '-f', '--flavor', action="store", dest="flavor", default='nss', help='specify the flavor of the build. [default=nss]') #parser.add_argument( # '-p', # '--platform', # action="store", # dest="platform", # default=None, # help='specify a platform to use for mock config. [default=None] NOT IMPLEMENTED') parser.add_argument( '-r', '--rel', action="store", dest="rel", default=None, choices=("6", "7" ), help='specify a release to use for mock config. [default=None]') parser.add_argument( '-a', '--arch', action="store", dest="arch", default=None, choices=("i386", "x86_64"), help='specify an arch to use for mock config. [default=None]') parser.add_argument( '-l', '--local', action="store_true", dest="localBuild", default=False, help='perform a build in the current working diretory. [default=False]') parser.add_argument( '-mm', '--mailme', action="store_true", dest="mailMe", #default=True, default=False, help='send email to kwright@redhat.com. [default=False') parser.add_argument( '-sb', '--skipbuild', action="store_true", dest="skipBuild", default=False, help='skip the build portion of the program. [default=False] ') parser.add_argument( '-sc', '--skipcopy', action="store_true", dest="skipCopy", default=False, help='skip the copy portion of the program. [default=False] ') parser.add_argument( '-sw', '--skipwget', action="store_true", dest="skipWget", default=False, help='skip the wget portion of the program. [default=False] ') parser.add_argument( '-b', '--build', action='store', dest='nssPackageList', nargs='+', default=['nspr', 'nss-util', 'nss-softokn', 'nss', 'certmonger', 'crypto-utils', 'curl', 'mod_nss', 'mod_revocator' ], help='specify a list of one of more builds to performm. ', choices=('nspr', 'nss-util', 'nss-softokn', 'nss')) parser.add_argument( '-m', '--mock_cfg', action="store", dest="mockCfgList", nargs='+', default=["rhel-6-i386", "rhel-6-x86_64"], help='spcify a list of one or more mock configs to use. [default = rhel-6-i386", "rhel-6-x86_64]', choices=("rhel-6-i386", "rhel-6-x86_64")) options = parser.parse_args() #if args.servername is None and not args.dry_run: def print_debug(msg): if options.debug: print "DEBUG: %s" % (msg) #TODO: figure out some logic about which parameters can be used together ####################################################### workbase = os.environ['HOME'] scriptsDir = workbase + "/scripts" pythonDir=scriptsDir + "/build" sys.path.append(pythonDir) from build_functions import * ####################################################### if options.test: options.debug = True options.mailMe = True if options.skipCopy: options.skipWget = True if options.skipBuild and options.nssPackageList: print "INFO: --skipBuild and --build cannot be used together" print_debug("test = %s " % options.test) print_debug("debug = %s " % options.debug) #print_debug("platform = %s " % options.platform) print_debug("release = %s " % options.rel) print_debug("arch = %s " % options.arch) print_debug("flavor = %s " % options.flavor) print_debug("mailMe = %s " % options.mailMe) print_debug("localBuild = %s " % options.localBuild) print_debug("skipBuild = %s " % options.skipBuild) print_debug("skipCopy = %s " % options.skipCopy) print_debug("skipWget = %s " % options.skipWget) print_debug("nssPackageList = %s " % options.nssPackageList) print_debug("mockCfgList = %s " % options.mockCfgList) ####################################################### mockCfgList=[] for mock_cfg in options.mockCfgList: [platform, rel, arch] = mock_cfg.split("-") if options.rel is not None: print_debug("Release = %s" % options.rel) mockCfgList.append("-".join([platform, options.rel, arch])) else: print_debug("Release not defind") mockCfgList = options.mockCfgList print_debug("mockCfgList = %s" % mockCfgList) for mock_cfg in options.mockCfgList: [platform, rel, arch] = mock_cfg.split("-") if options.arch is not None: print_debug("arch = %s" % options.arch) mockCfgList = [("-".join([platform, rel, options.arch]))] else: print_debug("arch not defind") mockCfgList = options.mockCfgList print_debug("mockCfgList = %s" % mockCfgList) ####################################################### #TODO use MAILTO or mailTo or receiver to pass as a arg #test to see if a variable is defined #try: #thevariable #except NameError: #print "well, it WASN'T defined after all!" #else: #print "sure, it was defined." ####################################################### #TODO use MAILTO or mailTo or receiver to pass as a arg if options.mailMe: mailTo="emaldona@redhat.com" else: #mailTo="rhcs-dev-list@redhat.com" mailTo="nss-nspr-devel@redhat.com" ####################################################### if options.localBuild is False: import datetime now = datetime.datetime.now() DT=now.strftime('%Y%m%d-%H%M%S') str(DT) buildDir = workbase + "/" + DT print_debug("DT = %s" % DT) else: buildDir = os.getcwd() DT=os.path.basename(buildDir) #need the DT for later when copying files. print_debug("DT = %s" % DT) print_debug("buildDir = %s" % buildDir) nssPackageList = options.nssPackageList flavor = options.flavor ####################################################### progname = os.path.basename(__file__) message = "Subject: INFO: starting a build of from %s\n\nThe build directory is %s " % (progname, buildDir) #TODO. figure out how to send this email only to me. (ugh!) #email(message, mailTo) ####################################################### print_debug("Verifying the existence of the mock config file") mockDir = '/etc/mock' fileNameExt = '.cfg' for mock_cfg in mockCfgList: if os.path.isfile(os.path.join(mockDir, mock_cfg + fileNameExt)): print_debug("%s" % os.path.join(mockDir, mock_cfg + fileNameExt)) else: print "ERROR: %s doesn't exist." % os.path.join(mockDir, mock_cfg + fileNameExt) message = "Subject: ERROR: %s missing from /etc/mock\n\nERROR: %s missing from /etc/mock. Killing the build." % (mock_cfg + fileNameExt, mock_cfg) email(message, mailTo) sys.exit() ####################################################### buildStatusDict={} if options.skipBuild is False: for mock_cfg in mockCfgList: [platform, rel, arch] = mock_cfg.split("-") if rel == "18": nssPackageList.append("pki-tps") print_debug("Adding pki-tps to list of packages to build for %s %s" % (platform, rel)) print_debug("nssPackageList = %s" % nssPackageList) for package in nssPackageList: #status = build_pki(package, buildDir, mock_cfg, flavor, scriptsDir, options.debug, mailTo) status = build_generic_pkg(package, buildDir, mock_cfg, flavor, scriptsDir, options.debug, mailTo) buildStatusDict[(package,mock_cfg)]=status #################### #hope this line works print_debug("%s" % json.dumps(str(buildStatusDict), sort_keys=True, indent=4)) #################### print_debug("package %s completed with status %s for %s" % (package, status, mock_cfg)) # TODO fix issue with failed build not stopping creating the repo # NOTE the problem appears to be if the x86_64 bit builds all complete # successfully, then the dict only shows those builds then it thinks the # build is okay. also, dogtag uses build_pki, whereas nss # uses build_generic_pkg -- this may not apply to nss #print_debug("%s" % buildStatusDict) print_debug("%s" % json.dumps(str(buildStatusDict), sort_keys=True, indent=4)) #TODO write the output of buildStatusDict to a file in the home directory. #This way, I can easily tell if anything failed. ################################################################################ #NOTE: handle whether or not to copy the files over and create the rpm repo. #The logic is as follows: #if one of the packages failed to build, skipCopy is enalbed, don't copy #if the commandline option skipCopy is enalbled, don't copy #else skipCopy is disabled and the files get copied then the yum repos are created. ################################################################################ skipCopy=False for mock_cfg in mockCfgList: for (package, status) in buildStatusDict: print_debug("%s" % buildStatusDict[package,mock_cfg]) if buildStatusDict[package,mock_cfg]=="FAILED": skipCopy=True print "ERROR: skipCopy is %s (enabled) due to a failure of package %s on %s. The repo will NOT be created)" % (skipCopy, package, mock_cfg) #TODO Add the code here to copy the build logs over possibly only for the packages the failed? if options.skipCopy is True: message = "Subject: INFO: skipCopy was enabled from the commandline. Skipping copying to and/or creating the repo.\n\nThe build directory is %s." % (buildDir) print message email(message, mailTo) elif skipCopy is True: status_message="" for (package, status) in buildStatusDict: status_message += "build status of package: %s on %s: %s\n" % (package, status, buildStatusDict[package,mock_cfg]) message = "Subject: ERROR: %s skipping copying to and/or creating the repo.\n\nERROR: The repo was not created due to a failure of one or more packages.\n\nHere's the list of builds and their status:\n\n%s\n" % (flavor, status_message) #TODO add code to copy the log files over somewhere when the build failes. createRepoDirs(mock_cfg, flavor, DT, buildDir, options.test, options.debug, mailTo) print_debug("%s" % message) email(message, mailTo) elif skipCopy is False: #for mock_cfg in mockCfgList: print_debug("copy the files to the repo for %s" % mock_cfg) copyToRepo(mock_cfg, flavor, DT, buildDir, options.test, options.debug, options.skipWget, mailTo) sys.exit() if __name__ == '__main__': import sys try: main(sys.argv[1]) except IndexError: main()