示例#1
0
 def accepts(cls, device, parameters):
     if 'method' not in parameters:
         raise ConfigurationError("method not specified in boot parameters")
     if parameters['method'] != 'new_connection':
         return False, 'new_connection not in method'
     if 'actions' not in device:
         raise ConfigurationError("Invalid device configuration")
     if 'boot' not in device['actions']:
         return False, 'boot not in device actions'
     if 'methods' not in device['actions']['boot']:
         raise ConfigurationError("Device misconfiguration")
     if 'method' not in parameters:
         return False, 'no boot method'
     return True, 'accepted'
示例#2
0
 def get_constant(self, const, prefix=None, missing_ok=False):
     if 'constants' not in self:
         raise ConfigurationError("constants section not present in the device config.")
     if prefix:
         if not self['constants'].get(prefix, {}).get(const, {}):
             if missing_ok:
                 return None
             raise ConfigurationError("Constant %s,%s does not exist in the device config 'constants' section." % (prefix, const))
         else:
             return self['constants'][prefix][const]
     if const not in self['constants']:
         if missing_ok:
             return None
         raise ConfigurationError("Constant %s does not exist in the device config 'constants' section." % const)
     return self['constants'][const]
示例#3
0
 def read_settings(self, filename):
     """
     NodeDispatchers need to use the same port and blocksize as the Coordinator,
     so read the same conffile.
     The protocol header is hard-coded into the server & here.
     """
     settings = {
         "port": 3079,
         "blocksize": 4 * 1024,
         "poll_delay": 1,
         "coordinator_hostname": "localhost"
     }
     self.logger = logging.getLogger('dispatcher')
     json_default = {}
     with open(filename) as stream:
         jobdata = stream.read()
         try:
             json_default = json.loads(jobdata)
         except ValueError as exc:
             raise ConfigurationError("Invalid JSON settings for %s: %s" % (self.name, exc))
     if "port" in json_default:
         settings['port'] = json_default['port']
     if "blocksize" in json_default:
         settings['blocksize'] = json_default["blocksize"]
     if "poll_delay" in json_default:
         settings['poll_delay'] = json_default['poll_delay']
     if "coordinator_hostname" in json_default:
         settings['coordinator_hostname'] = json_default['coordinator_hostname']
     return settings
示例#4
0
 def boot_check(cls, device, parameters):
     if not device:
         raise JobError('job "device" was None')
     if 'method' not in parameters:
         raise ConfigurationError("method not specified in boot parameters")
     if 'actions' not in device:
         raise ConfigurationError(
             'Invalid device configuration, no "actions" in device configuration'
         )
     if 'boot' not in device['actions']:
         raise ConfigurationError(
             '"boot" is not in the device configuration actions')
     if 'methods' not in device['actions']['boot']:
         raise ConfigurationError(
             'Device misconfiguration, no "methods" in device configuration boot action'
         )
示例#5
0
 def deploy_check(cls, device, parameters):
     if not device:
         raise JobError('job "device" was None')
     if 'actions' not in device:
         raise ConfigurationError(
             'Invalid device configuration, no "actions" in device configuration'
         )
     if 'to' not in parameters:
         raise ConfigurationError('"to" not specified in deploy parameters')
     if 'deploy' not in device['actions']:
         raise ConfigurationError(
             '"deploy" is not in the device configuration actions')
     if 'methods' not in device['actions']['deploy']:
         raise ConfigurationError(
             'Device misconfiguration, no "methods" in device configuration deploy actions'
         )
示例#6
0
    def __init__(self, target):
        super(NewDevice, self).__init__({})
        # Parse the yaml configuration
        try:
            if isinstance(target, str):
                with open(target) as f_in:
                    data = f_in.read()
            else:
                data = target.read()
            data = yaml.load(data)
            if data is None:
                raise ConfigurationError("Missing device configuration")
            self.update(data)
        except yaml.parser.ParserError:
            raise ConfigurationError("%s could not be parsed" % target)

        self.setdefault('power_state', 'off')  # assume power is off at start of job
示例#7
0
 def accepts(cls, device, parameters):
     if 'method' not in parameters:
         raise ConfigurationError("method not specified in boot parameters")
     if parameters["method"] not in ["grub", "grub-efi"]:
         return False, '"method" was not "grub" or "grub-efi"'
     if 'actions' not in device:
         raise ConfigurationError("Invalid device configuration")
     if 'boot' not in device['actions']:
         return False, '"boot" was not in the device configuration actions'
     if 'methods' not in device['actions']['boot']:
         raise ConfigurationError("Device misconfiguration")
     params = device['actions']['boot']['methods']
     if 'grub' in params and 'sequence' in params['grub']:
         return False, '"sequence" was in "grub" parameters'
     if 'grub' in params or 'grub-efi' in params:
         return True, 'accepted'
     else:
         return False, '"grub" or "grub-efi" was not in the device configuration boot methods'
示例#8
0
 def accepts(cls, device, parameters):
     if parameters['method'] != 'u-boot':
         return False, '"method" was not "u-boot"'
     if 'commands' not in parameters:
         raise ConfigurationError(
             "commands not specified in boot parameters")
     if 'u-boot' in device['actions']['boot']['methods']:
         return True, 'accepted'
     else:
         return False, '"u-boot" was not in the device configuration boot methods'
示例#9
0
 def poll(self, message, timeout=None):
     """
     Blocking, synchronous polling of the Coordinator on the configured port.
     Single send operations greater than 0xFFFF are rejected to prevent truncation.
     :param msg_str: The message to send to the Coordinator, as a JSON string.
     :return: a JSON string of the response to the poll
     """
     if not timeout:
         timeout = self.poll_timeout.duration
     if isinstance(timeout, float):
         timeout = int(timeout)
     elif not isinstance(timeout, int):
         raise ConfigurationError("Invalid timeout duration type: %s %s" % (type(timeout), timeout))
     msg_len = len(message)
     if msg_len > 0xFFFE:
         raise JobError("Message was too long to send!")
     c_iter = 0
     response = None
     delay = self.settings['poll_delay']
     self.logger.debug("Connecting to LAVA Coordinator on %s:%s timeout=%d seconds.",
                       self.settings['coordinator_hostname'],
                       self.settings['port'], timeout)
     while True:
         c_iter += self.settings['poll_delay']
         if self._connect(delay):
             delay = self.settings['poll_delay']
         else:
             delay += 2
             continue
         if not c_iter % int(10 * self.settings['poll_delay']):
             self.logger.debug("sending message: %s waited %s of %s seconds",
                               json.loads(message)['request'], c_iter,
                               timeout)
         # blocking synchronous call
         if not self._send_message(message):
             continue
         self.sock.shutdown(socket.SHUT_WR)
         response = self._recv_message()
         self.sock.close()
         try:
             json_data = json.loads(response)
         except ValueError:
             self.logger.debug("response starting '%s' was not JSON", response[:42])
             self.finalise_protocol()
             break
         if json_data['response'] != 'wait':
             break
         else:
             time.sleep(delay)
         # apply the default timeout to each poll operation.
         if c_iter > timeout:
             self.finalise_protocol()
             raise MultinodeProtocolTimeoutError(
                 "protocol %s timed out" % self.name)
     return response
示例#10
0
    def validate(self):
        super(CommandAction, self).validate()
        cmd_name = self.parameters['name']
        try:
            user_commands = self.job.device['commands']['users']
        except KeyError:
            raise ConfigurationError(
                "Unable to get device.commands.users dictionary")

        try:
            self.cmd = user_commands[cmd_name]
            if not isinstance(self.cmd['do'], str) or \
               not isinstance(self.cmd.get('undo', ""), str):
                raise ConfigurationError("User command \"%s\" is invalid: "
                                         "'do' and 'undo' should be strings" %
                                         cmd_name)
            return True
        except KeyError:
            self.errors = "Unknown user command '%s'" % cmd_name
            return False
示例#11
0
 def validate(self):
     super(IsoRebootAction, self).validate()
     if 'prompts' not in self.parameters:
         self.errors = "Unable to identify boot prompts from job definition."
     try:
         boot = self.job.device['actions']['boot']['methods']['qemu']
         qemu_binary = which(boot['parameters']['command'])
         self.sub_command = [qemu_binary]
         self.sub_command.extend(boot['parameters'].get('options', []))
     except AttributeError as exc:
         raise ConfigurationError(exc)
     except (KeyError, TypeError):
         self.errors = "Invalid parameters for %s" % self.name
示例#12
0
 def validate(self):
     super(FlashDFUAction, self).validate()
     try:
         boot = self.job.device['actions']['boot']['methods']['dfu']
         dfu_binary = which(boot['parameters']['command'])
         self.base_command = [dfu_binary]
         self.base_command.extend(boot['parameters'].get('options', []))
         if self.job.device['board_id'] == '0000000000':
             self.errors = "board_id unset"
         if self.job.device['usb_vendor_id'] == '0000':
             self.errors = 'usb_vendor_id unset'
         if self.job.device['usb_product_id'] == '0000':
             self.errors = 'usb_product_id unset'
         self.usb_vendor_id = self.job.device['usb_vendor_id']
         self.usb_product_id = self.job.device['usb_product_id']
         self.board_id = self.job.device['board_id']
         self.base_command.extend(['--serial', self.board_id])
         self.base_command.extend([
             '--device',
             '%s:%s' % (self.usb_vendor_id, self.usb_product_id)
         ])
     except AttributeError as exc:
         raise ConfigurationError(exc)
     except (KeyError, TypeError):
         self.errors = "Invalid parameters for %s" % self.name
     substitutions = {}
     namespace = self.parameters['namespace']
     for action in self.data[namespace]['download-action'].keys():
         dfu_full_command = []
         image_arg = self.data[namespace]['download-action'][action].get(
             'image_arg', None)
         action_arg = self.data[namespace]['download-action'][action].get(
             'file', None)
         if not image_arg or not action_arg:
             self.errors = "Missing image_arg for %s. " % action
             continue
         if not isinstance(image_arg, str):
             self.errors = "image_arg is not a string (try quoting it)"
             continue
         substitutions["{%s}" % action] = action_arg
         dfu_full_command.extend(self.base_command)
         dfu_full_command.extend(substitute([image_arg], substitutions))
         self.exec_list.append(dfu_full_command)
     if len(self.exec_list) < 1:
         self.errors = "No DFU command to execute"
示例#13
0
 def run(self, connection, max_end_time, args=None):
     connection = super(OverlayUnpack, self).run(connection, max_end_time, args)
     if not connection:
         raise LAVABug("Cannot transfer overlay, no connection available.")
     ip_addr = dispatcher_ip(self.job.parameters['dispatcher'])
     overlay_full_path = self.get_namespace_data(action='compress-overlay', label='output', key='file')
     if not overlay_full_path:
         raise JobError("No overlay file identified for the transfer.")
     if not overlay_full_path.startswith(DISPATCHER_DOWNLOAD_DIR):
         raise ConfigurationError("overlay should already be in DISPATCHER_DOWNLOAD_DIR")
     overlay_path = overlay_full_path[len(DISPATCHER_DOWNLOAD_DIR) + 1:]
     overlay = os.path.basename(overlay_path)
     dwnld = self.parameters['transfer_overlay']['download_command']
     dwnld += " http://%s/tmp/%s" % (ip_addr, overlay_path)
     unpack = self.parameters['transfer_overlay']['unpack_command']
     unpack += ' ' + overlay
     connection.sendline("rm %s; %s && %s" % (overlay, dwnld, unpack))
     return connection