mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 14:26:09 +03:00
135 lines
4.8 KiB
Python
135 lines
4.8 KiB
Python
# Copyright 2018 The Chromium Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
"""Implements commands for running and interacting with Fuchsia on devices."""
|
|
|
|
import boot_data
|
|
import logging
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import target
|
|
import time
|
|
import uuid
|
|
|
|
from common import SDK_ROOT, EnsurePathExists
|
|
|
|
CONNECT_RETRY_COUNT = 20
|
|
CONNECT_RETRY_WAIT_SECS = 1
|
|
|
|
# Number of failed connection attempts before redirecting system logs to stdout.
|
|
CONNECT_RETRY_COUNT_BEFORE_LOGGING = 10
|
|
|
|
class DeviceTarget(target.Target):
|
|
def __init__(self, output_dir, target_cpu, host=None, port=None,
|
|
ssh_config=None, system_log_file=None):
|
|
"""output_dir: The directory which will contain the files that are
|
|
generated to support the deployment.
|
|
target_cpu: The CPU architecture of the deployment target. Can be
|
|
"x64" or "arm64".
|
|
host: The address of the deployment target device.
|
|
port: The port of the SSH service on the deployment target device.
|
|
ssh_config: The path to SSH configuration data."""
|
|
|
|
super(DeviceTarget, self).__init__(output_dir, target_cpu)
|
|
|
|
self._port = 22
|
|
self._auto = not host or not ssh_config
|
|
self._new_instance = True
|
|
self._system_log_file = system_log_file
|
|
self._loglistener = None
|
|
|
|
if self._auto:
|
|
self._ssh_config_path = EnsurePathExists(
|
|
boot_data.GetSSHConfigPath(output_dir))
|
|
else:
|
|
self._ssh_config_path = os.path.expanduser(ssh_config)
|
|
self._host = host
|
|
if port:
|
|
self._port = port
|
|
self._new_instance = False
|
|
|
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
if self._loglistener:
|
|
self._loglistener.kill()
|
|
|
|
def __Discover(self, node_name):
|
|
"""Returns the IP address and port of a Fuchsia instance discovered on
|
|
the local area network."""
|
|
|
|
netaddr_path = os.path.join(SDK_ROOT, 'tools', 'netaddr')
|
|
command = [netaddr_path, '--fuchsia', '--nowait', node_name]
|
|
logging.debug(' '.join(command))
|
|
proc = subprocess.Popen(command,
|
|
stdout=subprocess.PIPE,
|
|
stderr=open(os.devnull, 'w'))
|
|
proc.wait()
|
|
if proc.returncode == 0:
|
|
return proc.stdout.readlines()[0].strip()
|
|
return None
|
|
|
|
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)
|
|
|
|
# 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();
|
|
|
|
def IsNewInstance(self):
|
|
return self._new_instance
|
|
|
|
def _GetEndpoint(self):
|
|
return (self._host, self._port)
|
|
|
|
def _GetSshConfigPath(self):
|
|
return self._ssh_config_path
|