def on_entry(self):
        req = self.db.requests.get_info(self.machine.request_id)
        device_name = req['assigned_device']
        device_state = self.db.devices.get_machine_state(device_name)
        if device_state != 'ready':
            self.logger.error('Assigned device %s is in unexpected state %s '
                              'when about to contact lifeguard.' %
                              (device_name, device_state))
            self.machine.goto_state(finding_device)
            # note that there's still a small chance of a race here between
            # mozpool and lifeguard: lifeguard begins self-testing the device
            # after this check and before it receives the event below; the
            # device eventually returns to the 'ready' state, but has not sent
            # the request.  The timeout for 'pending' will catch this rare
            # situation.
            return

        # If the requested image is reusable and we got a device with that
        # image and the requested bootconfig, just power cycle it.
        # Otherwise, image it.  Note that there will be a failure if the
        # image is not installed and the device is not imageable.
        event = ''
        device_request_data = {}
        assigned_device_name = req['assigned_device']

        if self.db.images.is_reusable(req['image']):
            dev = self.db.devices.get_image(req['assigned_device'])
            if (dev['image'] == req['image'] and util.from_json(
                    dev['boot_config']) == util.from_json(req['boot_config'])):
                event = 'please_power_cycle'

        if not event:
            # Use the device's hardware type and requested image to find the
            # pxe config, if any.
            event = 'please_image'
            device_request_data['boot_config'] = req['boot_config']
            device_request_data['image'] = req['image']

        # try to ask lifeguard to start imaging or power cycling
        device_url = 'http://%s/api/device/%s/event/%s/' % (
            self.db.devices.get_imaging_server(assigned_device_name),
            assigned_device_name, event)

        def posted(result):
            if result.status_code != 200:
                self.logger.warn("got %d from Lifeguard" % result.status_code)
                return
            mozpool.driver.handle_event(self.machine.request_id,
                                        'lifeguard_contacted', {})

        async .requests.post.start(posted,
                                   device_url,
                                   data=json.dumps(device_request_data))
예제 #2
0
    def on_entry(self):
        req = self.db.requests.get_info(self.machine.request_id)
        device_name = req['assigned_device']
        device_state = self.db.devices.get_machine_state(device_name)
        if device_state != 'ready':
            self.logger.error('Assigned device %s is in unexpected state %s '
                              'when about to contact lifeguard.' %
                              (device_name, device_state))
            self.machine.goto_state(finding_device)
            # note that there's still a small chance of a race here between
            # mozpool and lifeguard: lifeguard begins self-testing the device
            # after this check and before it receives the event below; the
            # device eventually returns to the 'ready' state, but has not sent
            # the request.  The timeout for 'pending' will catch this rare
            # situation.
            return

        # If the requested image is reusable and we got a device with that
        # image and the requested bootconfig, just power cycle it.
        # Otherwise, image it.  Note that there will be a failure if the
        # image is not installed and the device is not imageable.
        event = ''
        device_request_data = {}
        assigned_device_name = req['assigned_device']

        if self.db.images.is_reusable(req['image']):
            dev = self.db.devices.get_image(req['assigned_device'])
            if (dev['image'] == req['image'] and
                util.from_json(dev['boot_config']) ==
                util.from_json(req['boot_config'])):
                event = 'please_power_cycle'

        if not event:
            # Use the device's hardware type and requested image to find the
            # pxe config, if any.
            event = 'please_image'
            device_request_data['boot_config'] = req['boot_config']
            device_request_data['image'] = req['image']

        # try to ask lifeguard to start imaging or power cycling
        device_url = 'http://%s/api/device/%s/event/%s/' % (
            self.db.devices.get_imaging_server(assigned_device_name),
            assigned_device_name, event)
        def posted(result):
            if result.status_code != 200:
                self.logger.warn("got %d from Lifeguard" % result.status_code)
                return
            mozpool.driver.handle_event(self.machine.request_id, 'lifeguard_contacted', {})
        async.requests.post.start(posted, device_url,
                data=json.dumps(device_request_data))
    def find_device(self):
        self.logger.info('Finding device.')
        device_name = None
        count = self.machine.increment_counter(self.state_name)
        self.db.device_requests.clear(self.machine.request_id)
        request = self.db.requests.get_info(self.machine.request_id)
        image_is_reusable = self.db.images.is_reusable(request['image'])

        avail_devices = self.db.devices.list_available(
            environment=request['environment'],
            device_name=request['requested_device'])

        if avail_devices:
            if image_is_reusable:
                devices_with_image = [
                    x for x in avail_devices if x['image'] == request['image']
                    and util.from_json(x['boot_config']) == util.from_json(
                        request['boot_config'])
                ]
                if devices_with_image:
                    avail_devices = devices_with_image

            # pick a device at random from the returned list
            device_name = random.choice(avail_devices)['name']
            self.logger.info('Assigning device %s.' % device_name)
            if self.db.device_requests.add(self.machine.request_id,
                                           device_name):
                self.logger.info('Request succeeded.')
                self.machine.goto_state(contact_lifeguard)
        else:
            self.logger.warn('Request failed!')
            if request['requested_device'] == 'any':
                if count >= self.MAX_ANY_REQUESTS:
                    self.logger.warn('Hit maximum number of attempts to find '
                                     'a free device; giving up.')
                    self.machine.goto_state(failed_device_not_found)
            else:
                if count >= self.MAX_SPECIFIC_REQUESTS:
                    self.logger.warn('Requested device %s is busy.' %
                                     request['requested_device'])
                    self.machine.goto_state(failed_device_busy)
                    return
                # check the device status - if it's failed, then short-circuit
                # to failed_bad_device
                state = self.db.devices.get_machine_state(
                    request['requested_device'])
                if state.startswith('failed_'):
                    self.machine.goto_state(failed_bad_device)
예제 #4
0
    def find_device(self):
        self.logger.info('Finding device.')
        device_name = None
        count = self.machine.increment_counter(self.state_name)
        self.db.device_requests.clear(self.machine.request_id)
        request = self.db.requests.get_info(self.machine.request_id)
        image_is_reusable = self.db.images.is_reusable(request['image'])

        avail_devices = self.db.devices.list_available(
                environment=request['environment'],
                device_name=request['requested_device'])

        if avail_devices:
            if image_is_reusable:
                devices_with_image = [x for x in avail_devices
                                      if x['image'] == request['image'] and
                                         util.from_json(x['boot_config']) ==
                                         util.from_json(request['boot_config'])]
                if devices_with_image:
                    avail_devices = devices_with_image

            # pick a device at random from the returned list
            device_name = random.choice(avail_devices)['name']
            self.logger.info('Assigning device %s.' % device_name)
            if self.db.device_requests.add(self.machine.request_id,
                                                device_name):
                self.logger.info('Request succeeded.')
                self.machine.goto_state(contacting_lifeguard)
        else:
            self.logger.warn('Request failed!')
            if request['requested_device'] == 'any':
                if count >= self.MAX_ANY_REQUESTS:
                    self.logger.warn('Hit maximum number of attempts to find '
                                     'a free device; giving up.')
                    self.machine.goto_state(failed_device_not_found)
            else:
                if count >= self.MAX_SPECIFIC_REQUESTS:
                    self.logger.warn('Requested device %s is busy.' %
                                     request['requested_device'])
                    self.machine.goto_state(failed_device_busy)
                    return
                # check the device status - if it's failed, then short-circuit
                # to failed_bad_device
                state = self.db.devices.get_machine_state(request['requested_device'])
                if state.startswith('failed_'):
                    self.machine.goto_state(failed_bad_device)
예제 #5
0
 def test_from_json(self):
     self.assertEqual(util.from_json('{"a": "b"}'), {'a': 'b'})
     self.assertEqual(util.from_json('{"a"'), {})