def GET(self, request_id): try: return data.request_config(int(request_id)) except ValueError: raise web.badrequest() except data.NotFound: raise web.notfound()
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
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
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
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)
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)
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
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)
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)
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)