Example #1
0
 def handleRecipe(self,
                  xmlrecipe,
                  user,
                  guest=False,
                  ignore_missing_tasks=False):
     if not guest:
         recipe = MachineRecipe(ttasks=0)
         for xmlguest in xmlrecipe.iter_guests():
             guestrecipe = self.handleRecipe(
                 xmlguest,
                 user,
                 guest=True,
                 ignore_missing_tasks=ignore_missing_tasks)
             recipe.guests.append(guestrecipe)
     else:
         recipe = GuestRecipe(ttasks=0)
         recipe.guestname = xmlrecipe.guestname
         recipe.guestargs = xmlrecipe.guestargs
     recipe.host_requires = xmlrecipe.hostRequires()
     recipe.distro_requires = xmlrecipe.distroRequires()
     recipe.partitions = xmlrecipe.partitions()
     try:
         recipe.distro_tree = DistroTree.by_filter(
             "%s" % recipe.distro_requires)[0]
     except IndexError:
         raise BX(
             _('No distro tree matches Recipe: %s') %
             recipe.distro_requires)
     try:
         # try evaluating the host_requires, to make sure it's valid
         systems = XmlHost.from_string(recipe.host_requires).apply_filter(
             System.query)
     except StandardError, e:
         raise BX(_('Error in hostRequires: %s' % e))
Example #2
0
 def check_filter(self, filterxml, present=[], absent=[]):
     session.flush()
     query = XmlHost.from_string(filterxml).apply_filter(System.query)
     if present:
         self.assertItemsEqual(present,
                 query.filter(System.id.in_([s.id for s in present])).all())
     if absent:
         self.assertItemsEqual([],
                 query.filter(System.id.in_([s.id for s in absent])).all())
Example #3
0
 def check_filter(self, filterxml, present=[], absent=[]):
     session.flush()
     query = XmlHost.from_string(filterxml).apply_filter(System.query)
     if present:
         self.assertItemsEqual(present,
                 query.filter(System.id.in_([s.id for s in present])).all())
     if absent:
         self.assertItemsEqual([],
                 query.filter(System.id.in_([s.id for s in absent])).all())
Example #4
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 #5
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 #6
0
 def test_multiple_nonexistent_keys(self):
     filter = """
         <hostRequires>
             <and>
                 <key_value key="NOTEXIST1" op="=" value="asdf"/>
                 <key_value key="NOTEXIST2" op="=" value="asdf"/>
             </and>
         </hostRequires>
         """
     query = XmlHost.from_string(filter).apply_filter(System.query)
     query.all() # don't care about the results, just that it doesn't break
Example #7
0
 def test_multiple_nonexistent_keys(self):
     filter = """
         <hostRequires>
             <and>
                 <key_value key="NOTEXIST1" op="=" value="asdf"/>
                 <key_value key="NOTEXIST2" op="=" value="asdf"/>
             </and>
         </hostRequires>
         """
     query = XmlHost.from_string(filter).apply_filter(System.query)
     query.all() # don't care about the results, just that it doesn't break
Example #8
0
 def test_arch_inside_or(self):
     # The bug was that <arch/> inside <or/> with other conditions would 
     # produce a cartesian product where the join condition was on one side 
     # of the OR, leading to a row explosion (similar to the case above).
     lc = data_setup.create_labcontroller(fqdn=u'bz1183239.lab')
     data_setup.create_system(lab_controller=lc, arch=[u'i386', u'x86_64'])
     session.flush()
     filter = """
         <hostRequires>
             <labcontroller value="bz1183239.lab" />
             <or>
                 <system><arch value="i386" /></system>
                 <hostname op="!=" value="blerch" />
             </or>
         </hostRequires>
         """
     query = XmlHost.from_string(filter).apply_filter(System.query)
     self.assertEquals(len(query.all()), 1)
     # with the bug this count comes out as 2 instead of 1,
     # which doesn't sound so bad...
     # but when it's 30575826 instead of 4131, that's bad
     self.assertEquals(query.count(), 1)
Example #9
0
 def test_keyvalue_does_not_cause_duplicate_rows(self):
     system = data_setup.create_system()
     disk_key = Key.by_name(u'DISK')
     system.key_values_int.extend([
             Key_Value_Int(disk_key, 30718),
             Key_Value_Int(disk_key, 140011),
             Key_Value_Int(disk_key, 1048570)])
     session.flush()
     filter = """
         <hostRequires>
             <and>
                 <system><name op="=" value="%s" /></system>
                 <key_value key="DISK" op="&gt;" value="9000" />
             </and>
         </hostRequires>
         """ % system.fqdn
     query = XmlHost.from_string(filter).apply_filter(System.query)
     self.assertEquals(len(query.all()), 1)
     # with the bug this count comes out as 3 instead of 1,
     # which doesn't sound so bad...
     # but when it's 926127 instead of 278, that's bad
     self.assertEquals(query.count(), 1)
Example #10
0
 def test_keyvalue_does_not_cause_duplicate_rows(self):
     system = data_setup.create_system()
     disk_key = Key.by_name(u'DISK')
     system.key_values_int.extend([
             Key_Value_Int(disk_key, 30718),
             Key_Value_Int(disk_key, 140011),
             Key_Value_Int(disk_key, 1048570)])
     session.flush()
     filter = """
         <hostRequires>
             <and>
                 <system><name op="=" value="%s" /></system>
                 <key_value key="DISK" op="&gt;" value="9000" />
             </and>
         </hostRequires>
         """ % system.fqdn
     query = XmlHost.from_string(filter).apply_filter(System.query)
     self.assertEquals(len(query.all()), 1)
     # with the bug this count comes out as 3 instead of 1,
     # which doesn't sound so bad...
     # but when it's 926127 instead of 278, that's bad
     self.assertEquals(query.count(), 1)
Example #11
0
 def handleRecipe(self, xmlrecipe, user, guest=False, ignore_missing_tasks=False):
     if not guest:
         recipe = MachineRecipe(ttasks=0)
         for xmlguest in xmlrecipe.iter_guests():
             guestrecipe = self.handleRecipe(xmlguest, user, guest=True,
                     ignore_missing_tasks=ignore_missing_tasks)
             recipe.guests.append(guestrecipe)
     else:
         recipe = GuestRecipe(ttasks=0)
         recipe.guestname = xmlrecipe.guestname
         recipe.guestargs = xmlrecipe.guestargs
     recipe.host_requires = xmlrecipe.hostRequires()
     recipe.distro_requires = xmlrecipe.distroRequires()
     recipe.partitions = xmlrecipe.partitions()
     try:
         recipe.distro_tree = DistroTree.by_filter("%s" %
                                        recipe.distro_requires)[0]
     except IndexError:
         raise BX(_('No distro tree matches Recipe: %s') % recipe.distro_requires)
     try:
         # try evaluating the host_requires, to make sure it's valid
         systems = XmlHost.from_string(recipe.host_requires).apply_filter(System.query)
     except StandardError, e:
         raise BX(_('Error in hostRequires: %s' % e))
Example #12
0
 def check_filter(self, filterxml, lab_controller=None, present=[], absent=[]):
     if lab_controller is None:
         lab_controller = self.lc
     matched_flavors = XmlHost.from_string(filterxml)\
         .filter_openstack_flavors(present + absent, lab_controller)
     self.assertItemsEqual(present, matched_flavors)
Example #13
0
 def check_filter(self, filterxml, virtualisable_expected):
     result = XmlHost.from_string(filterxml).virtualisable()
     self.assertEquals(result, virtualisable_expected)
Example #14
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)
        job_owner = recipe.recipeset.job.owner
        manager = dynamic_virt.VirtManager(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.info(
                'No OpenStack flavors matched recipe %s, marking precluded',
                recipe.id)
            recipe.virt_status = RecipeVirtStatus.precluded
            return
        # cheapest flavor has the smallest disk and ram
        # id guarantees consistency of our results
        flavor = min(possible_flavors,
                     key=lambda flavor: (flavor.ram, flavor.disk, flavor.id))
        vm_name = '%srecipe-%s' % (ConfigItem.by_name(
            u'guest_name_prefix').current_value(u'beaker-'), recipe.id)
        log.debug('Creating VM named %s as flavor %s', vm_name, flavor)
        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 as 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:
        session.close()
Example #15
0
 def check_filter(self, filterxml, lab_controller=None, present=[], absent=[]):
     if lab_controller is None:
         lab_controller = self.lc
     matched_flavors = XmlHost.from_string(filterxml)\
         .filter_openstack_flavors(present + absent, lab_controller)
     self.assertItemsEqual(present, matched_flavors)
Example #16
0
 def check_filter(self, filterxml, virtualisable_expected):
     result = XmlHost.from_string(filterxml).virtualisable()
     self.assertEquals(result, virtualisable_expected)