Example #1
0
    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
Example #2
0
def provision_virt_recipe(recipe_id):
    log.debug('Attempting to provision dynamic virt guest for recipe %s', recipe_id)
    session.begin()
    try:
        recipe = Recipe.by_id(recipe_id)
        manager = dynamic_virt.VirtManager(recipe.recipeset.job.owner)
        available_flavors = manager.available_flavors()
        # We want them in order of smallest to largest, so that we can pick the
        # smallest flavor that satisfies the recipe's requirements. Sorting by RAM
        # is a decent approximation.
        possible_flavors = XmlHost.from_string(recipe.host_requires)\
            .filter_openstack_flavors(available_flavors, manager.lab_controller)
        if not possible_flavors:
            log.debug('No OpenStack flavors matched recipe %s, marking precluded',
                    recipe.id)
            recipe.virt_status = RecipeVirtStatus.precluded
            return
        possible_flavors = sorted(possible_flavors, key=lambda flavor: flavor.ram)
        flavor = possible_flavors[0]
        vm_name = '%srecipe-%s' % (
                ConfigItem.by_name(u'guest_name_prefix').current_value(u'beaker-'),
                recipe.id)
        # FIXME can we control use of virtio?
        #virtio_possible = True
        #if self.recipe.distro_tree.distro.osversion.osmajor.osmajor == "RedHatEnterpriseLinux3":
        #    virtio_possible = False
        vm = manager.create_vm(vm_name, flavor)
        vm.instance_created = datetime.utcnow()
        try:
            recipe.createRepo()
            recipe.clear_candidate_systems()
            recipe.watchdog = Watchdog()
            recipe.resource = vm
            recipe.recipeset.lab_controller = manager.lab_controller
            recipe.virt_status = RecipeVirtStatus.succeeded
            recipe.schedule()
            log.info("recipe ID %s moved from Queued to Scheduled by provision_virt_recipe" % recipe.id)
            recipe.waiting()
            recipe.provision()
            log.info("recipe ID %s moved from Scheduled to Waiting by provision_virt_recipe" % recipe.id)
        except:
            exc_type, exc_value, exc_tb = sys.exc_info()
            try:
                manager.destroy_vm(vm)
            except Exception:
                log.exception('Failed to clean up vm %s '
                        'during provision_virt_recipe, leaked!', vm.instance_id)
                # suppress this exception so the original one is not masked
            raise exc_type, exc_value, exc_tb
        session.commit()
    except Exception, e:
        log.exception('Error in provision_virt_recipe(%s)', recipe_id)
        session.rollback()
        # As an added precaution, let's try and avoid this recipe in future
        with session.begin():
            recipe = Recipe.by_id(recipe_id)
            recipe.virt_status = RecipeVirtStatus.failed
Example #3
0
def provision_virt_recipe(recipe_id):
    log.debug('Attempting to provision dynamic virt guest for recipe %s', recipe_id)
    session.begin()
    try:
        recipe = Recipe.by_id(recipe_id)
        manager = dynamic_virt.VirtManager(recipe.recipeset.job.owner)
        available_flavors = manager.available_flavors()
        # We want them in order of smallest to largest, so that we can pick the
        # smallest flavor that satisfies the recipe's requirements. Sorting by RAM
        # is a decent approximation.
        possible_flavors = XmlHost.from_string(recipe.host_requires)\
            .filter_openstack_flavors(available_flavors, manager.lab_controller)
        if not possible_flavors:
            log.debug('No OpenStack flavors matched recipe %s, marking precluded',
                    recipe.id)
            recipe.virt_status = RecipeVirtStatus.precluded
            return
        possible_flavors = sorted(possible_flavors, key=lambda flavor: flavor.ram)
        flavor = possible_flavors[0]
        vm_name = '%srecipe-%s' % (
                ConfigItem.by_name(u'guest_name_prefix').current_value(u'beaker-'),
                recipe.id)
        # FIXME can we control use of virtio?
        #virtio_possible = True
        #if self.recipe.distro_tree.distro.osversion.osmajor.osmajor == "RedHatEnterpriseLinux3":
        #    virtio_possible = False
        vm = manager.create_vm(vm_name, flavor)
        vm.instance_created = datetime.utcnow()
        try:
            recipe.createRepo()
            recipe.systems = []
            recipe.watchdog = Watchdog()
            recipe.resource = vm
            recipe.recipeset.lab_controller = manager.lab_controller
            recipe.virt_status = RecipeVirtStatus.succeeded
            recipe.schedule()
            log.info("recipe ID %s moved from Queued to Scheduled by provision_virt_recipe" % recipe.id)
            recipe.waiting()
            recipe.provision()
            log.info("recipe ID %s moved from Scheduled to Waiting by provision_virt_recipe" % recipe.id)
        except:
            exc_type, exc_value, exc_tb = sys.exc_info()
            try:
                manager.destroy_vm(vm)
            except Exception:
                log.exception('Failed to clean up vm %s '
                        'during provision_virt_recipe, leaked!', vm.instance_id)
                # suppress this exception so the original one is not masked
            raise exc_type, exc_value, exc_tb
        session.commit()
    except Exception, e:
        log.exception('Error in provision_virt_recipe(%s)', recipe_id)
        session.rollback()
        # As an added precaution, let's try and avoid this recipe in future
        with session.begin():
            recipe = Recipe.by_id(recipe_id)
            recipe.virt_status = RecipeVirtStatus.failed
Example #4
0
def provision_virt_recipes(*args):
    # We limit to labs where the tree is available by NFS because RHEV needs to 
    # use autofs to grab the images. See VirtManager.start_install.
    recipes = MachineRecipe.query\
            .join(Recipe.recipeset).join(RecipeSet.job)\
            .filter(Job.dirty_version == Job.clean_version)\
            .join(Recipe.distro_tree, DistroTree.lab_controller_assocs, LabController)\
            .filter(Recipe.status == TaskStatus.queued)\
            .filter(Recipe.virt_status == RecipeVirtStatus.possible)\
            .filter(LabController.disabled == False)\
            .filter(or_(RecipeSet.lab_controller == None,
                RecipeSet.lab_controller_id == LabController.id))\
            .filter(LabControllerDistroTree.url.like(u'nfs://%'))\
            .order_by(RecipeSet.priority.desc(), Recipe.id.asc())
    if not recipes.count():
        return False
    log.debug("Entering provision_virt_recipes")
    for recipe_id, in recipes.values(Recipe.id.distinct()):
        system_name = None
        session.begin()
        try:
            system_name = u'%srecipe_%s' % (
                    ConfigItem.by_name(u'guest_name_prefix').current_value(u'beaker_'),
                    recipe_id)
            provision_virt_recipe(system_name, recipe_id)
            session.commit()
        except needpropertyxml.NotVirtualisable:
            session.rollback()
            session.begin()
            recipe = Recipe.by_id(recipe_id)
            recipe.virt_status = RecipeVirtStatus.precluded
            session.commit()
        except VMCreationFailedException:
            session.rollback()
            session.begin()
            recipe = Recipe.by_id(recipe_id)
            recipe.virt_status = RecipeVirtStatus.skipped
            session.commit()
        except Exception, e: # This will get ovirt RequestErrors from recipe.provision()
            log.exception('Error in provision_virt_recipe(%s)', recipe_id)
            session.rollback()
            try:
                # Don't leak the vm if it was created
                if system_name:
                    with dynamic_virt.VirtManager() as manager:
                        manager.destroy_vm(system_name)
                # As an added precaution, let's try and avoid this recipe in future
                session.begin()
                recipe = Recipe.by_id(recipe_id)
                recipe.virt_status = RecipeVirtStatus.failed
                session.commit()
            except Exception:
                log.exception('Exception in exception handler :-(')
        finally:
Example #5
0
def provision_virt_recipes(*args):
    recipes = MachineRecipe.query\
            .join(Recipe.recipeset).join(RecipeSet.job)\
            .filter(Job.dirty_version == Job.clean_version)\
            .join(Recipe.distro_tree, DistroTree.lab_controller_assocs, LabController)\
            .filter(Recipe.status == TaskStatus.queued)\
            .filter(Recipe.virt_status == RecipeVirtStatus.possible)\
            .filter(LabController.disabled == False)\
            .filter(or_(RecipeSet.lab_controller == None,
                RecipeSet.lab_controller_id == LabController.id))\
            .order_by(RecipeSet.priority.desc(), Recipe.id.asc())
    if not recipes.count():
        return False
    log.debug("Entering provision_virt_recipes")
    for recipe_id, in recipes.values(Recipe.id.distinct()):
        session.begin()
        try:
            provision_virt_recipe(recipe_id)
            session.commit()
        except Exception, e:
            log.exception('Error in provision_virt_recipe(%s)', recipe_id)
            session.rollback()
            # As an added precaution, let's try and avoid this recipe in future
            with session.begin():
                recipe = Recipe.by_id(recipe_id)
                recipe.virt_status = RecipeVirtStatus.failed
        finally:
Example #6
0
 def tearDown(self):
     admin_user = User.by_user_name(data_setup.ADMIN_USER)
     if getattr(self,'recipe_id', None):
         with session.begin():
             recipe = Recipe.by_id(self.recipe_id)
             if recipe.resource.system.open_reservation:
                 recipe.resource.release()
Example #7
0
    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
Example #8
0
 def tearDown(self):
     admin_user = User.by_user_name(data_setup.ADMIN_USER)
     if getattr(self, 'recipe_id', None):
         with session.begin():
             recipe = Recipe.by_id(self.recipe_id)
             if recipe.resource.system.open_reservation:
                 recipe.resource.release()
Example #9
0
    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
Example #10
0
    def install_done(self, recipe_id=None, fqdn=None):
        """
        Report completion of installation with current FQDN
        """
        if not recipe_id:
            raise BX(_("No recipe id provided!"))

        try:
            recipe = Recipe.by_id(recipe_id)
        except InvalidRequestError:
            raise BX(_("Invalid Recipe ID %s" % recipe_id))
        if not recipe.installation:
            raise BX(_('Recipe %s not provisioned yet') % recipe_id)

        recipe.installation.install_finished = datetime.utcnow()
        # We don't want to change an existing FQDN, just set it
        # if it hasn't been set already (see BZ#879146)
        configured = recipe.resource.fqdn
        if configured is None and fqdn:
            recipe.resource.fqdn = configured = fqdn
        elif configured != fqdn:
            # We use eager formatting here to make this easier to test
            logger.info("Configured FQDN (%s) != reported FQDN (%s) in R:%s" %
                        (configured, fqdn, recipe_id))
        return configured
Example #11
0
def provision_virt_recipe(system_name, recipe_id):
    recipe = Recipe.by_id(recipe_id)
    recipe.createRepo()
    # Figure out the "data centers" where we can run the recipe
    if recipe.recipeset.lab_controller:
        # First recipe of a recipeSet determines the lab_controller
        lab_controllers = [recipe.recipeset.lab_controller]
    else:
        # NB the same criteria are also expressed above
        lab_controllers = LabController.query.filter_by(disabled=False, removed=None)
        lab_controllers = needpropertyxml.apply_lab_controller_filter(
                recipe.host_requires, lab_controllers)

    lab_controllers = [lc for lc in lab_controllers.all()
            if recipe.distro_tree.url_in_lab(lc, 'nfs')]
    recipe.systems = []
    recipe.watchdog = Watchdog()
    recipe.resource = VirtResource(system_name=system_name)
    with dynamic_virt.VirtManager() as manager:
        recipe.resource.allocate(manager, lab_controllers)
    recipe.recipeset.lab_controller = recipe.resource.lab_controller
    recipe.schedule()
    log.info("recipe ID %s moved from Queued to Scheduled by provision_virt_recipe" % recipe.id)
    recipe.waiting()
    recipe.provision()
    log.info("recipe ID %s moved from Scheduled to Waiting by provision_virt_recipe" % recipe.id)
Example #12
0
    def install_done(self, recipe_id=None, fqdn=None):
        """
        Report completion of installation with current FQDN
        """
        if not recipe_id:
            raise BX(_("No recipe id provided!"))
        if not fqdn:
            raise BX(_("No fqdn provided!"))

        try:
            recipe = Recipe.by_id(recipe_id)
        except InvalidRequestError:
            raise BX(_("Invalid Recipe ID %s" % recipe_id))

        recipe.resource.install_finished = datetime.utcnow()
        # We don't want to change an existing FQDN, just set it
        # if it hasn't been set already (see BZ#879146)
        configured = recipe.resource.fqdn
        if configured is None:
            recipe.resource.fqdn = configured = fqdn
        elif configured != fqdn:
            # We use eager formatting here to make this easier to test
            log.info("Configured FQDN (%s) != reported FQDN (%s) in R:%s" %
                     (configured, fqdn, recipe_id))
        return configured
Example #13
0
 def run(self):
     session.begin()
     recipe = Recipe.by_id(self.recipe_id)
     self.ready_evt.set()
     self.continue_evt.wait()
     recipe.tasks[-1].stop()
     session.commit()
Example #14
0
 def run(self):
     session.begin()
     recipe = Recipe.by_id(self.recipe_id)
     self.ready_evt.set()
     self.continue_evt.wait()
     recipe.tasks[-1].stop()
     session.commit()
Example #15
0
def provision_virt_recipes(*args):
    recipes = MachineRecipe.query\
            .join(Recipe.recipeset).join(RecipeSet.job)\
            .filter(Job.dirty_version == Job.clean_version)\
            .join(Recipe.distro_tree, DistroTree.lab_controller_assocs, LabController)\
            .filter(Recipe.status == TaskStatus.queued)\
            .filter(Recipe.virt_status == RecipeVirtStatus.possible)\
            .filter(LabController.disabled == False)\
            .filter(or_(RecipeSet.lab_controller == None,
                RecipeSet.lab_controller_id == LabController.id))\
            .order_by(RecipeSet.priority.desc(), Recipe.id.asc())
    if not recipes.count():
        return False
    log.debug("Entering provision_virt_recipes")
    for recipe_id, in recipes.values(Recipe.id.distinct()):
        session.begin()
        try:
            provision_virt_recipe(recipe_id)
            session.commit()
        except Exception, e:
            log.exception('Error in provision_virt_recipe(%s)', recipe_id)
            session.rollback()
            # As an added precaution, let's try and avoid this recipe in future
            with session.begin():
                recipe = Recipe.by_id(recipe_id)
                recipe.virt_status = RecipeVirtStatus.failed
        finally:
Example #16
0
    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
Example #17
0
    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
Example #18
0
    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')
Example #19
0
 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)
Example #20
0
    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')
Example #21
0
 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)
Example #22
0
 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
Example #23
0
 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)
Example #24
0
 def test_rendered_kickstart_is_deleted(self):
     with session.begin():
         self.job_to_delete.to_delete = datetime.datetime.utcnow()
         recipe = self.job_to_delete.recipesets[0].recipes[0]
         ks = RenderedKickstart(kickstart=u'This is not a real kickstart.')
         recipe.rendered_kickstart = ks
     log_delete.log_delete()
     with session.begin():
         self.assertEqual(Recipe.by_id(recipe.id).rendered_kickstart, None)
         self.assertRaises(NoResultFound, RenderedKickstart.by_id, ks.id)
Example #25
0
 def test_rendered_kickstart_is_deleted(self):
     with session.begin():
         self.job_to_delete.to_delete = datetime.datetime.utcnow()
         recipe = self.job_to_delete.recipesets[0].recipes[0]
         ks = RenderedKickstart(kickstart=u'This is not a real kickstart.')
         recipe.rendered_kickstart = ks
     log_delete.log_delete()
     with session.begin():
         self.assertEqual(Recipe.by_id(recipe.id).rendered_kickstart, None)
         self.assertRaises(NoResultFound, RenderedKickstart.by_id, ks.id)
Example #26
0
 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)
Example #27
0
 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
Example #28
0
 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 = Recipe.by_id(recipe_id).to_xml().toprettyxml()
     except InvalidRequestError:
         raise BX(_("Invalid Recipe ID %s" % recipe_id))
     return recipexml
Example #29
0
 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 = Recipe.by_id(recipe_id).to_xml().toprettyxml()
     except InvalidRequestError:
         raise BX(_("Invalid Recipe ID %s" % recipe_id))
     return recipexml
Example #30
0
    def install_fail(self, recipe_id=None):
        """
        Records the fail of a recipe's installation.
        """
        try:
            recipe = Recipe.by_id(recipe_id)
        except InvalidRequestError:
            raise BX(_("Invalid Recipe ID {}".format(recipe_id)))  # noqa: F821
        if not recipe.installation:
            raise BX(_("Recipe {} not provisioned yet".format(recipe_id)))  # noqa: F821

        return recipe.abort('Installation failed')
Example #31
0
 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
Example #32
0
 def default(self, id):
     try:
         recipe = Recipe.by_id(id)
     except InvalidRequestError:
         flash(_(u"Invalid recipe id %s" % id))
         redirect(".")
     if recipe.is_deleted():
         flash(_(u"Invalid %s, has been deleted" % recipe.t_id))
         redirect(".")
     return dict(title='Recipe',
                 recipe_widget=self.recipe_widget,
                 recipe=recipe)
Example #33
0
 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
Example #34
0
 def systems(self, recipe_id=None, *args, **kw):
     try:
         recipe = Recipe.by_id(recipe_id)
     except NoResultFound:
         flash(_(u"Invalid recipe id %s" % recipe_id))
         redirect(url("/recipes"))
     PDC = widgets.PaginateDataGrid.Column
     fields = [PDC(name='fqdn', getter=lambda x: x.link, title='Name'),
         PDC(name='user', getter=lambda x: x.user.email_link if x.user else None, title='User'),]
     grid = myPaginateDataGrid(fields=fields)
     return dict(title='Recipe Systems', grid=grid, list=recipe.systems,
         search_bar=None)
Example #35
0
 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
Example #36
0
 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
Example #37
0
 def default(self, id):
     try:
         recipe = Recipe.by_id(id)
     except InvalidRequestError:
         flash(_(u"Invalid recipe id %s" % id))
         redirect(".")
     if recipe.is_deleted():
         flash(_(u"Invalid %s, has been deleted" % recipe.t_id))
         redirect(".")
     return dict(title   = 'Recipe',
                 recipe_widget        = self.recipe_widget,
                 recipe               = recipe)
Example #38
0
 def systems(self, recipe_id=None, *args, **kw):
     try:
         recipe = Recipe.by_id(recipe_id)
     except NoResultFound:
         flash(_(u"Invalid recipe id %s" % recipe_id))
         redirect(url("/recipes"))
     PDC = widgets.PaginateDataGrid.Column
     fields = [PDC(name='fqdn', getter=lambda x: x.link, title='Name'),
         PDC(name='user', getter=lambda x: x.user.email_link if x.user else None, title='User'),]
     grid = myPaginateDataGrid(fields=fields)
     return dict(title='Recipe Systems', grid=grid, list=recipe.systems,
         search_bar=None)
Example #39
0
 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)
Example #40
0
 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)
Example #41
0
 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
Example #42
0
 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
Example #43
0
    def register_file(self, server, task_id, path, filename, basepath):
        """
        register file and return path to store
        """
        try:
            recipetask = RecipeTask.by_id(task_id, lockmode='update')
        except NoResultFound:
            raise BX(_('Invalid task ID: %s' % task_id))
        Recipe.by_id(recipetask.recipe_id, lockmode='update')
        if recipetask.is_finished():
            raise BX('Cannot register file for finished task %s'
                    % recipetask.t_id)
        self._check_log_limit(recipetask)

        # 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
Example #44
0
    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` instead.
        """
        try:
            recipe = Recipe.by_id(recipe_id)
        except InvalidRequestError:
            raise BX(_('Invalid recipe ID: %s' % recipe_id))
        return [log for log in recipe.all_logs]
Example #45
0
    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` instead.
        """
        try:
            recipe = Recipe.by_id(recipe_id)
        except InvalidRequestError:
            raise BX(_('Invalid recipe ID: %s' % recipe_id))
        return [log for log in recipe.all_logs]
Example #46
0
 def default(self, id, *args, **kwargs):
     # When flask returns a 404, it falls back to here so we need to
     # raise a cherrypy 404.
     if cherrypy.request.method == 'POST':
         raise cherrypy.HTTPError(404)
     try:
         recipe = Recipe.by_id(id)
     except InvalidRequestError:
         flash(_(u"Invalid recipe id %s" % id))
         redirect(".")
     if recipe.is_deleted():
         flash(_(u"Invalid %s, has been deleted" % recipe.t_id))
         redirect(".")
     return dict(title   = 'Recipe',
                 recipe_widget        = self.recipe_widget,
                 recipe               = recipe)
Example #47
0
 def default(self, id, *args, **kwargs):
     # When flask returns a 404, it falls back to here so we need to
     # raise a cherrypy 404.
     if cherrypy.request.method == 'POST':
         raise cherrypy.HTTPError(404)
     try:
         recipe = Recipe.by_id(id)
     except InvalidRequestError:
         flash(_(u"Invalid recipe id %s" % id))
         redirect(".")
     if recipe.is_deleted():
         flash(_(u"Invalid %s, has been deleted" % recipe.t_id))
         redirect(".")
     return dict(title='Recipe',
                 recipe_widget=self.recipe_widget,
                 recipe=recipe)
Example #48
0
    def postreboot(self, recipe_id=None):
        # Backwards compat only, delete this after 0.10:
        # the recipe_id arg used to be hostname
        try:
            int(recipe_id)
        except ValueError:
            system = System.by_fqdn(recipe_id, identity.current.user)
            system.action_power('reboot', service=u'XMLRPC', delay=30)
            return system.fqdn

        try:
            recipe = Recipe.by_id(int(recipe_id))
        except (InvalidRequestError, NoResultFound, ValueError):
            raise BX(_('Invalid recipe ID %s') % recipe_id)
        if isinstance(recipe.resource, SystemResource):
            recipe.resource.system.action_power('reboot',
                    service=u'XMLRPC', delay=30)
        return True
Example #49
0
    def postreboot(self, recipe_id=None):
        # Backwards compat only, delete this after 0.10:
        # the recipe_id arg used to be hostname
        try:
            int(recipe_id)
        except ValueError:
            system = System.by_fqdn(recipe_id, identity.current.user)
            system.action_power('reboot', service=u'XMLRPC', delay=30)
            return system.fqdn

        try:
            recipe = Recipe.by_id(int(recipe_id))
        except (InvalidRequestError, NoResultFound, ValueError):
            raise BX(_('Invalid recipe ID %s') % recipe_id)
        if isinstance(recipe.resource, SystemResource):
            recipe.resource.system.action_power('reboot',
                    service=u'XMLRPC', delay=30)
        return True
Example #50
0
 def default(self, id, *args, **kwargs):
     # When flask returns a 404, it falls back to here so we need to
     # raise a cherrypy 404.
     if cherrypy.request.method == 'POST':
         raise cherrypy.HTTPError(404)
     if args:
         raise cherrypy.HTTPError(404)
     if cherrypy.request.path.endswith('/'):
         raise cherrypy.HTTPError(404)
     try:
         recipe = Recipe.by_id(id)
     except InvalidRequestError:
         flash(_(u"Invalid recipe id %s" % id))
         redirect(".")
     if recipe.is_deleted:
         flash(_(u"Invalid %s, has been deleted" % recipe.t_id))
         redirect(".")
     recipe.set_reviewed_state(identity.current.user, True)
     return dict(title   = 'Recipe',
                 recipe_widget        = self.recipe_widget,
                 recipe               = recipe)
Example #51
0
    def register_file(self, server, recipe_id, path, filename, basepath):
        """
        register file and return path to store
        """
        try:
            recipe = Recipe.by_id(recipe_id)
        except InvalidRequestError:
            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
Example #52
0
 def default(self, id, *args, **kwargs):
     # When flask returns a 404, it falls back to here so we need to
     # raise a cherrypy 404.
     if cherrypy.request.method == 'POST':
         raise cherrypy.HTTPError(404)
     if args:
         raise cherrypy.HTTPError(404)
     if cherrypy.request.path.endswith('/'):
         raise cherrypy.HTTPError(404)
     try:
         recipe = Recipe.by_id(id)
     except InvalidRequestError:
         flash(_(u"Invalid recipe id %s" % id))
         redirect(".")
     if recipe.is_deleted:
         flash(_(u"Invalid %s, has been deleted" % recipe.t_id))
         redirect(".")
     if recipe.is_finished() or recipe.status == TaskStatus.reserved:
         recipe.set_reviewed_state(identity.current.user, True)
     return dict(title   = 'Recipe',
                 recipe_widget        = self.recipe_widget,
                 recipe               = recipe)
Example #53
0
    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 test_reserve_with_recipe(self):
        with session.begin():
            recipe = data_setup.create_recipe()
            job = data_setup.create_job_for_recipes([recipe])
            data_setup.mark_job_running(job)
            recipe = Recipe.by_id(recipe.id)
            fqdn = recipe.resource.system.fqdn
            user = recipe.resource.system.user
            recipe.resource.system.loaned = user
            recipe.resource.system.loan_comment = 'Amy, must I jujitsu my ma?'
        system = recipe.resource.system
        # JSON output
        json_out = run_client(
            ['bkr', 'system-status', fqdn, '--format', 'json'])
        json_out = loads(json_out)
        current_reservation = json_out.get('current_reservation')
        self.assertEqual(current_reservation.get('user_name'),
                         unicode(system.user))
        self.assertEqual(current_reservation.get('recipe_id'), '%s' % \
            system.open_reservation.recipe.id)
        self.assertEqual(json_out.get('condition'), '%s' % system.status)

        # Human friendly output
        human_out = run_client(['bkr', 'system-status', fqdn])
        expected_out = textwrap.dedent('''\
            Condition: %s
            Current reservation:
                User: %s
                Recipe ID: %s
                Start time: %s UTC
            Current loan:
                User: %s
                Comment: Amy, must I jujitsu my ma?''' % \
            (system.status, system.user, system.open_reservation.recipe.id,
            system.open_reservation.recipe.start_time.strftime('%Y-%m-%d %H:%M:%S'),
            system.loaned))
        human_out = human_out.rstrip('\n')
        self.assertEqual(human_out, expected_out, human_out)
    def test_reserve_with_recipe(self):
        with session.begin():
            recipe = data_setup.create_recipe()
            job = data_setup.create_job_for_recipes([recipe])
            data_setup.mark_job_running(job)
            recipe = Recipe.by_id(recipe.id)
            fqdn = recipe.resource.system.fqdn
            user = recipe.resource.system.user
            recipe.resource.system.loaned = user
            recipe.resource.system.loan_comment = u'Amy, must I jujitsu my ma?'
        system = recipe.resource.system
        # JSON output
        json_out = run_client(['bkr', 'system-status', fqdn, '--format',
            'json'])
        json_out = loads(json_out)
        current_reservation = json_out.get('current_reservation')
        self.assertEqual(current_reservation.get('user_name'),
            unicode(system.user))
        self.assertEqual(current_reservation.get('recipe_id'), '%s' % \
            system.open_reservation.recipe.id)
        self.assertEqual(json_out.get('condition'), '%s' % system.status)

        # Human friendly output
        human_out = run_client(['bkr', 'system-status', fqdn])
        expected_out = textwrap.dedent('''\
            Condition: %s
            Current reservation:
                User: %s
                Recipe ID: %s
                Start time: %s UTC
            Current loan:
                User: %s
                Comment: Amy, must I jujitsu my ma?''' % \
            (system.status, system.user, system.open_reservation.recipe.id,
            system.open_reservation.recipe.start_time.strftime('%Y-%m-%d %H:%M:%S'),
            system.loaned))
        human_out = human_out.rstrip('\n')
        self.assertEqual(human_out, expected_out, human_out)
Example #56
0
    def install_start(self, recipe_id=None):
        """
        Records the start of a recipe's installation. The watchdog is extended 
        by 3 hours to allow the installation to complete.
        """
        try:
            recipe = Recipe.by_id(recipe_id)
        except InvalidRequestError:
            raise BX(_("Invalid Recipe ID %s" % recipe_id))
        if not recipe.installation:
            raise BX(_('Recipe %s not provisioned yet') % recipe_id)

        installation = recipe.installation
        if not installation.install_started:
            installation.install_started = datetime.utcnow()
            # extend watchdog by 3 hours 60 * 60 * 3
            kill_time = 10800
            logger.debug('Extending watchdog for %s', recipe.t_id)
            recipe.extend(kill_time)
            return True
        else:
            logger.debug('Already recorded install_started for %s', recipe.t_id)
            return False
Example #57
0
    def install_start(self, recipe_id=None):
        """
        Records the start of a recipe's installation. The watchdog is extended 
        by 3 hours to allow the installation to complete.
        """
        try:
            recipe = Recipe.by_id(recipe_id)
        except InvalidRequestError:
            raise BX(_("Invalid Recipe ID %s" % recipe_id))
        if not recipe.installation:
            raise BX(_('Recipe %s not provisioned yet') % recipe_id)

        installation = recipe.installation
        if not installation.install_started:
            installation.install_started = datetime.utcnow()
            # extend watchdog by 3 hours 60 * 60 * 3
            kill_time = 10800
            log.debug('Extending watchdog for %s', recipe.t_id)
            recipe.extend(kill_time)
            return True
        else:
            log.debug('Already recorded install_started for %s', recipe.t_id)
            return False
Example #58
0
    def postreboot(self, recipe_id=None):
        # Backwards compat only, delete this after 0.10:
        # the recipe_id arg used to be hostname
        try:
            int(recipe_id)
        except ValueError:
            system = System.by_fqdn(recipe_id, identity.current.user)
            system.action_power('reboot', service=u'XMLRPC', delay=30)
            return system.fqdn

        try:
            recipe = Recipe.by_id(int(recipe_id))
        except (InvalidRequestError, NoResultFound, ValueError):
            raise BX(_('Invalid recipe ID %s') % recipe_id)
        if isinstance(recipe.resource, SystemResource):
            recipe.resource.system.action_power('reboot',
                    service=u'XMLRPC', delay=30)
        elif isinstance(recipe.resource, VirtResource):
            # XXX this should also be delayed 30 seconds but there is no way
            with dynamic_virt.VirtManager() as manager:
                vm = manager.api.vms.get(recipe.resource.system_name)
                vm.stop()
                vm.start()
        return True
Example #59
0
def _get_recipe_by_id(id):
    """Get recipe by id, reporting HTTP 404 if the recipe is not found"""
    try:
        return Recipe.by_id(id)
    except NoResultFound:
        raise NotFound404('Recipe not found')
Example #60
0
 def watchdog(self, recipe_id):
     try:
         recipe = Recipe.by_id(recipe_id)
     except InvalidRequestError:
         raise BX(_('Invalid recipe ID: %s' % recipe_id))
     return recipe.status_watchdog()