def _do_download(task, session, opts): ''' Perform download of a single task. ''' if opts.arches: print 'Downloading %s rpms from task %i: %s' \ % (', '.join(opts.arches), task['id'], koji.taskLabel(task)) else: print 'Downloading rpms from task %i: %s' \ % (task['id'], koji.taskLabel(task)) base_path = koji.pathinfo.taskrelpath(task['id']) output = session.listTaskOutput(task['id']) prog_meter = urlgrabber.progress.TextMeter() if output == []: print "This build is empty, no files to download" sys.exit(1) for filename in output: if opts.nologs and filename.endswith('log'): continue elif filename.endswith('.rpm'): if opts.arches: arch = filename.rsplit('.', 3)[2] if arch not in opts.arches: continue if 'debuginfo' in filename and opts.nodebug: continue what = opts.baseurl + base_path + '/' + filename urlgrabber.grabber.urlgrab(what, progress_obj=prog_meter)
def _download_scratch_rpms(parser, task_ids, opts): ''' Given build id, tasks and CLI options download build results to current dir. ''' if not os.access(os.getcwd(), os.R_OK | os.W_OK | os.X_OK): raise IOError("Insufficient permissons for current directory." " Aborting download") session = koji.ClientSession(opts.huburl) for task_id in task_ids: task = session.getTaskInfo(task_id, request=True) if not task: parser.error('Invalid task ID: %i' % task_id) elif task['state'] in (koji.TASK_STATES['FREE'], koji.TASK_STATES['OPEN']): parser.error('Task %i has not completed' % task['id']) elif task['state'] != koji.TASK_STATES['CLOSED']: parser.error('Task %i did not complete successfully' % task['id']) if task['method'] == 'build': print 'Getting rpms from children of task %i: %s' \ % (task['id'], koji.taskLabel(task)) task_opts = {'parent': task_id, 'method': 'buildArch', 'state': [koji.TASK_STATES['CLOSED']], 'decode': True} tasks = session.listTasks(opts=task_opts) elif task['method'] == 'buildArch': tasks = [task] else: parser.error('Task %i is not a build or buildArch task' % task['id']) for task in tasks: _do_download(task, session, opts)
def get_build_info(build_id, nvr=False): """Get the dist-git commit and NVR when given a Koji build ID or NVR.""" session = koji.ClientSession(HUB, KOJI_OPTIONS) if not session.krb_login(**KERBEROS_OPTIONS): raise Exception("Failed to log into Koji") if nvr is True: info = session.getBuild(build_id) else: info = session.getBuild(int(build_id)) if info is None: raise ValueError("No such build: {}".format(build_id)) task = None if info['task_id']: task = session.getTaskInfo(info['task_id'], request=True) nvrtag = info["nvr"] print(nvrtag) if task is None: return None tasklabel = koji.taskLabel(task) print(tasklabel) sha = urlparse(info["source"]).fragment print(sha) return (sha, nvrtag)
def get_koji_tasks(cls, task_id, dir_name): session = cls.session_maker(baseurl=cls.server) task_id = int(task_id) rpm_list = [] log_list = [] tasks = [] task = session.getTaskInfo(task_id, request=True) if task['state'] in (koji.TASK_STATES['FREE'], koji.TASK_STATES['OPEN']): return None, None elif task['state'] != koji.TASK_STATES['CLOSED']: logger.info('Task %i did not complete successfully' % task_id) if task['method'] == 'build': logger.info('Getting rpms for chilren of task %i: %s', task['id'], koji.taskLabel(task)) # getting rpms from children of task tasks = session.listTasks( opts={ 'parent': task_id, 'method': 'buildArch', 'state': [koji.TASK_STATES['CLOSED'], koji.TASK_STATES['FAILED']], 'decode': True }) elif task['method'] == 'buildArch': tasks = [task] for task in tasks: base_path = koji.pathinfo.taskrelpath(task['id']) output = session.listTaskOutput(task['id']) if output is None: return None for filename in output: download = False full_path_name = os.path.join(dir_name, filename) if filename.endswith('.src.rpm'): continue if filename.endswith('.rpm'): if task['state'] != koji.TASK_STATES['CLOSED']: continue arch = filename.rsplit('.', 3)[2] if full_path_name not in rpm_list: download = arch in ['noarch', 'x86_64'] if download: rpm_list.append(full_path_name) else: if full_path_name not in log_list: log_list.append(full_path_name) download = True if download: DownloadHelper.download_file( cls.baseurl + base_path + '/' + filename, full_path_name) return rpm_list, log_list
def print_task(task,depth=0): """Print a task""" task = task.copy() task['state'] = koji.TASK_STATES.get(task['state'],'BADSTATE') fmt = "%(id)-8s %(priority)-4s %(owner_name)-20s %(state)-8s %(arch)-10s " if depth: indent = " "*(depth-1) + " +" else: indent = '' label = koji.taskLabel(task) print(''.join([fmt % task, indent, label]))
def get_koji_tasks(cls, task_id, dir_name): session = cls.session_maker(baseurl=cls.server) task_id = int(task_id) rpm_list = [] log_list = [] tasks = [] task = session.getTaskInfo(task_id, request=True) if task['state'] in (koji.TASK_STATES['FREE'], koji.TASK_STATES['OPEN']): return None, None elif task['state'] != koji.TASK_STATES['CLOSED']: logger.info('Task %i did not complete successfully' % task_id) if task['method'] == 'build': logger.info('Getting rpms for chilren of task %i: %s', task['id'], koji.taskLabel(task)) # getting rpms from children of task tasks = session.listTasks(opts={'parent': task_id, 'method': 'buildArch', 'state': [koji.TASK_STATES['CLOSED'], koji.TASK_STATES['FAILED']], 'decode': True}) elif task['method'] == 'buildArch': tasks = [task] for task in tasks: base_path = koji.pathinfo.taskrelpath(task['id']) output = session.listTaskOutput(task['id']) if output is None: return None for filename in output: download = False full_path_name = os.path.join(dir_name, filename) if filename.endswith('.src.rpm'): continue if filename.endswith('.rpm'): if task['state'] != koji.TASK_STATES['CLOSED']: continue arch = filename.rsplit('.', 3)[2] if full_path_name not in rpm_list: download = arch in ['noarch', 'x86_64'] if download: rpm_list.append(full_path_name) else: if full_path_name not in log_list: log_list.append(full_path_name) download = True if download: DownloadHelper.download_file(cls.baseurl + base_path + '/' + filename, full_path_name) return rpm_list, log_list
def str(self): if self.info: label = koji.taskLabel(self.info) return "%s%d %s" % (' ' * self.level, self.id, label) else: return "%s%d" % (' ' * self.level, self.id)
#!/usr/bin/python2 import sys import koji args = sys.argv[1:] nvrs = [] ks = koji.ClientSession('https://koji.fedoraproject.org/kojihub') ks.multicall = True for build in args: ks.getBuild(build) ret = ks.multiCall(strict=True) ks.multicall = True for i in range(len(args)): if ret[i][0] is not None: if ret[i][0]['task_id'] is not None: ks.getTaskInfo(ret[i][0]['task_id'], request=True) nvrs.append(args[i]) ret = ks.multiCall(strict=True) for i in range(len(nvrs)): print nvrs[i], koji.taskLabel(ret[i][0])
def test_all(self): url = 'https+git://git.server/path/module#branch' module = '/path/module:branch' build = {'name': 'n', 'version': 'v', 'release': 'r', 'epoch': None} nvr = 'n-v-r' test_data = [ ['randomdata', 'malformed task'], [{}, 'malformed task'], [None, 'malformed task'], [ {'method': 'build', 'arch': 'x86_64', 'request': [url, 'target', 'opts'], }, 'build (target, %s)' % module ], [ {'method': 'build', 'arch': 'x86_64', 'request': ['n-v-r.src.rpm', 'target', 'opts'] }, 'build (target, n-v-r.src.rpm)' ], [ {'method': 'maven', 'arch': 'x86_64', 'request': ['https+git://git.server/path/module#branch', 'target', 'opts'], }, 'maven (target, %s)' % module ], [ {'method': 'maven', 'arch': 'x86_64', 'request': ['n-v-r.jar', 'target', 'opts'], }, 'maven (target, n-v-r.jar)' ], [ {'method': 'indirectionimage', 'arch': 'x86_64', 'request': [build], }, 'indirectionimage (n, v, r)' ], [ {'method': 'buildSRPMFromSCM', 'arch': 'x86_64', 'request': [url, 'build_tag', 'opts'] }, 'buildSRPMFromSCM (%s)' % module ], [ {'method': 'buildArch', 'arch': 'x86_64', 'request': ['pkg', 'root', 'arch', True, 'opts'], }, 'buildArch (pkg, arch)' ], [ {'method': 'buildMaven', 'arch': 'x86_64', 'request': [url, {'name': 'build_tag', 'id': 123}, {}], }, 'buildMaven (build_tag)', ], [ {'method': 'wrapperRPM', 'arch': 'x86_64', 'request': [url, {'name': 'target'}, build, 'task'] }, 'wrapperRPM (target, n-v-r)', ], # winbuild, vmExec (not in legacy signatures) [ {'method': 'buildNotification', 'arch': 'x86_64', 'request': ['rpts', build, 'target', 'weburl'] }, 'buildNotification (n-v-r)' ], [ {'method': 'newRepo', 'arch': 'x86_64', 'request': ['tag', 123, 'src'] }, 'newRepo (tag)' ], [ {'method': 'distRepo', 'arch': 'x86_64', 'request': ['tag', 123, 'keys', 'task_opts'] }, 'distRepo (tag)' ], [ {'method': 'tagBuild', 'arch': 'x86_64', 'request': ['tag', 123, True, 'from', True], }, 'tagBuild (x86_64)' ], [ {'method': 'tagNotification', 'arch': 'x86_64', 'request': ['rcpts', True, 'tag', 'from', build, 'user'], }, 'tagNotification (x86_64)' ], [ {'method': 'createrepo', 'arch': 'x86_64', 'request': ['repo_id', 'arch', 'oldrepo'] }, 'createrepo (arch)' ], [ {'method': 'createdistrepo', 'arch': 'x86_64', 'request': ['tag', 'repo_id', 'arch', 'keys', 'opts'] }, 'createdistrepo (repo_id, arch)' ], [ {'method': 'dependantTask', 'arch': 'x86_64', 'request': ['wait_list', [[1], [2]]], }, 'dependantTask (1, 2)' ], [ {'method': 'chainbuild', 'arch': 'x86_64', 'request': ['srcs', 'target', 'opts'], }, 'chainbuild (target)' ], [ {'method': 'chainmaven', 'arch': 'x86_64', 'request': ['srcs', 'target', 'opts'], }, 'chainmaven (target)' ], [ {'method': 'waitrepo', 'arch': 'x86_64', 'request': ['tag', 'newer', ['nvr1', 'nvr2']] }, 'waitrepo (tag, nvr1, nvr2)' ], [ {'method': 'appliance', 'arch': 'x86_64', 'request': ['name', 'version', 'arch', 'target', 'ksfile', 'opts'], }, 'appliance (arch, name-version, ksfile)', ], [ {'method': 'livecd', 'arch': 'x86_64', 'request': ['name', 'version', 'arch', 'target', 'ksfile', 'opts'], }, 'livecd (arch, name-version, ksfile)', ], [ {'method': 'image', 'arch': 'x86_64', 'request': ['name', 'version', 'arches', 'target', 'inst_tree', 'opts'], }, 'image (arches, name-version, inst_tree)', ], [ {'method': 'livemedia', 'arch': 'x86_64', 'request': ['name', 'version', 'arches', 'target', 'ksfile', 'opts'], }, 'livemedia (arches, name-version, ksfile)', ], [ {'method': 'createLiveCD', 'arch': 'x86_64', 'request': ['name', 'version', 'release', 'arch', {'name': 'target'}, 'build_tag', 'repo_info', 'ksfile', 'opts'], }, 'createLiveCD (target, name-version-release, ksfile, arch)', ], [ {'method': 'restart', 'arch': 'noarch', 'request': [{'name': 'hostname'}], }, 'restart (hostname)' ], [ {'method': 'restartVerify', 'arch': 'noarch', 'request': [123, {'name': 'hostname'}], }, 'restartVerify (hostname)' ], [ {'method': 'vmExec', 'arch': 'x86_64', 'request': ['name', 'task_info', 'opts'], }, 'vmExec (name)' ], [ {'method': 'winbuild', 'arch': 'x86_64', 'request': ['name', 'source_url', 'target', 'opts'], }, 'winbuild (target, :source_url)' ], ] for input, output in test_data: result = koji.taskLabel(input) self.assertEqual(result, output)
for task_id in args: if not task_id.isdigit(): parser.error('%s is not an integer task ID' % task_id) task_id = int(task_id) task = session.getTaskInfo(task_id, request=True) if not task: parser.error('Invalid task ID: %i' % task_id) elif task['state'] in (koji.TASK_STATES['FREE'], koji.TASK_STATES['OPEN']): parser.error('Task %i has not completed' % task['id']) elif task['state'] != koji.TASK_STATES['CLOSED']: parser.error('Task %i did not complete successfully' % task['id']) if task['method'] == 'build': print 'Getting rpms from children of task %i: %s' % (task['id'], koji.taskLabel(task)) tasks = session.listTasks(opts={'parent': task_id, 'method': 'buildArch', 'state': [koji.TASK_STATES['CLOSED']], 'decode': True}) elif task['method'] == 'buildArch': tasks = [task] else: parser.error('Task %i is not a build or buildArch task' % task['id']) prog_meter = urlgrabber.progress.TextMeter() for task in tasks: if opts.arches: print 'Downloading %s rpms from task %i: %s' % (', '.join(opts.arches), task['id'], koji.taskLabel(task)) else: print 'Downloading rpms from task %i: %s' % (task['id'], koji.taskLabel(task))
def fetch_koji_build(build): """ build ==> buildID or NVR """ if build.isdigit(): build = int(build) urls = [] # output pathinfo = koji.PathInfo(topdir=topurl) session = koji.ClientSession(server) info = session.getBuild(build) # print session.listArchives(build) # rpms = session.listRPMs(buildID=info['id']) # if not rpms: # print ":-(" # for rpm in rpms: # fname = pathinfo.rpm(rpm) # url = pathinfo.build(info) + '/' + fname # print url if not info: return task_id = info["task_id"] nvr = info.get("nvr", str(task_id)) package = info.get("name", str(task_id)) task = session.getTaskInfo(task_id, request=True) if not task: return found = False for item in task["request"]: if not isinstance(item, str): continue if re.match(build_target, item): found = True break if not found: print "skipping", build, task["request"] return if not task: print('Invalid task ID: %i' % task_id) elif task['state'] in (koji.TASK_STATES['FREE'], koji.TASK_STATES['OPEN']): print('Task %i has not completed' % task['id']) elif task['state'] != koji.TASK_STATES['CLOSED']: print('Task %i did not complete successfully' % task['id']) if task['method'] == 'build': print 'Getting rpms from children of task %i: %s' % ( task['id'], koji.taskLabel(task)) tasks = session.listTasks( opts={ 'parent': task_id, 'method': 'buildArch', 'state': [koji.TASK_STATES['CLOSED']], 'decode': True }) elif task['method'] == 'buildArch': tasks = [task] else: print('Task %i is not a build or buildArch task' % task['id']) for task in tasks: print ">>>>", task, task['id'] arch = task.get('arch', 'unkwown') output = session.listTaskOutput(task['id']) print ">>>>", arch, output # logs = [filename for filename in output if filename.endswith('.log')] for item in output: base_path = koji.pathinfo.taskrelpath(task['id']) file_url = "%s/%s/%s" % (work_url, base_path, item) urls.append((arch, file_url)) # print file_url # urls.append(file_url) # rpms = session.listRPMs(buildID=info['id']) # pathinfo = koji.PathInfo(topdir=topurl) # for rpm in rpms: # fname = koji.pathinfo.rpm(rpm) # url = os.path.join(pathinfo.build(info), fname) # print url # skip SRPMs and 32-bit RPMs # if not url.endswith("src.rpm") and not url.endswith("686.rpm"): # urls.append(url) print "Getting", urls if not urls: return download_url(package, nvr, urls) return package, nvr, urls
def _populate_modulemd(module_ctx, module_exclusive_packages, api_rpms, include_module_bootstrap): mod_md = modulemd.ModuleMetadata() mod_md.name = str(module_ctx.module) mod_md.description = str(module_ctx.module_desc) for lic in module_ctx.module_license: mod_md.add_module_license(str(lic)) mod_md.community = str(module_ctx.community) mod_md.documentation = str(module_ctx.docs) mod_md.tracker = str(module_ctx.tracker) # All modules require base runtime mod_md.add_requires("base-runtime", "master") for req in module_ctx.module_deps: mod_md.add_requires(str(req), "master") # All modules build-require bootstrap mod_md.add_buildrequires("bootstrap", "master") for req in module_ctx.module_build_deps: mod_md.add_buildrequires(str(req), "master") if include_module_bootstrap: mod_md.add_buildrequires("%s-bootstrap" % str(module_ctx.module), "master") nvr_re = re.compile("\d+\:(.*).src$") nvr_values = list() for srpm_name, srpm_nvr in module_exclusive_packages.items(): match = nvr_re.match(srpm_nvr) if match: nvr_values.append(match.group(1)) else: raise IOError("NVR [%s] didnt parse" % srpm_nvr) ks = koji.ClientSession('https://koji.fedoraproject.org/kojihub') ks.multicall = True for srpm_nvr in nvr_values: ks.getBuild(srpm_nvr) ret = ks.multiCall(strict=True) ks.multicall = True task_nvrs = [] for i in range(len(nvr_values)): if ret[i][0] is not None: if ret[i][0]['task_id'] is not None: ks.getTaskInfo(ret[i][0]['task_id'], request=True) task_nvrs.append(nvr_values[i]) else: print("WARNING: no task ID for %s" % nvrs[i]) else: print("WARNING: no task ID for %s" % nvrs[i]) ret = ks.multiCall(strict=True) deps = dict() commit_re = re.compile("([^\/]+?):([a-f0-9]{40})") for i in range(len(task_nvrs)): match = commit_re.search(koji.taskLabel(ret[i][0])) if match: deps[match.group(1)] = match.group(2) else: raise IOError("Task [%s] didnt parse" % (koji.taskLabel(ret[i][0]))) for name in sorted(deps, key=deps.get): mod_md.components.add_rpm(name, "Automatically generated", ref=deps[name]) for rpm in api_rpms: mod_md.api.add_rpm(rpm) return mod_md
def fetch_koji_build(build): """ build ==> buildID or NVR """ if build.isdigit(): build = int(build) urls = [] # output pathinfo = koji.PathInfo(topdir=topurl) session = koji.ClientSession(server) info = session.getBuild(build) # print session.listArchives(build) # rpms = session.listRPMs(buildID=info['id']) # if not rpms: # print ":-(" # for rpm in rpms: # fname = pathinfo.rpm(rpm) # url = pathinfo.build(info) + '/' + fname # print url if not info: return task_id = info["task_id"] nvr = info.get("nvr", str(task_id)) package = info.get("name", str(task_id)) task = session.getTaskInfo(task_id, request=True) if not task: return found = False for item in task["request"]: if not isinstance(item, str): continue if re.match(build_target, item): found = True break if not found: print "skipping", build, task["request"] return if not task: print ("Invalid task ID: %i" % task_id) elif task["state"] in (koji.TASK_STATES["FREE"], koji.TASK_STATES["OPEN"]): print ("Task %i has not completed" % task["id"]) elif task["state"] != koji.TASK_STATES["CLOSED"]: print ("Task %i did not complete successfully" % task["id"]) if task["method"] == "build": print "Getting rpms from children of task %i: %s" % (task["id"], koji.taskLabel(task)) tasks = session.listTasks( opts={"parent": task_id, "method": "buildArch", "state": [koji.TASK_STATES["CLOSED"]], "decode": True} ) elif task["method"] == "buildArch": tasks = [task] else: print ("Task %i is not a build or buildArch task" % task["id"]) for task in tasks: print ">>>>", task, task["id"] arch = task.get("arch", "unkwown") output = session.listTaskOutput(task["id"]) print ">>>>", arch, output # logs = [filename for filename in output if filename.endswith('.log')] for item in output: base_path = koji.pathinfo.taskrelpath(task["id"]) file_url = "%s/%s/%s" % (work_url, base_path, item) urls.append((arch, file_url)) # print file_url # urls.append(file_url) # rpms = session.listRPMs(buildID=info['id']) # pathinfo = koji.PathInfo(topdir=topurl) # for rpm in rpms: # fname = koji.pathinfo.rpm(rpm) # url = os.path.join(pathinfo.build(info), fname) # print url # skip SRPMs and 32-bit RPMs # if not url.endswith("src.rpm") and not url.endswith("686.rpm"): # urls.append(url) print "Getting", urls if not urls: return download_url(package, nvr, urls) return package, nvr, urls
def update(self): # Get Lastest Info last_info = self.info self.info = self.session.getTaskInfo(self.id, request=True) self.info["label"] = koji.taskLabel(self.info) self.info["state_str"] = koji.TASK_STATES[self.info["state"]] # Write the new job state to the trace if last_info: if self.info["state"] != last_info["state"]: logging.getLogger(LOG_KOJI_TASK).info( "Koji Task {old_state} => {new_state}" .format( task_id=self.id, old_state=last_info["state_str"], new_state=self.info["state_str"]), extra={ "koji_task_id" : self.id, "gitlab_job_id" : self.job["id"] }) if self.trace_callback is not None: self.trace_callback(self.session, None, "%(id)s %(state_str)s %(label)s\n" % self.info) else: if self.trace_callback is not None: self.trace_callback(self.session, None, "%(id)s %(state_str)s %(label)s\n" % self.info) # Discover Child Tasks for child_task in self.session.getTaskChildren(self.id): child_task_id = child_task['id'] if child_task_id not in self.child_tasks: logging.getLogger(LOG_KOJI_TASK).info( "Discovered new child task {child_task_id}" .format(child_task_id = child_task_id), extra={ "koji_task_id" : self.id, "gitlab_job_id" : self.job["id"] }) self.child_tasks[child_task_id] = \ KojiTaskWatcher(\ self.job, \ child_task_id, \ self.session, \ self.trace_callback, \ self.artifact_callback) # Update child tasks all_children_done = True for child_task_id in self.child_tasks: if self.child_tasks[child_task_id].update(): all_children_done = False # Get log updates/output output_files = self.session.listTaskOutput(self.id) for file_name in output_files: full_file_name = os.path.join(str(self.id), file_name) while True: if file_name not in self.file_offsets: self.file_offsets[file_name] = 0 logging.getLogger(LOG_KOJI_TASK_OUTPUT).debug( "Downloading {file_name} starting at offset {offset}"\ .format(file_name = full_file_name, offset = self.file_offsets[file_name]), extra={ "koji_task_id" : self.id, "gitlab_job_id" : self.job["id"] }) contents = self.session.downloadTaskOutput(self.id, file_name, self.file_offsets[file_name], 16384) logging.getLogger(LOG_KOJI_TASK_OUTPUT).debug( "Downloaded {content_length} bytes of {file_name} starting at offset {offset}" .format(file_name = full_file_name, offset = self.file_offsets[file_name], content_length = len(contents)), extra={ "koji_task_id" : self.id, "gitlab_job_id" : self.job["id"] }) if len(contents) > 0: if file_name.endswith('.log') and self.trace_callback is not None: self.trace_callback(self.session, "Task:%d - %s" % (self.id, file_name,), contents) if self.artifact_callback is not None: self.artifact_callback(self.session, full_file_name, contents, self.file_offsets[file_name]) self.file_offsets[file_name] += len(contents) else: break logging.getLogger(LOG_KOJI_TASK).debug( "Koji Task - State: {state}, Done: {is_done}" .format( task_id=self.id, state=self.info["state_str"], is_done=self.is_done()), extra={ "koji_task_id" : self.id, "gitlab_job_id" : self.job["id"] }) # Return True until we and our childeren have finished return not (self.is_done() and all_children_done)