示例#1
0
  def Start(self):
    if self._auto:
      logging.debug('Starting automatic device deployment.')
      node_name = boot_data.GetNodeName(self._output_dir)
      self._host = self.__Discover(node_name)
      if self._host and self._WaitUntilReady(retries=0):
        if not self._SDKHashMatches():
          logging.info('SDK hash does not match, rebooting.')
          self.RunCommand(['dm', 'reboot'])
          self._started = False
        else:
          logging.info('Connected to an already booted device.')
          self._new_instance = False
          return

      logging.info('Netbooting Fuchsia. ' +
                   'Please ensure that your device is in bootloader mode.')
      bootserver_path = os.path.join(SDK_ROOT, 'tools', 'bootserver')
      bootserver_command = [
          bootserver_path,
          '-1',
          '--efi',
          EnsurePathExists(boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                                   'local.esp.blk')),
          '--fvm',
          EnsurePathExists(boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                                   'fvm.sparse.blk')),
          '--fvm',
          EnsurePathExists(
              boot_data.ConfigureDataFVM(self._output_dir,
                                         boot_data.FVM_TYPE_SPARSE)),
          EnsurePathExists(boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                                   'fuchsia.zbi')),
          '--'] + boot_data.GetKernelArgs(self._output_dir)
      logging.debug(' '.join(bootserver_command))
      subprocess.check_call(bootserver_command)

      # Start loglistener to save system logs.
      if self._system_log_file:
        loglistener_path = os.path.join(SDK_ROOT, 'tools', 'loglistener')
        self._loglistener = subprocess.Popen(
            [loglistener_path, node_name],
            stdout=self._system_log_file,
            stderr=subprocess.STDOUT, stdin=open(os.devnull))

      logging.debug('Waiting for device to join network.')
      for retry in xrange(CONNECT_RETRY_COUNT):
        self._host = self.__Discover(node_name)
        if self._host:
          break
        time.sleep(CONNECT_RETRY_WAIT_SECS)
      if not self._host:
        raise Exception('Couldn\'t connect to device.')

      logging.debug('host=%s, port=%d' % (self._host, self._port))

    self._WaitUntilReady();

    # Update the target's hash to match the current tree's.
    self.PutFile(os.path.join(SDK_ROOT, '.hash'), TARGET_HASH_FILE_PATH)
示例#2
0
  def Start(self):
    if self._auto:
      logging.debug('Starting automatic device deployment.')
      node_name = boot_data.GetNodeName(self._output_dir)
      self._host = self.__Discover(node_name)
      if self._host and self._WaitUntilReady(retries=0):
        logging.info('Connected to an already booted device.')
        self._new_instance = False
        return

      logging.info('Netbooting Fuchsia. ' +
                   'Please ensure that your device is in bootloader mode.')
      bootserver_path = os.path.join(SDK_ROOT, 'tools', 'bootserver')
      bootserver_command = [
          bootserver_path,
          '-1',
          '--efi',
          EnsurePathExists(boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                                   'local.esp.blk')),
          '--fvm',
          EnsurePathExists(boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                                   'fvm.sparse.blk')),
          '--fvm',
          EnsurePathExists(
              boot_data.ConfigureDataFVM(self._output_dir,
                                         boot_data.FVM_TYPE_SPARSE)),
          EnsurePathExists(boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                                   'zircon.bin')),
          EnsurePathExists(boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                                   'bootdata-blob.bin')),
          '--'] + boot_data.GetKernelArgs(self._output_dir)
      logging.debug(' '.join(bootserver_command))
      subprocess.check_call(bootserver_command)

      # Setup loglistener. Logs will be redirected to stdout if the device takes
      # longer than expected to boot.
      loglistener_path = os.path.join(SDK_ROOT, 'tools', 'loglistener')
      loglistener = subprocess.Popen([loglistener_path, node_name],
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.STDOUT,
                                     stdin=open(os.devnull))
      self._SetSystemLogsReader(
          log_reader.LogReader(loglistener, loglistener.stdout))

      logging.debug('Waiting for device to join network.')
      for retry in xrange(CONNECT_RETRY_COUNT):
        if retry == CONNECT_RETRY_COUNT_BEFORE_LOGGING:
          self._system_logs_reader.RedirectTo(sys.stdout);
        self._host = self.__Discover(node_name)
        if self._host:
          break
        time.sleep(CONNECT_RETRY_WAIT_SECS)
      if not self._host:
        raise Exception('Couldn\'t connect to device.')

      logging.debug('host=%s, port=%d' % (self._host, self._port))

    self._WaitUntilReady();
示例#3
0
    def Start(self):
        if self._auto:
            logging.debug('Starting automatic device deployment.')
            node_name = boot_data.GetNodeName(self._output_dir)
            self._host = self.__Discover(node_name)
            if self._host and self._WaitUntilReady(retries=0):
                logging.info('Connected to an already booted device.')
                self._new_instance = False
                return

            logging.info(
                'Netbooting Fuchsia. ' +
                'Please ensure that your device is in bootloader mode.')
            bootserver_path = os.path.join(common.SDK_ROOT, 'tools',
                                           'bootserver')
            data_fvm_path = boot_data.ConfigureDataFVM(
                self._output_dir, boot_data.FVM_TYPE_SPARSE)
            bootserver_command = [bootserver_path,
                                  '-1',
                                  '--efi',
                                  boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                                          'local.esp.blk'),
                                  '--fvm',
                                  boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                                          'fvm.sparse.blk'),
                                  '--fvm',
                                  data_fvm_path,
                                  boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                                          'zircon.bin'),
                                  boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                                          'bootdata-blob.bin'),
                                  '--'] + \
                                  boot_data.GetKernelArgs(self._output_dir)
            logging.debug(' '.join(bootserver_command))
            subprocess.check_call(bootserver_command)

            logging.debug('Waiting for device to join network.')
            for _ in xrange(CONNECT_RETRY_COUNT):
                self._host = self.__Discover(node_name)
                if self._host:
                    break
                time.sleep(CONNECT_RETRY_WAIT_SECS)
            if not self._host:
                raise Exception('Couldn\'t connect to device.')

            logging.debug('host=%s, port=%d' % (self._host, self._port))

        self._WaitUntilReady()
示例#4
0
    def Start(self):
        qemu_path = os.path.join(common.SDK_ROOT, 'qemu', 'bin',
                                 'qemu-system-' + self._GetTargetSdkArch())
        kernel_args = boot_data.GetKernelArgs(self._output_dir)

        qemu_command = [
            qemu_path,
            '-m',
            str(self._ram_size_mb),
            '-nographic',
            '-kernel',
            boot_data.GetTargetFile(self._GetTargetSdkArch(), 'zircon.bin'),
            '-initrd',
            boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                    'bootdata-blob.bin'),
            '-smp',
            '4',

            # Attach the blobstore and data volumes. Use snapshot mode to discard
            # any changes.
            '-snapshot',
            '-drive',
            'file=%s,format=qcow2,if=none,id=data,snapshot=on' %
            os.path.join(self._output_dir, 'fvm.blk.qcow2'),
            '-drive',
            'file=%s,format=qcow2,if=none,id=blobstore,snapshot=on' %
            self._MakeQcowDisk(
                boot_data.ConfigureDataFVM(self._output_dir, False)),
            '-device',
            'virtio-blk-pci,drive=data',
            '-device',
            'virtio-blk-pci,drive=blobstore',

            # Use stdio for the guest OS only; don't attach the QEMU interactive
            # monitor.
            '-serial',
            'stdio',
            '-monitor',
            'none',

            # TERM=dumb tells the guest OS to not emit ANSI commands that trigger
            # noisy ANSI spew from the user's terminal emulator.
            '-append',
            'TERM=dumb ' + ' '.join(kernel_args)
        ]

        # Configure the machine & CPU to emulate, based on the target architecture.
        # Enable lightweight virtualization (KVM) if the host and guest OS run on
        # the same architecture.
        if self._target_cpu == 'arm64':
            qemu_command.extend([
                '-machine',
                'virt',
                '-cpu',
                'cortex-a53',
            ])
            netdev_type = 'virtio-net-pci'
            if platform.machine() == 'aarch64':
                qemu_command.append('-enable-kvm')
        else:
            qemu_command.extend([
                '-machine',
                'q35',
                '-cpu',
                'host,migratable=no',
            ])
            netdev_type = 'e1000'
            if platform.machine() == 'x86_64':
                qemu_command.append('-enable-kvm')

        # Configure virtual network. It is used in the tests to connect to
        # testserver running on the host.
        netdev_config = 'user,id=net0,net=%s,dhcpstart=%s,host=%s' % \
                (GUEST_NET, GUEST_IP_ADDRESS, HOST_IP_ADDRESS)

        self._host_ssh_port = _GetAvailableTcpPort()
        netdev_config += ",hostfwd=tcp::%s-:22" % self._host_ssh_port
        qemu_command.extend([
            '-netdev',
            netdev_config,
            '-device',
            '%s,netdev=net0,mac=%s' % (netdev_type, GUEST_MAC_ADDRESS),
        ])

        # We pass a separate stdin stream to qemu. Sharing stdin across processes
        # leads to flakiness due to the OS prematurely killing the stream and the
        # Python script panicking and aborting.
        # The precise root cause is still nebulous, but this fix works.
        # See crbug.com/741194.
        logging.debug('Launching QEMU.')
        logging.debug(' '.join(qemu_command))

        stdio_flags = {'stdin': open(os.devnull)}
        if logging.getLogger().getEffectiveLevel() != logging.DEBUG:
            # Output the Fuchsia debug log.
            stdio_flags['stdout'] = open(os.devnull)
            stdio_flags['stderr'] = open(os.devnull)

        self._qemu_process = subprocess.Popen(qemu_command, **stdio_flags)
        self._WaitUntilReady()
示例#5
0
    def Start(self):
        qemu_path = os.path.join(
            QEMU_ROOT, 'bin', 'qemu-system-' + self._GetTargetSdkLegacyArch())
        kernel_args = boot_data.GetKernelArgs(self._output_dir)

        # TERM=dumb tells the guest OS to not emit ANSI commands that trigger
        # noisy ANSI spew from the user's terminal emulator.
        kernel_args.append('TERM=dumb')

        # Enable logging to the serial port. This is a temporary fix to investigate
        # the root cause for https://crbug.com/869753 .
        kernel_args.append('kernel.serial=legacy')

        qemu_command = [
            qemu_path,
            '-m',
            str(self._ram_size_mb),
            '-nographic',
            '-kernel',
            EnsurePathExists(
                boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                        'zircon.bin')),
            '-initrd',
            EnsurePathExists(
                boot_data.GetTargetFile(self._GetTargetSdkArch(),
                                        'bootdata-blob.bin')),
            '-smp',
            '4',

            # Attach the blobstore and data volumes. Use snapshot mode to discard
            # any changes.
            '-snapshot',
            '-drive',
            'file=%s,format=qcow2,if=none,id=data,snapshot=on' %
            EnsurePathExists(os.path.join(self._output_dir, 'fvm.blk.qcow2')),
            '-drive',
            'file=%s,format=qcow2,if=none,id=blobstore,snapshot=on' %
            EnsurePathExists(
                boot_data.ConfigureDataFVM(self._output_dir,
                                           boot_data.FVM_TYPE_QCOW)),
            '-device',
            'virtio-blk-pci,drive=data',
            '-device',
            'virtio-blk-pci,drive=blobstore',

            # Use stdio for the guest OS only; don't attach the QEMU interactive
            # monitor.
            '-serial',
            'stdio',
            '-monitor',
            'none',
            '-append',
            ' '.join(kernel_args)
        ]

        # Configure the machine & CPU to emulate, based on the target architecture.
        # Enable lightweight virtualization (KVM) if the host and guest OS run on
        # the same architecture.
        if self._target_cpu == 'arm64':
            qemu_command.extend([
                '-machine',
                'virt',
                '-cpu',
                'cortex-a53',
            ])
            netdev_type = 'virtio-net-pci'
            if platform.machine() == 'aarch64':
                qemu_command.append('-enable-kvm')
        else:
            qemu_command.extend([
                '-machine',
                'q35',
                '-cpu',
                'host,migratable=no',
            ])
            netdev_type = 'e1000'
            if platform.machine() == 'x86_64':
                qemu_command.append('-enable-kvm')

        # Configure virtual network. It is used in the tests to connect to
        # testserver running on the host.
        netdev_config = 'user,id=net0,net=%s,dhcpstart=%s,host=%s' % \
                (GUEST_NET, GUEST_IP_ADDRESS, HOST_IP_ADDRESS)

        self._host_ssh_port = _GetAvailableTcpPort()
        netdev_config += ",hostfwd=tcp::%s-:22" % self._host_ssh_port
        qemu_command.extend([
            '-netdev',
            netdev_config,
            '-device',
            '%s,netdev=net0,mac=%s' % (netdev_type, GUEST_MAC_ADDRESS),
        ])

        # We pass a separate stdin stream to qemu. Sharing stdin across processes
        # leads to flakiness due to the OS prematurely killing the stream and the
        # Python script panicking and aborting.
        # The precise root cause is still nebulous, but this fix works.
        # See crbug.com/741194.
        logging.debug('Launching QEMU.')
        logging.debug(' '.join(qemu_command))

        # Zircon sends debug logs to serial port (see kernel.serial=legacy flag
        # above). Serial port is redirected to a file through QEMU stdout.
        # This approach is used instead of loglistener to debug
        # https://crbug.com/86975 .
        if self._system_log_file:
            stdout = self._system_log_file
            stderr = subprocess.STDOUT
        else:
            stdout = open(os.devnull)
            stderr = sys.stderr

        self._qemu_process = subprocess.Popen(qemu_command,
                                              stdin=open(os.devnull),
                                              stdout=stdout,
                                              stderr=stderr)
        self._WaitUntilReady()