def runroot(tagInfo, arch, command, channel=None, **opts): """ Create a runroot task """ context.session.assertPerm('runroot') taskopts = { 'priority': 15, 'arch': arch, } taskopts['channel'] = channel or 'runroot' if arch == 'noarch': #not all arches can generate a proper buildroot for all tags tag = kojihub.get_tag(tagInfo) if not tag['arches']: raise koji.GenericError('no arches defined for tag %s' % tag['name']) #get all known arches for the system fullarches = kojihub.get_all_arches() tagarches = tag['arches'].split() # If our tag can't do all arches, then we need to # specify one of the arches it can do. if set(fullarches) - set(tagarches): chanarches = get_channel_arches(taskopts['channel']) choices = [x for x in tagarches if x in chanarches] if not choices: raise koji.GenericError('no common arches for tag/channel: %s/%s' \ % (tagInfo, taskopts['channel'])) taskopts['arch'] = koji.canonArch(random.choice(choices)) args = koji.encode_args(tagInfo, arch, command, **opts) return kojihub.make_task('runroot', args, **taskopts)
def runroot(tagInfo, arch, command, channel=None, **opts): """ Create a runroot task """ context.session.assertPerm('runroot') taskopts = { 'priority': 15, 'arch': arch, } taskopts['channel'] = channel or 'runroot' if arch == 'noarch': #not all arches can generate a proper buildroot for all tags tag = kojihub.get_tag(tagInfo) if not tag['arches']: raise koji.GenericError, 'no arches defined for tag %s' % tag['name'] #get all known arches for the system fullarches = kojihub.get_all_arches() tagarches = tag['arches'].split() # If our tag can't do all arches, then we need to # specify one of the arches it can do. if set(fullarches) - set(tagarches): chanarches = get_channel_arches(taskopts['channel']) choices = [x for x in tagarches if x in chanarches] if not choices: raise koji.GenericError, 'no common arches for tag/channel: %s/%s' \ % (tagInfo, taskopts['channel']) taskopts['arch'] = koji.canonArch(random.choice(choices)) args = koji.encode_args(tagInfo, arch, command,**opts) return kojihub.make_task('runroot', args, **taskopts)
def test_build_notification(self): # force locale to compare 'message' value locale.setlocale(locale.LC_ALL, ('en_US', 'UTF-8')) # task_info['id'], method, params, self.session, self.options task_id = 999 fn = os.path.join(os.path.dirname(__file__), 'data/calls', 'build_notif_1', 'params.json') kwargs = koji.load_json(fn) self.session = MyClientSession('https://koji.example.com/kojihub') self.session.load_calls('build_notif_1') self.options.from_addr = "*****@*****.**" server = mock.MagicMock() self.SMTP.return_value = server # run it handler = kojid.BuildNotificationTask(task_id, 'buildNotification', koji.encode_args(**kwargs), self.session, self.options) ret = handler.run() self.assertEqual( ret, "sent notification of build 612609 to: [email protected]") # check sendmail args from_addr, recipients, message = server.sendmail.call_args[0] self.assertEqual(from_addr, "*****@*****.**") self.assertEqual(recipients, ["*****@*****.**"]) fn = os.path.join(os.path.dirname(__file__), 'data/calls', 'build_notif_1', 'message.txt') with open(fn, 'rb') as fp: msg_expect = fp.read() if six.PY2: msg_expect = msg_expect.decode() self.assertMultiLineEqual(message.decode(), msg_expect.decode()) locale.resetlocale()
def test_build_notification(self): # task_info['id'], method, params, self.session, self.options task_id = 999 fn = os.path.join(os.path.dirname(__file__), 'data/calls', 'build_notif_1', 'params.json') with file(fn) as fp: kwargs = json.load(fp) self.session = MyClientSession('https://koji.example.com/kojihub') self.session.load_calls('build_notif_1') self.options.from_addr = "*****@*****.**" server = mock.MagicMock() self.SMTP.return_value = server # run it handler = kojid.BuildNotificationTask(task_id, 'buildNotification', koji.encode_args(**kwargs), self.session, self.options) ret = handler.run() self.assertEqual( ret, "sent notification of build 612609 to: [email protected]") # check sendmail args from_addr, recipients, message = server.sendmail.call_args[0] self.assertEqual(from_addr, "*****@*****.**") self.assertEqual(recipients, ["*****@*****.**"]) fn = os.path.join(os.path.dirname(__file__), 'data/calls', 'build_notif_1', 'message.txt') with file(fn) as fp: msg_expect = fp.read() self.assertEqual(message, msg_expect)
def replicate_build_task(session, task, options): if isinstance(task, six.integer_types): task = session.getTaskInfo(task, request=True) task_id = task['id'] logger.info("%i: Looking at task", task_id) if task['parent'] is not None: raise koji.GenericError("%(id)i: not a parent task" % task) if task['method'] == 'build': params = replicate_build_request(session, task, options) # TODO: ONLY build task is supported right now # elif task['method'] in ['image', 'livemedia', 'livecd', 'appliance']: # params = replicate_image_request(session, task, options) else: raise koji.GenericError("%(id)i: can not replicate %(method)s task" % task) channel = task['channel_id'] if options.channel_override: channel = options.channel_override new_task_id = session.makeTask(task['method'], koji.encode_args(**params), channel=channel) logger.info("Original task %i replicated as task %i", task_id, new_task_id) rv = watch_tasks(session, [new_task_id], quiet=options.quiet) # always True return True
def test_build_notification(self): # task_info['id'], method, params, self.session, self.options task_id = 999 fn = os.path.join(os.path.dirname(__file__), 'data/calls', 'build_notif_1', 'params.json') with open(fn) as fp: kwargs = json.load(fp) self.session = MyClientSession('https://koji.example.com/kojihub') self.session.load_calls('build_notif_1') self.options.from_addr = "*****@*****.**" server = mock.MagicMock() self.SMTP.return_value = server # run it handler = kojid.BuildNotificationTask( task_id, 'buildNotification', koji.encode_args(**kwargs), self.session, self.options) ret = handler.run() self.assertEqual(ret, "sent notification of build 612609 to: [email protected]") # check sendmail args from_addr, recipients, message = server.sendmail.call_args[0] self.assertEqual(from_addr, "*****@*****.**") self.assertEqual(recipients, ["*****@*****.**"]) fn = os.path.join(os.path.dirname(__file__), 'data/calls', 'build_notif_1', 'message.txt') with open(fn, 'rb') as fp: msg_expect = fp.read().decode() self.assertEqual(message, msg_expect)
def saveFailedTree(buildrootID, full=False, **opts): """Create saveFailedTree task If arguments are invalid, error message is returned. Otherwise task id of newly created task is returned.""" global config, allowed_methods # let it raise errors buildrootID = int(buildrootID) full = bool(full) # read configuration only once if config is None: config = six.moves.configparser.SafeConfigParser() config.read(CONFIG_FILE) allowed_methods = config.get('permissions', 'allowed_methods').split() if len(allowed_methods) == 1 and allowed_methods[0] == '*': allowed_methods = '*' brinfo = kojihub.get_buildroot(buildrootID, strict=True) taskID = brinfo['task_id'] task_info = kojihub.Task(taskID).getInfo() if task_info['state'] != koji.TASK_STATES['FAILED']: raise koji.PreBuildError( "Task %s has not failed. Only failed tasks can upload their buildroots." % taskID) elif allowed_methods != '*' and task_info['method'] not in allowed_methods: raise koji.PreBuildError("Only %s tasks can upload their buildroots (Task %s is %s)." % \ (', '.join(allowed_methods), task_info['id'], task_info['method'])) elif task_info[ "owner"] != context.session.user_id and not context.session.hasPerm( 'admin'): raise koji.ActionNotAllowed( "Only owner of failed task or 'admin' can run this task.") elif not kojihub.get_host(task_info['host_id'])['enabled']: raise koji.PreBuildError("Host is disabled.") args = koji.encode_args(buildrootID, full, **opts) taskopts = { 'assign': brinfo['host_id'], } return kojihub.make_task('saveFailedTree', args, **taskopts)
def saveFailedTree(buildrootID, full=False, **opts): """Create saveFailedTree task If arguments are invalid, error message is returned. Otherwise task id of newly created task is returned.""" global config, allowed_methods # let it raise errors buildrootID = int(buildrootID) full = bool(full) # read configuration only once if config is None: config = six.moves.configparser.SafeConfigParser() config.read(CONFIG_FILE) allowed_methods = config.get('permissions', 'allowed_methods').split() if len(allowed_methods) == 1 and allowed_methods[0] == '*': allowed_methods = '*' brinfo = kojihub.get_buildroot(buildrootID, strict=True) taskID = brinfo['task_id'] task_info = kojihub.Task(taskID).getInfo() if task_info['state'] != koji.TASK_STATES['FAILED']: raise koji.PreBuildError("Task %s has not failed. Only failed tasks can upload their buildroots." % taskID) elif allowed_methods != '*' and task_info['method'] not in allowed_methods: raise koji.PreBuildError("Only %s tasks can upload their buildroots (Task %s is %s)." % \ (', '.join(allowed_methods), task_info['id'], task_info['method'])) elif task_info["owner"] != context.session.user_id and not context.session.hasPerm('admin'): raise koji.ActionNotAllowed("Only owner of failed task or 'admin' can run this task.") elif not kojihub.get_host(task_info['host_id'])['enabled']: raise koji.PreBuildError("Host is disabled.") args = koji.encode_args(buildrootID, full, **opts) taskopts = { 'assign': brinfo['host_id'], } return kojihub.make_task('saveFailedTree', args, **taskopts)