def register_result_file(self, server, result_id, path, filename, basepath): """ register file and return path to store """ try: result = RecipeTaskResult.by_id(result_id, lockmode='update') except NoResultFound: raise BX(_('Invalid result ID: %s' % result_id)) RecipeTask.by_id(result.recipe_task_id, lockmode='update') Recipe.by_id(result.recipetask.recipe_id, lockmode='update') if result.recipetask.is_finished(): raise BX('Cannot register file for finished task %s' % result.recipetask.t_id) self._check_log_limit(result.recipetask) log_recipe = LogRecipeTaskResult.lazy_create( recipe_task_result_id=result.id, path=path, filename=filename, ) log_recipe.server = server log_recipe.basepath = basepath result.recipetask.recipe.log_server = urlparse.urlparse(server)[1] return '%s' % result.filepath
def create_recipe(distro_tree=None, task_list=None, task_name=u'/distribution/reservesys', whiteboard=None, role=None, cls=MachineRecipe, **kwargs): if not distro_tree: distro_tree = create_distro_tree() recipe = cls(ttasks=1) recipe.whiteboard = whiteboard recipe.distro_tree = distro_tree recipe.role = role recipe.distro_requires = recipe.distro_tree.to_xml().toxml() if kwargs.get('reservesys', False): duration=kwargs.get('reservesys_duration', 86400) recipe.reservation_request = RecipeReservationRequest(duration) if task_list: #don't specify a task_list and a task_name... for t in task_list: rt = RecipeTask.from_task(t) rt.role = u'STANDALONE' recipe.tasks.append(rt) recipe.ttasks = len(task_list) else: rt = RecipeTask.from_task(create_task(name=task_name)) rt.role = u'STANDALONE' recipe.tasks.append(rt) return recipe
def create_recipe(distro_tree=None, task_list=None, task_name=u'/distribution/reservesys', num_tasks=None, whiteboard=None, role=None, cls=MachineRecipe, **kwargs): if not distro_tree: distro_tree = create_distro_tree() recipe = cls(ttasks=1) recipe.whiteboard = whiteboard recipe.distro_tree = distro_tree recipe.role = role or u'STANDALONE' recipe.distro_requires = recipe.distro_tree.to_xml().toxml() if kwargs.get('reservesys', False): duration = kwargs.get('reservesys_duration', 86400) recipe.reservation_request = RecipeReservationRequest(duration) if num_tasks: task_list = [create_task() for i in range(0, num_tasks)] if task_list: #don't specify a task_list and a task_name... for t in task_list: rt = RecipeTask.from_task(t) rt.role = u'STANDALONE' recipe.tasks.append(rt) recipe.ttasks = len(task_list) else: rt = RecipeTask.from_task(create_task(name=task_name)) rt.role = u'STANDALONE' recipe.tasks.append(rt) return recipe
def setUp(self): with session.begin(): self.recipe = data_setup.create_recipe(task_name=u'/distribution/install') self.recipe.tasks.extend([ RecipeTask.from_task(data_setup.create_task()), RecipeTask.from_fetch_url(u'http://example.com/tasks/example.tar.bz2'), ]) data_setup.create_job_for_recipes([self.recipe]) data_setup.mark_recipe_running(self.recipe)
def setUp(self): with session.begin(): self.recipe = data_setup.create_recipe( task_name=u'/distribution/install') self.recipe.tasks.extend([ RecipeTask.from_task(data_setup.create_task()), RecipeTask.from_fetch_url( u'http://example.com/tasks/example.tar.bz2'), ]) data_setup.create_job_for_recipes([self.recipe]) data_setup.mark_recipe_running(self.recipe)
def _get_recipe_task_by_id(recipeid, taskid): try: task = RecipeTask.by_id(taskid) except NoResultFound: raise NotFound404('Recipe task not found') if recipeid != '_' and str(task.recipe.id) != recipeid: raise NotFound404('Recipe task not found') return task
def extend(self, task_id, kill_time): """ Extend tasks watchdog by kill_time seconds """ try: task = RecipeTask.by_id(task_id) except InvalidRequestError: raise BX(_('Invalid task ID: %s' % task_id)) return task.extend(kill_time)
def watchdog(self, task_id): """ Returns number of seconds left on task_id watchdog, or False if it doesn't exist. """ try: task = RecipeTask.by_id(task_id) except InvalidRequestError: raise BX(_('Invalid task ID: %s' % task_id)) return task.status_watchdog()
def start(self, task_id, watchdog_override=None): """ Set task status to Running """ try: task = RecipeTask.by_id(task_id) except InvalidRequestError: raise BX(_('Invalid task ID: %s' % task_id)) return task.start(watchdog_override)
def test_recipe_task_result_rows_are_deleted(self): with session.begin(): self.job_to_delete.to_delete = datetime.datetime.utcnow() recipe = self.job_to_delete.recipesets[0].recipes[0] recipetask = recipe.tasks[0] self.assertEqual(len(recipetask.results), 1) log_delete.log_delete() with session.begin(): recipetask = RecipeTask.by_id(recipetask.id) self.assertEqual(len(recipetask.results), 0)
def create_recipe(distro_tree=None, task_list=None, task_name=u'/distribution/reservesys', whiteboard=None, role=None, cls=MachineRecipe, **kwargs): if not distro_tree: distro_tree = create_distro_tree() recipe = cls(ttasks=1) recipe.whiteboard = whiteboard recipe.distro_tree = distro_tree recipe.role = role recipe.distro_requires = recipe.distro_tree.to_xml().toxml() if task_list: #don't specify a task_list and a task_name... for t in task_list: rt = RecipeTask(task=t) rt.role = u'STANDALONE' recipe.tasks.append(rt) else: rt = RecipeTask(task=create_task(name=task_name)) rt.role = u'STANDALONE' recipe.tasks.append(rt) return recipe
def result(self, task_id, result_type, path=None, score=None, summary=None): """ Record a Result """ try: task = RecipeTask.by_id(task_id) except InvalidRequestError: raise BX(_('Invalid task ID: %s' % task_id)) if result_type not in task.result_types: raise BX(_('Invalid result_type: %s, must be one of %s' % (result_type, task.result_types))) kwargs = dict(path=path, score=score, summary=summary) return getattr(task,result_type)(**kwargs)
def stop(self, task_id, stop_type, msg=None): """ Set task status to Completed """ try: task = RecipeTask.by_id(task_id) except InvalidRequestError: raise BX(_('Invalid task ID: %s' % task_id)) if stop_type not in task.stop_types: raise BX(_('Invalid stop_type: %s, must be one of %s' % (stop_type, task.stop_types))) kwargs = dict(msg = msg) return getattr(task,stop_type)(**kwargs)
def test_recipe_view_shows_external_task_results(self): with session.begin(): recipe = data_setup.create_recipe(task_name=u'/distribution/install') external_task = RecipeTask.from_fetch_url( url='git://example.com/externaltasks/example#master', subdir='examples') recipe.tasks.extend([external_task]) data_setup.create_job_for_recipes([recipe], whiteboard='job with external tasks') data_setup.mark_recipe_complete(recipe, result=TaskResult.warn, task_status=TaskStatus.aborted) b = self.browser go_to_recipe_view(b, recipe=recipe, tab='Tasks') b.find_element_by_xpath('//div[@class="task-result-path"]/.[contains(text(), "%s")]' % external_task.fetch_url) b.find_element_by_xpath('//span[@class="task-name"]/.[contains(text(), "%s")]' % external_task.fetch_url)
def stop(self, task_id, stop_type, msg=None): """ Set task status to Completed """ try: task = RecipeTask.by_id(task_id) except InvalidRequestError: raise BX(_('Invalid task ID: %s' % task_id)) if stop_type not in task.stop_types: raise BX( _('Invalid stop_type: %s, must be one of %s' % (stop_type, task.stop_types))) kwargs = dict(msg=msg) return getattr(task, stop_type)(**kwargs)
def update(self, task_id, data): """ XML-RPC method used by the lab controller harness API to update a recipe-task's attributes. """ try: task = RecipeTask.by_id(task_id) except InvalidRequestError: raise BX(_('Invalid task ID: %s' % task_id)) if 'name' in data: task.name = data['name'] if 'version' in data: task.version = data['version'] return task.__json__()
def register_result_file(self, server, result_id, path, filename, basepath): """ register file and return path to store """ try: result = RecipeTaskResult.by_id(result_id, lockmode='update') except NoResultFound: raise BX(_('Invalid result ID: %s' % result_id)) RecipeTask.by_id(result.recipe_task_id, lockmode='update') Recipe.by_id(result.recipetask.recipe_id, lockmode='update') if result.recipetask.is_finished(): raise BX('Cannot register file for finished task %s' % result.recipetask.t_id) self._check_log_limit(result.recipetask) log_recipe = LogRecipeTaskResult.lazy_create(recipe_task_result_id=result.id, path=path, filename=filename, ) log_recipe.server = server log_recipe.basepath = basepath result.recipetask.recipe.log_server = urlparse.urlparse(server)[1] return '%s' % result.filepath
def create_recipe(distro_tree=None, task_list=None, task_name=u'/distribution/reservesys', num_tasks=None, whiteboard=None, role=None, ks_meta=None, cls=MachineRecipe, **kwargs): recipe = cls(ttasks=1) recipe.ks_meta = ks_meta recipe.whiteboard = whiteboard recipe.distro_tree = distro_tree recipe.role = role or u'STANDALONE' custom_distro = kwargs.get('custom_distro', False) if not custom_distro: if not distro_tree: distro_tree = create_distro_tree(**kwargs) recipe.distro_tree = distro_tree recipe.installation = recipe.distro_tree.create_installation_from_tree() recipe.distro_requires = lxml.etree.tostring(recipe.distro_tree.to_xml(), encoding=unicode) else: name = kwargs.get('distro_name', u'MyAwesomeLinux1.0') tree_url = kwargs.get('tree_url', u'ftp://dummylab.example.com/distros/MyAwesomeLinux1/') initrd_path = kwargs.get('initrd_path', u'pxeboot/initrd') kernel_path = kwargs.get('kernel_path', u'pxeboot/vmlinuz') arch = kwargs.get('arch', u'i386') variant = kwargs.get('variant', u'Server') osmajor = kwargs.get('osmajor', u'DansAwesomeLinux6') osminor = kwargs.get('osminor', u'0') arch = Arch.by_name(arch) recipe.installation = Installation(tree_url=tree_url, initrd_path=initrd_path, kernel_path=kernel_path, arch=arch, distro_name=name, osmajor=osmajor, osminor=osminor, variant=variant) if kwargs.get('reservesys', False): recipe.reservation_request = RecipeReservationRequest() if kwargs.get('reservesys_duration'): recipe.reservation_request.duration = kwargs['reservesys_duration'] if num_tasks: task_list = [create_task() for i in range(0, num_tasks)] if not task_list: #don't specify a task_list and a task_name... try: task = Task.by_name(task_name) except LookupError: task = create_task(name=task_name) task_list = [task] for t in task_list: rt = RecipeTask.from_task(t) rt.role = u'STANDALONE' recipe.tasks.append(rt) recipe.ttasks = len(task_list) return recipe
def result(self, task_id, result_type, path=None, score=None, summary=None): """ Record a Result """ try: task = RecipeTask.by_id(task_id) except InvalidRequestError: raise BX(_('Invalid task ID: %s' % task_id)) if result_type not in task.result_types: raise BX( _('Invalid result_type: %s, must be one of %s' % (result_type, task.result_types))) kwargs = dict(path=path, score=score, summary=summary) return getattr(task, result_type)(**kwargs)
def register_file(self, server, task_id, path, filename, basepath): """ register file and return path to store """ try: recipetask = RecipeTask.by_id(task_id) except InvalidRequestError: raise BX(_('Invalid task ID: %s' % task_id)) if recipetask.is_finished(): raise BX('Cannot register file for finished task %s' % recipetask.t_id) # Add the log to the DB if it hasn't been recorded yet. log_recipe = LogRecipeTask.lazy_create(recipe_task_id=recipetask.id, path=path, filename=filename, ) log_recipe.server = server log_recipe.basepath = basepath recipetask.recipe.log_server = urlparse.urlparse(server)[1] return '%s' % recipetask.filepath
def register_file(self, server, task_id, path, filename, basepath): """ register file and return path to store """ try: recipetask = RecipeTask.by_id(task_id) except InvalidRequestError: raise BX(_('Invalid task ID: %s' % task_id)) if recipetask.is_finished(): raise BX('Cannot register file for finished task %s' % recipetask.t_id) # Add the log to the DB if it hasn't been recorded yet. log_recipe = LogRecipeTask.lazy_create( recipe_task_id=recipetask.id, path=path, filename=filename, ) log_recipe.server = server log_recipe.basepath = basepath recipetask.recipe.log_server = urlparse.urlparse(server)[1] return '%s' % recipetask.filepath
def peer_roles(self, task_id): try: task = RecipeTask.by_id(task_id) except NoResultFound: raise BX(_('Invalid task ID: %s') % task_id) # don't use set, we want to preserve ordering roles = {} for role, recipes in task.recipe.peer_roles().iteritems(): fqdns = roles.setdefault(unicode(role), []) for recipe in recipes: if not recipe.resource or not recipe.resource.fqdn: continue fqdn = unicode(recipe.resource.fqdn) if fqdn not in fqdns: fqdns.append(fqdn) for role, tasks in task.peer_roles().iteritems(): fqdns = roles.setdefault(unicode(role), []) for task in tasks: if not task.recipe.resource or not task.recipe.resource.fqdn: continue fqdn = unicode(task.recipe.resource.fqdn) if fqdn not in fqdns: fqdns.append(fqdn) return roles
xmltasks = [] invalid_tasks = [] for xmltask in xmlrecipe.iter_tasks(): if hasattr(xmltask, 'fetch'): # If fetch URL is given, the task doesn't need to exist. xmltasks.append(xmltask) elif Task.exists_by_name(xmltask.name, valid=True): xmltasks.append(xmltask) else: invalid_tasks.append(xmltask.name) if invalid_tasks and not ignore_missing_tasks: raise BX(_('Invalid task(s): %s') % ', '.join(invalid_tasks)) for xmltask in xmltasks: if hasattr(xmltask, 'fetch'): recipetask = RecipeTask.from_fetch_url( xmltask.fetch.url, subdir=xmltask.fetch.subdir, name=xmltask.name) else: recipetask = RecipeTask.from_task(Task.by_name(xmltask.name)) recipetask.role = xmltask.role for xmlparam in xmltask.iter_params(): param = RecipeTaskParam(name=xmlparam.name, value=xmlparam.value) recipetask.params.append(param) recipe.tasks.append(recipetask) if not recipe.tasks: raise BX(_('No Tasks! You can not have a recipe with no tasks!')) return recipe @expose('json') def update_recipe_set_response(self, recipe_set_id, response_id):
def to_xml(self, id): taskxml = RecipeTask.by_id(id).to_xml().toprettyxml() return dict(xml=taskxml)
recipe.ks_appends.append(RecipeKSAppend(ks_append=xmlksappend)) xmltasks = [] invalid_tasks = [] for xmltask in xmlrecipe.iter_tasks(): if hasattr(xmltask, 'fetch'): # If fetch URL is given, the task doesn't need to exist. xmltasks.append(xmltask) elif Task.exists_by_name(xmltask.name, valid=True): xmltasks.append(xmltask) else: invalid_tasks.append(xmltask.name) if invalid_tasks and not ignore_missing_tasks: raise BX(_('Invalid task(s): %s') % ', '.join(invalid_tasks)) for xmltask in xmltasks: if hasattr(xmltask, 'fetch'): recipetask = RecipeTask.from_fetch_url(xmltask.fetch.url, subdir=xmltask.fetch.subdir, name=xmltask.name) else: recipetask = RecipeTask.from_task(Task.by_name(xmltask.name)) recipetask.role = xmltask.role for xmlparam in xmltask.iter_params(): param = RecipeTaskParam( name=xmlparam.name, value=xmlparam.value) recipetask.params.append(param) recipe.tasks.append(recipetask) if not recipe.tasks: raise BX(_('No Tasks! You can not have a recipe with no tasks!')) return recipe @expose('json') def update_recipe_set_response(self,recipe_set_id,response_id): rs = RecipeSet.by_id(recipe_set_id)
def _do_search(self, hidden={}, **kw): tasks = RecipeTask.query\ .filter(RecipeTask.recipe.has(Recipe.recipeset.has(RecipeSet.job.has( and_(Job.to_delete == None, Job.deleted == None)))))\ .options(joinedload(RecipeTask.task), joinedload_all(RecipeTask.results, RecipeTaskResult.logs)) recipe_task_id = kw.get('recipe_task_id') if recipe_task_id: if isinstance(recipe_task_id, basestring): tasks = tasks.filter(RecipeTask.id == recipe_task_id) elif isinstance(recipe_task_id, list): tasks = tasks.filter(RecipeTask.id.in_(recipe_task_id)) if 'recipe_id' in kw: #most likely we are coming here from a LinkRemoteFunction in recipe_widgets tasks = tasks.join( RecipeTask.recipe).filter(Recipe.id == kw['recipe_id']) hidden = dict(distro_tree=1, system=1) if kw.get('distro_tree_id'): tasks = tasks.join(RecipeTask.recipe, Recipe.distro_tree)\ .filter(DistroTree.id == kw.get('distro_tree_id')) hidden = dict(distro_tree=1) elif kw.get('distro_id'): tasks = tasks.join(RecipeTask.recipe, Recipe.distro_tree, DistroTree.distro)\ .filter(Distro.id == kw.get('distro_id')) if kw.get('task_id'): try: tasks = tasks.join('task').filter(Task.id == kw.get('task_id')) hidden = dict(task=1, ) except InvalidRequestError: return "<div>Invalid data:<br>%r</br></div>" % kw if kw.get('system_id'): tasks = tasks.join(RecipeTask.recipe, Recipe.resource.of_type(SystemResource), SystemResource.system)\ .filter(System.id == kw.get('system_id'))\ .order_by(RecipeTask.id.desc()) hidden = dict(system=1) if kw.get('job_id'): job_id = kw.get('job_id') if not isinstance(job_id, list): job_id = [job_id] tasks = tasks.join('recipe', 'recipeset', 'job').filter(Job.id.in_(job_id)) if kw.get('system'): tasks = tasks.join(RecipeTask.recipe, Recipe.resource)\ .filter(RecipeResource.fqdn.like('%%%s%%' % kw.get('system'))) if kw.get('task'): # Shouldn't have to do this. This only happens on the LinkRemoteFunction calls kw['task'] = kw.get('task').replace('%2F', '/') tasks = tasks.filter( RecipeTask.name.like('%s' % kw.get('task').replace('*', '%%'))) if kw.get('version'): tasks = tasks.filter( RecipeTask.version.like(kw.get('version').replace('*', '%'))) if kw.get('distro'): tasks = tasks.join(RecipeTask.recipe, Recipe.distro_tree, DistroTree.distro)\ .filter(Distro.name.like('%%%s%%' % kw.get('distro'))) if kw.get('arch_id'): tasks = tasks.join(RecipeTask.recipe, Recipe.distro_tree, DistroTree.arch)\ .filter(Arch.id == kw.get('arch_id')) if kw.get('status'): tasks = tasks.filter(RecipeTask.status == kw['status']) if kw.get('is_failed'): tasks = tasks.filter(RecipeTask.is_failed()) elif kw.get('result'): tasks = tasks.filter(RecipeTask.result == kw['result']) if kw.get('osmajor_id'): tasks = tasks.join(RecipeTask.recipe, Recipe.distro_tree, DistroTree.distro, Distro.osversion, OSVersion.osmajor)\ .filter(OSMajor.id == kw.get('osmajor_id')) if kw.get('whiteboard'): tasks = tasks.join('recipe').filter( Recipe.whiteboard == kw.get('whiteboard')) return dict(tasks=tasks, hidden=hidden, task_widget=self.task_widget)
def _do_search(self, hidden={}, **kw): tasks = RecipeTask.query\ .filter(RecipeTask.recipe.has(Recipe.recipeset.has(RecipeSet.job.has( and_(Job.to_delete == None, Job.deleted == None)))))\ .options(joinedload(RecipeTask.task), joinedload_all(RecipeTask.results, RecipeTaskResult.logs)) recipe_task_id = kw.get('recipe_task_id') if recipe_task_id: if isinstance(recipe_task_id, basestring): tasks = tasks.filter(RecipeTask.id == recipe_task_id) elif isinstance(recipe_task_id, list): tasks = tasks.filter(RecipeTask.id.in_(recipe_task_id)) if 'recipe_id' in kw: #most likely we are coming here from a LinkRemoteFunction in recipe_widgets tasks = tasks.join(RecipeTask.recipe).filter(Recipe.id == kw['recipe_id']) hidden = dict(distro_tree=1, system=1) if kw.get('distro_tree_id'): tasks = tasks.join(RecipeTask.recipe, Recipe.distro_tree)\ .filter(DistroTree.id == kw.get('distro_tree_id')) hidden = dict(distro_tree=1) elif kw.get('distro_id'): tasks = tasks.join(RecipeTask.recipe, Recipe.distro_tree, DistroTree.distro)\ .filter(Distro.id == kw.get('distro_id')) if kw.get('task_id'): try: tasks = tasks.join('task').filter(Task.id==kw.get('task_id')) hidden = dict(task = 1, ) except InvalidRequestError: return "<div>Invalid data:<br>%r</br></div>" % kw if kw.get('system_id'): tasks = tasks.join(RecipeTask.recipe, Recipe.resource.of_type(SystemResource), SystemResource.system)\ .filter(System.id == kw.get('system_id'))\ .order_by(RecipeTask.id.desc()) hidden = dict(system=1) if kw.get('job_id'): job_id = kw.get('job_id') if not isinstance(job_id, list): job_id = [job_id] tasks = tasks.join('recipe','recipeset','job').filter(Job.id.in_(job_id)) if kw.get('system'): tasks = tasks.join(RecipeTask.recipe, Recipe.resource)\ .filter(RecipeResource.fqdn.like('%%%s%%' % kw.get('system'))) if kw.get('task'): # Shouldn't have to do this. This only happens on the LinkRemoteFunction calls kw['task'] = kw.get('task').replace('%2F','/') tasks = tasks.filter(RecipeTask.name.like('%s' % kw.get('task').replace('*','%%'))) if kw.get('version'): tasks = tasks.filter(RecipeTask.version.like(kw.get('version').replace('*', '%'))) if kw.get('distro'): tasks = tasks.join(RecipeTask.recipe, Recipe.distro_tree, DistroTree.distro)\ .filter(Distro.name.like('%%%s%%' % kw.get('distro'))) if kw.get('arch_id'): tasks = tasks.join(RecipeTask.recipe, Recipe.distro_tree, DistroTree.arch)\ .filter(Arch.id == kw.get('arch_id')) if kw.get('status'): tasks = tasks.filter(RecipeTask.status == kw['status']) if kw.get('is_failed'): tasks = tasks.filter(RecipeTask.is_failed()) elif kw.get('result'): tasks = tasks.filter(RecipeTask.result == kw['result']) if kw.get('osmajor_id'): tasks = tasks.join(RecipeTask.recipe, Recipe.distro_tree, DistroTree.distro, Distro.osversion, OSVersion.osmajor)\ .filter(OSMajor.id == kw.get('osmajor_id')) if kw.get('whiteboard'): tasks = tasks.join('recipe').filter(Recipe.whiteboard==kw.get('whiteboard')) return dict(tasks = tasks, hidden = hidden, task_widget = self.task_widget)