def create_vm(self, name, flavor): image_id = self.region.ipxe_image_id if not image_id: raise RuntimeError('iPXE image has not been uploaded') with VirtNetwork(self.neutronclient, name) as net: instance = self.novaclient.servers.create(name, image_id, flavor, nics=[{ 'net-id': net.network_id }]) log.info('Created %r', instance) try: self._wait_for_build(instance) self._assign_floating_ip(net.floating_ip.get('id'), instance) # would be nice if nova let us build an instance without starting it instance.stop() self._wait_for_stop(instance) return VirtResource(uuid.UUID(instance.id), uuid.UUID(net.network_id), uuid.UUID(net.subnet_id), uuid.UUID(net.router_id), net.floating_ip.get('floating_ip_address'), self.lab_controller) except: exc_type, exc_value, exc_tb = sys.exc_info() try: instance.delete() except Exception: log.exception( 'Failed to clean up %r during create_vm, leaked!', instance) # suppress this exception so the original one is not masked raise exc_type, exc_value, exc_tb
def ipxe_script(uuid): try: resource = VirtResource.by_instance_id(uuid) except (NoResultFound, ValueError): raise NotFound404('Instance is not known to Beaker') if resource.kernel_options is None: # recipe.provision() hasn't been called yet # We need to handle this case because the VM is created and boots up # *before* we generate the kickstart etc raise ServiceUnavailable503('Recipe has not been provisioned yet') distro_tree = resource.recipe.distro_tree distro_tree_url = distro_tree.url_in_lab(resource.lab_controller, scheme=['http', 'ftp']) kernel = distro_tree.image_by_type(ImageType.kernel, KernelType.by_name(u'default')) if not kernel: raise BadRequest400('Kernel image not found for distro tree %s' % distro_tree.id) initrd = resource.recipe.distro_tree.image_by_type( ImageType.initrd, KernelType.by_name(u'default')) if not initrd: raise BadRequest400('Initrd image not found for distro tree %s' % distro_tree.id) kernel_url = urlparse.urljoin(distro_tree_url, kernel.path) initrd_url = urlparse.urljoin(distro_tree_url, initrd.path) kernel_options = resource.kernel_options + ' netboot_method=ipxe' return ('#!ipxe\nkernel %s %s\ninitrd %s\nboot\n' % (kernel_url, kernel_options, initrd_url), 200, [('Content-Type', 'text/plain')])
def ipxe_script(uuid): try: resource = VirtResource.by_instance_id(uuid) except (NoResultFound, ValueError): raise NotFound404('Instance is not known to Beaker') if resource.kernel_options is None: # recipe.provision() hasn't been called yet # We need to handle this case because the VM is created and boots up # *before* we generate the kickstart etc raise ServiceUnavailable503('Recipe has not been provisioned yet') distro_tree = resource.recipe.distro_tree distro_tree_url = distro_tree.url_in_lab(resource.lab_controller, scheme=['http', 'ftp']) kernel = distro_tree.image_by_type(ImageType.kernel, KernelType.by_name(u'default')) if not kernel: raise BadRequest400('Kernel image not found for distro tree %s' % distro_tree.id) initrd = resource.recipe.distro_tree.image_by_type(ImageType.initrd, KernelType.by_name(u'default')) if not initrd: raise BadRequest400('Initrd image not found for distro tree %s' % distro_tree.id) kernel_url = urlparse.urljoin(distro_tree_url, kernel.path) initrd_url = urlparse.urljoin(distro_tree_url, initrd.path) kernel_options = resource.kernel_options + ' netboot_method=ipxe' return ('#!ipxe\nkernel %s %s\ninitrd %s\nboot\n' % (kernel_url, kernel_options, initrd_url), 200, [('Content-Type', 'text/plain')])
def mark_recipe_waiting(recipe, start_time=None, system=None, lab_controller=None, virt=False, instance_id=None, **kwargs): if start_time is None: start_time = datetime.datetime.utcnow() recipe.process() recipe.queue() recipe.schedule() if not recipe.resource: if isinstance(recipe, MachineRecipe): if virt: if not lab_controller: lab_controller = create_labcontroller(fqdn=u'dummylab.example.invalid') if not instance_id: instance_id = uuid.uuid4() recipe.resource = VirtResource(instance_id, lab_controller) recipe.recipeset.lab_controller = lab_controller else: if not system: if not lab_controller: lab_controller = create_labcontroller(fqdn=u'dummylab.example.invalid') system = create_system(arch=recipe.arch, lab_controller=lab_controller) recipe.resource = SystemResource(system=system) recipe.resource.allocate() recipe.resource.reservation.start_time = start_time recipe.recipeset.lab_controller = system.lab_controller elif isinstance(recipe, GuestRecipe): recipe.resource = GuestResource() recipe.resource.allocate() recipe.start_time = start_time recipe.watchdog = Watchdog() recipe.waiting() recipe.resource.rebooted = start_time recipe.recipeset.job.update_status() log.debug('Marked %s as waiting with system %s', recipe.t_id, recipe.resource.fqdn)
def provision_virt_recipe(recipe_id): 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. available_flavors = sorted(available_flavors, key=lambda flavor: flavor.ram) 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 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 instance_id = manager.create_vm(vm_name, flavor) try: recipe.createRepo() recipe.systems = [] recipe.watchdog = Watchdog() recipe.resource = VirtResource(instance_id, manager.lab_controller) 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(instance_id) except Exception: log.exception( 'Failed to clean up instance %s ' 'during provision_virt_recipe, leaked!', instance_id) # suppress this exception so the original one is not masked raise exc_type, exc_value, exc_tb
def mark_recipe_scheduled(recipe, start_time=None, system=None, fqdn=None, mac_address=None, lab_controller=None, virt=False, instance_id=None, **kwargs): recipe.process() recipe.queue() recipe.schedule() if not recipe.resource: if isinstance(recipe, MachineRecipe): if virt: if not lab_controller: lab_controller = create_labcontroller( fqdn=u'dummylab.example.invalid') if not instance_id: instance_id = uuid.uuid4() recipe.resource = VirtResource(instance_id, lab_controller) recipe.recipeset.lab_controller = lab_controller else: if not system: if not lab_controller: lab_controller = create_labcontroller( fqdn=u'dummylab.example.invalid') system = create_system(arch=recipe.arch.arch, fqdn=fqdn, lab_controller=lab_controller) recipe.resource = SystemResource(system=system) recipe.resource.allocate() recipe.resource.reservation.start_time = start_time or datetime.datetime.utcnow( ) recipe.recipeset.lab_controller = system.lab_controller elif isinstance(recipe, GuestRecipe): recipe.resource = GuestResource() recipe.resource.allocate() if mac_address is not None: recipe.resource.mac_address = netaddr.EUI( mac_address, dialect=mac_unix_padded_dialect) if not recipe.distro_tree.url_in_lab(recipe.recipeset.lab_controller): add_distro_tree_to_lab(recipe.distro_tree, recipe.recipeset.lab_controller) recipe.watchdog = Watchdog() log.debug('Marked %s as scheduled with system %s', recipe.t_id, recipe.resource.fqdn)
def _create_vm_with_fixed_network(self, system_name, flavor, image_id): """ Creates a VM (Virtual Machine) with a fixed IP address (that is, doesn't assign a floating IP addres). """ network = FixedNetwork(self.neutronclient) instance = self.novaclient.servers.create(system_name, image_id, flavor, nics=[{ 'net-id': network.network_id }]) log.info('Created %r', instance) try: self._wait_for_build(instance) ipv4_address = self.get_vm_ipv4_address(instance, network.name) network.set_ip_address(ipv4_address) # would be nice if nova let us build an instance without starting it instance.stop() self._wait_for_stop(instance) return VirtResource(instance_id=uuid.UUID(instance.id), network_id=uuid.UUID(network.network_id), subnet_id=uuid.UUID(network.subnet_id), router_id=uuid.UUID(network.router_id), floating_ip=ipv4_address, lab_controller=self.lab_controller) except: exc_type, exc_value, exc_tb = sys.exc_info() try: instance.delete() except Exception: # pylint: disable=broad-except log.exception( 'Failed to clean up %r during create_vm, leaked!', instance) # suppress instance.delete exception so the original one is not masked raise exc_type, exc_value, exc_tb
def _create_vm_with_floating_ip(self, name, flavor, image_id): """ Creates a VM (Virtual Machine) with a custom network and a floating IP address. """ with VirtNetwork(self.neutronclient, name) as net: instance = self.novaclient.servers.create(name, image_id, flavor, nics=[{ 'net-id': net.network_id }]) log.info('Created %r', instance) try: self._wait_for_build(instance) self._assign_floating_ip(net.floating_ip.get('id'), instance) # would be nice if nova let us build an instance without starting it instance.stop() self._wait_for_stop(instance) return VirtResource(uuid.UUID(instance.id), uuid.UUID(net.network_id), uuid.UUID(net.subnet_id), uuid.UUID(net.router_id), net.floating_ip.get('floating_ip_address'), self.lab_controller) except: exc_type, exc_value, exc_tb = sys.exc_info() try: instance.delete() except Exception: log.exception( 'Failed to clean up %r during create_vm, leaked!', instance) # suppress instance.delete exception so the original one is not masked raise exc_type, exc_value, exc_tb