def postinstall_done(self, recipe_id=None): """ Report completion of postinstallation """ try: recipe = Recipe.by_id(recipe_id) except InvalidRequestError: raise BX(_(u'Invalid Recipe ID %s' % recipe_id)) if not recipe.installation: raise BX(_('Recipe %s not provisioned yet') % recipe_id) recipe.installation.postinstall_finished = datetime.utcnow() return True
def stop(self, recipe_id, stop_type, msg=None): """ Set recipe status to Completed """ try: recipe = Recipe.by_id(recipe_id) except InvalidRequestError: raise BX(_('Invalid recipe ID: %s' % recipe_id)) if stop_type not in recipe.stop_types: raise BX(_('Invalid stop_type: %s, must be one of %s' % (stop_type, recipe.stop_types))) kwargs = dict(msg = msg) return getattr(recipe,stop_type)(**kwargs)
def to_xml(self, recipe_id=None): """ Pass in recipe id and you'll get that recipe's xml """ if not recipe_id: raise BX(_("No recipe id provided!")) try: recipexml = etree.tostring(Recipe.by_id(recipe_id).to_xml(), pretty_print=True, encoding='utf8') except InvalidRequestError: raise BX(_("Invalid Recipe ID %s" % recipe_id)) return recipexml
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 stop(self, job_id, stop_type, msg=None): """ Set job status to Completed """ try: job = Job.by_id(job_id) except InvalidRequestError: raise BX(_('Invalid job ID: %s' % job_id)) if stop_type not in job.stop_types: raise BX( _('Invalid stop_type: %s, must be one of %s' % (stop_type, job.stop_types))) kwargs = dict(msg=msg) return getattr(job, stop_type)(**kwargs)
def remove_submission_delegate_by_name(self, delegate_name, service=u'XMLRPC'): user = identity.current.user try: submission_delegate = User.by_user_name(delegate_name) except NoResultFound: raise BX(_(u'%s is not a valid user name' % delegate_name)) try: user.remove_submission_delegate(submission_delegate, service=service) except ValueError: raise BX(_(u'%s is not a submission delegate of %s' % \ (delegate_name, user))) return delegate_name
def install_start(self, recipe_id=None): """ Report comencement of provisioning of a recipe's resource, extend first task's watchdog, and report 'Install Started' against it. """ try: recipe = Recipe.by_id(recipe_id) except InvalidRequestError: raise BX(_("Invalid Recipe ID %s" % recipe_id)) first_task = recipe.first_task if not recipe.resource.install_started: recipe.resource.install_started = datetime.utcnow() # extend watchdog by 3 hours 60 * 60 * 3 kill_time = 10800 # XXX In future releases where 'Provisioning' # is a valid recipe state, we will no longer # need the following block. log.debug('Extending watchdog for %s', first_task.t_id) first_task.extend(kill_time) log.debug('Recording /start for %s', first_task.t_id) first_task.pass_(path=u'/start', score=0, summary=u'Install Started') return True else: log.debug('Already recorded /start for %s', first_task.t_id) return False
def _remove(self, user, method, **kw): if user == identity.current.user: raise BX(_('You cannot remove yourself')) # cancel all running and queued jobs Job.cancel_jobs_by_user(user, 'User %s removed' % user.user_name) # Return all systems in use by this user for system in System.query.filter(System.user == user): reservation = system.open_reservation system.unreserve(reservation=reservation, service=method, user=user) # Return all loaned systems in use by this user for system in System.query.filter(System.loaned == user): system.record_activity(user=identity.current.user, service=method, action=u'Changed', field=u'Loaned To', old=u'%s' % system.loaned, new=u'None') system.loaned = None # Change the owner to the caller for system in System.query.filter(System.owner == user): system.owner = identity.current.user system.record_activity(user=identity.current.user, service=method, action=u'Changed', field=u'Owner', old=u'%s' % user, new=u'%s' % identity.current.user) # Finally remove the user user.removed = datetime.utcnow()
def files(self, recipe_id): """ Return an array of logs for the given recipe. :param recipe_id: id of recipe :type recipe_id: integer .. deprecated:: 0.9.4 Use :meth:`taskactions.files() <bkr.server.task_actions.taskactions.files>` instead. """ try: recipe = Recipe.by_id(recipe_id) except InvalidRequestError: raise BX(_('Invalid recipe ID: %s' % recipe_id)) # Build a list of logs excluding duplicate paths, to mitigate: # https://bugzilla.redhat.com/show_bug.cgi?id=963492 logdicts = [] seen_paths = set() for log in recipe.all_logs(): logdict = log.dict # The path we care about here is the path which beaker-transfer # will move the file to. # Don't be tempted to use os.path.join() here since log['path'] # is often '/' which does not give the result you would expect. path = os.path.normpath( '%s/%s/%s' % (logdict['filepath'], logdict['path'], logdict['filename'])) if path in seen_paths: logger.warn('%s contains duplicate log %s', log.parent.t_id, path) else: seen_paths.add(path) logdicts.append(logdict) return logdicts
def get_osmajor(self, distro): """ pass in a distro name and get back the osmajor is belongs to. """ try: osmajor = '%s' % Distro.by_name(distro).osversion.osmajor except DatabaseLookupError: raise BX(_('Invalid Distro: %s' % distro)) return osmajor
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 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 really_return_reservation(self, id, msg=None): try: recipe = Recipe.by_id(id) except InvalidRequestError: raise BX(_("Invalid Recipe ID %s" % id)) recipe.return_reservation() flash(_(u"Successfully released reserved system for %s" % recipe.t_id)) redirect('/jobs/mine')
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 add_submission_delegate_by_name(self, new_delegate_name, service=u'XMLRPC'): user = identity.current.user new_delegate = User.by_user_name(new_delegate_name) if not new_delegate: raise BX(_(u'%s is not a valid user' % new_delegate_name)) user.add_submission_delegate(new_delegate, service) return new_delegate_name
def extend(self, recipe_id, kill_time): """ Extend recipe watchdog by kill_time seconds """ try: recipe = Recipe.by_id(recipe_id) except InvalidRequestError: raise BX(_('Invalid recipe ID: %s' % recipe_id)) return recipe.extend(kill_time)
def _process_job_tag_product(self, retention_tag=None, product=None, *args, **kw): """ Process job retention_tag and product """ retention_tag = retention_tag or RetentionTag.get_default().tag try: tag = RetentionTag.by_tag(retention_tag.lower()) except InvalidRequestError: raise BX( _("Invalid retention_tag attribute passed. Needs to be one of %s. You gave: %s" % (','.join([x.tag for x in RetentionTag.get_all() ]), retention_tag))) if product is None and tag.requires_product(): raise BX( _("You've selected a tag which needs a product associated with it, \ alternatively you could use one of the following tags %s" % ','.join([ x.tag for x in RetentionTag.get_all() if not x.requires_product() ]))) elif product is not None and not tag.requires_product(): raise BX( _("Cannot specify a product with tag %s, please use %s as a tag " % (retention_tag, ','.join([ x.tag for x in RetentionTag.get_all() if x.requires_product() ])))) else: pass if tag.requires_product(): try: product = Product.by_name(product) return (tag, product) except ValueError: raise BX(_("You entered an invalid product name: %s" % product)) else: return tag, None
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 postinstall_done(self, recipe_id=None): """ Report completion of postinstallation """ try: recipe = Recipe.by_id(recipe_id) except InvalidRequestError: raise BX(_(u'Invalid Recipe ID %s' % recipe_id)) recipe.resource.postinstall_finished = datetime.utcnow() return True
def console_output(self, recipe_id, output_length=None, offset=None): """ Get text console log output from OpenStack """ try: recipe = Recipe.by_id(recipe_id) except InvalidRequestError: raise BX(_('Invalid recipe ID: %s' % recipe_id)) manager = dynamic_virt.VirtManager(recipe.recipeset.job.owner) return manager.get_console_output(recipe.resource.instance_id, output_length)
def _handle_recipe_set(self, xmlrecipeSet, user, ignore_missing_tasks=False): """ Handles the processing of recipesets into DB entries from their xml """ recipeSet = RecipeSet(ttasks=0) recipeset_priority = xmlrecipeSet.get_xml_attr('priority', unicode, None) if recipeset_priority is not None: try: my_priority = TaskPriority.from_string(recipeset_priority) except InvalidRequestError: raise BX( _('You have specified an invalid recipeSet priority:%s' % recipeset_priority)) allowed_priorities = RecipeSet.allowed_priorities_initial(user) if my_priority in allowed_priorities: recipeSet.priority = my_priority else: recipeSet.priority = TaskPriority.default_priority() else: recipeSet.priority = TaskPriority.default_priority() for xmlrecipe in xmlrecipeSet.iter_recipes(): recipe = self.handleRecipe( xmlrecipe, user, ignore_missing_tasks=ignore_missing_tasks) recipe.ttasks = len(recipe.tasks) recipeSet.ttasks += recipe.ttasks recipeSet.recipes.append(recipe) # We want the guests to be part of the same recipeSet for guest in recipe.guests: recipeSet.recipes.append(guest) guest.ttasks = len(guest.tasks) recipeSet.ttasks += guest.ttasks if not recipeSet.recipes: raise BX( _('No Recipes! You can not have a recipeSet with no recipes!')) return recipeSet
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) except InvalidRequestError: raise BX(_('Invalid result ID: %s' % result_id)) if result.recipetask.is_finished(): raise BX('Cannot register file for finished task %s' % result.recipetask.t_id) 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 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 remove_account(self, username): """ Remove a user account. Removing a user account cancels any running job(s), returns all the systems in use by the user, modifies the ownership of the systems owned to the admin closing the account, and disables the account for further login. :param username: An existing username :type username: string """ try: user = User.by_user_name(username) except InvalidRequestError: raise BX(_('Invalid User %s ' % username)) if user.removed: raise BX(_('User already removed %s' % username)) self._remove(user=user, method='XMLRPC')
def register_file(self, server, recipe_id, path, filename, basepath): """ register file and return path to store """ try: recipe = Recipe.by_id(recipe_id, lockmode='update') except NoResultFound: raise BX(_('Invalid recipe ID: %s' % recipe_id)) if recipe.is_finished(): raise BX('Cannot register file for finished recipe %s' % recipe.t_id) # Add the log to the DB if it hasn't been recorded yet. log_recipe = LogRecipe.lazy_create(recipe_id=recipe.id, path=path, filename=filename, ) log_recipe.server = server log_recipe.basepath = basepath # Pull log_server out of server_url. recipe.log_server = urlparse.urlparse(server)[1] return '%s' % recipe.filepath
def get_arch(self, filter): """ pass in a dict() with either distro or osmajor to get possible arches """ if 'distro' in filter: # look up distro try: arches = [ arch.arch for arch in Distro.by_name( filter['distro']).osversion.arches ] except DatabaseLookupError: raise BX(_('Invalid Distro: %s' % filter['distro'])) elif 'osmajor' in filter: # look up osmajor try: arches = [ arch.arch for arch in OSMajor.by_name( filter['osmajor']).osversions[0].arches ] except InvalidRequestError: raise BX(_('Invalid OSMajor: %s' % filter['osmajor'])) return arches
def upload(self, task_rpm_name, task_rpm_data): """ Uploads a new task RPM. :param task_rpm_name: filename of the task RPM, for example ``'beaker-distribution-install-1.10-11.noarch.rpm'`` :type task_rpm_name: string :param task_rpm_data: contents of the task RPM :type task_rpm_data: XML-RPC binary """ rpm_path = Task.get_rpm_path(task_rpm_name) # we do it here, since we do not want to proceed # any further if len(task_rpm_name) > 255: raise BX(_("Task RPM name should be <= 255 characters")) if os.path.exists("%s" % rpm_path): raise BX(_(u'Cannot import duplicate task %s') % task_rpm_name) def write_data(f): f.write(task_rpm_data.data) Task.update_task(task_rpm_name, write_data) return "Success"
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 return_reservation(self, recipe_id=None): """ End recipe reservation """ if not recipe_id: raise BX(_("No recipe id provided!")) return dict( title='Release reserved system for Recipe %s' % recipe_id, form=self.return_reservation_form, action='./really_return_reservation', options={}, value=dict(id=recipe_id), )
def change_files(self, recipe_id, server, basepath): """ Change the server and basepath where the log files lives, Usually used to move from lab controller cache to archive storage. """ try: recipe = Recipe.by_id(recipe_id) except InvalidRequestError: raise BX(_('Invalid recipe ID: %s' % recipe_id)) for mylog in recipe.all_logs(): mylog.server = '%s/%s/' % (server, mylog.parent.filepath) mylog.basepath = '%s/%s/' % (basepath, mylog.parent.filepath) recipe.log_server = urlparse.urlparse(server)[1] return True