示例#1
0
 def GET(self, request_id):
     try:
         return data.request_config(int(request_id))
     except ValueError:
         raise web.badrequest()
     except data.NotFound:
         raise web.notfound()
示例#2
0
    def contact_lifeguard(self):
        device_request_data = {}
        request_config = data.request_config(self.machine.request_id)

        # Determine if we are imaging or just rebooting.
        # We need to pass boot_config as a JSON string, but verify that it's
        # a non-null object.
        if json.loads(request_config['boot_config']):
            event = 'please_pxe_boot'
            device_request_data['boot_config'] = request_config['boot_config']
            # FIXME: differentiate between b2g builds and other (future) image
            # types.
            device_request_data['pxe_config'] = config.get('mozpool',
                                                           'b2g_pxe_config')
        else:
            event = 'please_power_cycle'

        device_url = 'http://%s/api/device/%s/event/%s/' % (
            data.get_server_for_device(request_config['assigned_device']),
            request_config['assigned_device'], event)

        # FIXME: make this asynchronous so slow/missing servers don't halt
        # the state machine.
        try:
            urllib.urlopen(device_url, json.dumps(device_request_data))
        except IOError:
            logs.request_logs.add(self.machine.request_id,
                                  "could not contact lifeguard server at %s" %
                                  device_url)
            return False
        return True
示例#3
0
    def POST(self, device_name):
        args, body = templeton.handlers.get_request_parms()
        try:
            assignee = body['assignee']
            duration = int(body['duration'])
            image_name = body['image']
            environment = body.get('environment', 'any')
        except (KeyError, ValueError):
            raise web.badrequest()

        images = data.dump_images(image_name)
        if not images:
            raise web.badrequest()

        boot_config = {}
        for k in images[0]['boot_config_keys']:
            try:
                boot_config[k] = body[k]
            except KeyError:
                raise web.badrequest()

        request_id = data.create_request(device_name, environment, assignee,
                                         duration, images[0]['id'], boot_config)
        mozpool.mozpool.driver.handle_event(request_id, 'find_device', None)
        response_data = {'request': data.request_config(request_id)}
        if data.request_status(request_id)['state'] == 'closed':
            raise ConflictJSON(response_data)
        return response_data
示例#4
0
    def contact_lifeguard(self):
        device_request_data = {}
        request_config = data.request_config(self.machine.request_id)

        # Determine if we are imaging or just rebooting.
        # We need to pass boot_config as a JSON string, but verify that it's
        # a non-null object.
        if json.loads(request_config['boot_config']):
            event = 'please_pxe_boot'
            device_request_data['boot_config'] = request_config['boot_config']
            # FIXME: differentiate between b2g builds and other (future) image
            # types.
            device_request_data['pxe_config'] = config.get(
                'mozpool', 'b2g_pxe_config')
        else:
            event = 'please_power_cycle'

        device_url = 'http://%s/api/device/%s/event/%s/' % (
            data.get_server_for_device(request_config['assigned_device']),
            request_config['assigned_device'], event)

        # FIXME: make this asynchronous so slow/missing servers don't halt
        # the state machine.
        try:
            urllib.urlopen(device_url, json.dumps(device_request_data))
        except IOError:
            logs.request_logs.add(
                self.machine.request_id,
                "could not contact lifeguard server at %s" % device_url)
            return False
        return True
示例#5
0
 def GET(self, request_id):
     try:
         return data.request_config(int(request_id))
     except ValueError:
         raise web.badrequest()
     except data.NotFound:
         raise web.notfound()
示例#6
0
 def on_timeout(self):
     # FIXME: go back to earlier state if request failed
     counter = self.machine.increment_counter(self.state_name)
     request_config = data.request_config(self.machine.request_id)
     device_name = request_config['assigned_device']
     device_state = data.device_status(device_name)['state']
     if device_state == 'ready':
         self.machine.goto_state(ready)
     elif counter > self.PERMANENT_FAILURE_COUNT:
         self.machine.goto_state(device_not_found)
     else:
         self.machine.goto_state(pending)
示例#7
0
 def on_timeout(self):
     # FIXME: go back to earlier state if request failed
     counter = self.machine.increment_counter(self.state_name)
     request_config = data.request_config(self.machine.request_id)
     device_name = request_config['assigned_device']
     print 'device_name is %s' % device_name
     device_state = data.device_status(device_name)['state']
     if device_state == 'ready':
         self.machine.goto_state(ready)
     elif counter > self.PERMANENT_FAILURE_COUNT:
         self.machine.goto_state(device_not_found)
     else:
         self.machine.goto_state(pending)
示例#8
0
 def POST(self, device_name):
     args, body = templeton.handlers.get_request_parms()
     boot_config = body.get('boot_config', {})
     try:
         assignee = body['assignee']
         duration = int(body['duration'])
     except (KeyError, ValueError):
         raise web.badrequest()
     request_id = data.create_request(device_name, assignee, duration,
                                      boot_config)
     mozpool.mozpool.driver.handle_event(request_id, 'find_device', None)
     response_data = {'request': data.request_config(request_id)}
     if data.request_status(request_id)['state'] == 'closed':
         raise ConflictJSON(response_data)
     return response_data
示例#9
0
 def POST(self, device_name):
     args, body = templeton.handlers.get_request_parms()
     boot_config = body.get('boot_config', {})
     try:
         assignee = body['assignee']
         duration = int(body['duration'])
     except (KeyError, ValueError):
         raise web.badrequest()
     request_id = data.create_request(device_name, assignee, duration,
                                      boot_config)
     mozpool.mozpool.driver.handle_event(request_id, 'find_device', None)
     response_data = {'request': data.request_config(request_id)}
     if data.request_status(request_id)['state'] == 'closed':
         raise ConflictJSON(response_data)
     return response_data
示例#10
0
    def on_entry(self):
        request_config = data.request_config(self.machine.request_id)
        device_name = request_config['assigned_device']
        device_state = data.device_status(device_name)['state']
        if device_state != 'free':
            self.logger.error('Assigned device %s is in unexpected state %s '
                              'when about to contact lifeguard.' %
                              (device_name, device_state))
            self.machine.goto_state(device_busy)
            return

        if self.contact_lifeguard(request_config):
            self.machine.goto_state(pending)
            return
        counters = self.machine.read_counters()
        if counters.get(self.state_name, 0) > self.PERMANENT_FAILURE_COUNT:
            self.machine.goto_state(device_not_found)
示例#11
0
    def on_entry(self):
        request_config = data.request_config(self.machine.request_id)
        device_name = request_config['assigned_device']
        device_state = data.device_status(device_name)['state']
        if device_state != 'free':
            logs.request_logs.add(
                self.machine.request_id,
                'assigned device %s is in unexpected state %s when about '
                'to contact lifeguard.' % (device_name, device_state))
            self.machine.goto_state(device_busy)
            return

        if self.contact_lifeguard():
            self.machine.goto_state(pending)
            return
        counters = self.machine.read_counters()
        if counters.get(self.state_name, 0) > self.PERMANENT_FAILURE_COUNT:
            self.machine.goto_state(device_not_found)
示例#12
0
    def find_device(self):
        self.logger.info('Finding device.')
        device_name = None
        count = self.machine.increment_counter(self.state_name)
        request = data.request_config(self.machine.request_id)
        image_is_reusable = data.image_is_reusable(request['image'])

        free_devices = data.get_free_devices(
                environment=request['environment'],
                device_name=request['requested_device'])

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

            # pick a device at random from the returned list
            device_name = random.choice(free_devices)['name']
            self.logger.info('Assigning device %s.' % device_name)
            if data.reserve_device(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(device_not_found)
            else:
                if count >= self.MAX_SPECIFIC_REQUESTS:
                    self.logger.warn('Requested device %s is busy.' %
                                     device_name)
                    self.machine.goto_state(device_busy)