Merge "acloud: [WebRTC] fix reconnect local-instance failed." am: ed75ab0f03
Original change: https://android-review.googlesource.com/c/platform/tools/acloud/+/1262155
Change-Id: I408edc47f0439139d7cd5d8e1adea258c2d29175
diff --git a/create/local_image_local_instance.py b/create/local_image_local_instance.py
index 088edeb..70bd1df 100644
--- a/create/local_image_local_instance.py
+++ b/create/local_image_local_instance.py
@@ -116,7 +116,7 @@
try:
self.CheckLaunchCVD(
cmd, host_bins_path, avd_spec.local_instance_id,
- local_image_path, no_prompts,
+ local_image_path, avd_spec.connect_webrtc, no_prompts,
avd_spec.boot_timeout_secs or constants.DEFAULT_CF_BOOT_TIMEOUT)
except errors.LaunchCVDFail as launch_error:
result_report.SetStatus(report.Status.BOOT_FAIL)
@@ -223,7 +223,7 @@
return launch_cmd
def CheckLaunchCVD(self, cmd, host_bins_path, local_instance_id,
- local_image_path, no_prompts=False,
+ local_image_path, connect_webrtc=False, no_prompts=False,
timeout_secs=constants.DEFAULT_CF_BOOT_TIMEOUT):
"""Execute launch_cvd command and wait for boot up completed.
@@ -236,6 +236,7 @@
host_bins_path: String of host package directory.
local_instance_id: Integer of instance id.
local_image_path: String of local image directory.
+ connect_webrtc: Boolean, whether to auto connect webrtc to device.
no_prompts: Boolean, True to skip all prompts.
timeout_secs: Integer, the number of seconds to wait for the AVD to boot up.
"""
@@ -262,7 +263,8 @@
"instance." % (local_image_path, occupied_ins_id),
utils.TextColors.FAIL)
sys.exit(constants.EXIT_BY_USER)
-
+ if connect_webrtc:
+ utils.ReleasePort(constants.WEBRTC_LOCAL_PORT)
self._LaunchCvd(cmd, local_instance_id, timeout=timeout_secs)
@staticmethod
diff --git a/reconnect/reconnect.py b/reconnect/reconnect.py
index fa43af8..6ced430 100644
--- a/reconnect/reconnect.py
+++ b/reconnect/reconnect.py
@@ -40,14 +40,18 @@
_RE_DISPLAY = re.compile(r"([\d]+)x([\d]+)\s.*")
_VNC_STARTED_PATTERN = "ssvnc vnc://127.0.0.1:%(vnc_port)d"
+_WEBRTC_PORTS_SEARCH = "".join(
+ [utils.PORT_MAPPING % {"local_port":port["local"],
+ "target_port":port["target"]}
+ for port in utils.WEBRTC_PORTS_MAPPING])
-def IsWebrtcEnable(ip_addr, host_user, host_ssh_private_key_path,
- extra_args_ssh_tunnel):
- """Check remote instance webRTC is enable.
+def _IsWebrtcEnable(instance, host_user, host_ssh_private_key_path,
+ extra_args_ssh_tunnel):
+ """Check local/remote instance webRTC is enable.
Args:
- ip_addr: String, use to connect to webrtc AVD on the instance.
+ instance: Local/Remote Instance object.
host_user: String of user login into the instance.
host_ssh_private_key_path: String of host key for logging in to the
host.
@@ -56,7 +60,9 @@
Returns:
Boolean: True if cf_runtime_cfg.enable_webrtc is True.
"""
- ssh = ssh_object.Ssh(ip=ssh_object.IP(ip=ip_addr), user=host_user,
+ if instance.islocal:
+ return instance.cf_runtime_cfg.enable_webrtc
+ ssh = ssh_object.Ssh(ip=ssh_object.IP(ip=instance.ip), user=host_user,
ssh_private_key_path=host_ssh_private_key_path,
extra_args_ssh_tunnel=extra_args_ssh_tunnel)
remote_cuttlefish_config = os.path.join(constants.REMOTE_LOG_FOLDER,
@@ -72,6 +78,24 @@
return False
+def _WebrtcPortOccupied():
+ """To decide whether need to release port.
+
+ Remote webrtc instance will create a ssh tunnel which may conflict with
+ local webrtc instance default port. Searching process cmd in the pattern
+ of _WEBRTC_PORTS_SEARCH to decide whether to release port.
+
+ Return:
+ True if need to release port.
+ """
+ process_output = utils.CheckOutput(constants.COMMAND_PS)
+ for line in process_output.splitlines():
+ match = re.search(_WEBRTC_PORTS_SEARCH, line)
+ if match:
+ return True
+ return False
+
+
def StartVnc(vnc_port, display):
"""Start vnc connect to AVD.
@@ -164,16 +188,26 @@
extra_args_ssh_tunnel=extra_args_ssh_tunnel)
vnc_port = forwarded_ports.vnc_port
adb_port = forwarded_ports.adb_port
-
- if IsWebrtcEnable(instance.ip,
- constants.GCE_USER,
- ssh_private_key_path,
- extra_args_ssh_tunnel):
- utils.EstablishWebRTCSshTunnel(
- ip_addr=instance.ip,
- rsa_key_file=ssh_private_key_path,
- ssh_user=constants.GCE_USER,
- extra_args_ssh_tunnel=extra_args_ssh_tunnel)
+ if _IsWebrtcEnable(instance,
+ constants.GCE_USER,
+ ssh_private_key_path,
+ extra_args_ssh_tunnel):
+ if instance.islocal:
+ if _WebrtcPortOccupied():
+ raise errors.PortOccupied("\nReconnect to a local webrtc instance "
+ "is not work because remote webrtc "
+ "instance has established ssh tunnel "
+ "which occupied local webrtc instance "
+ "port. If you want to connect to a "
+ "local-instance of webrtc. please run "
+ "'acloud create --local-instance "
+ "--autoconnect webrtc' directly.")
+ else:
+ utils.EstablishWebRTCSshTunnel(
+ ip_addr=instance.ip,
+ rsa_key_file=ssh_private_key_path,
+ ssh_user=constants.GCE_USER,
+ extra_args_ssh_tunnel=extra_args_ssh_tunnel)
utils.LaunchBrowser(constants.WEBRTC_LOCAL_HOST,
constants.WEBRTC_LOCAL_PORT)
elif(vnc_port and connect_vnc):
diff --git a/reconnect/reconnect_test.py b/reconnect/reconnect_test.py
index b33ca9b..ccce53e 100644
--- a/reconnect/reconnect_test.py
+++ b/reconnect/reconnect_test.py
@@ -51,7 +51,7 @@
self.Patch(AdbTools, "IsAdbConnected", return_value=False)
self.Patch(AdbTools, "IsAdbConnectionAlive", return_value=False)
self.Patch(utils, "IsCommandRunning", return_value=False)
- self.Patch(reconnect, "IsWebrtcEnable", return_value=False)
+ self.Patch(reconnect, "_IsWebrtcEnable", return_value=False)
fake_device_dict = {
constants.IP: "1.1.1.1",
constants.INSTANCE_NAME: "fake_name",
@@ -165,7 +165,7 @@
self.Patch(AdbTools, "IsAdbConnected", return_value=False)
self.Patch(AdbTools, "IsAdbConnectionAlive", return_value=False)
self.Patch(utils, "IsCommandRunning", return_value=False)
- self.Patch(reconnect, "IsWebrtcEnable", return_value=True)
+ self.Patch(reconnect, "_IsWebrtcEnable", return_value=True)
# test ssh tunnel not reconnect to the remote instance.
instance_object.vnc_port = 6666
@@ -192,7 +192,7 @@
instance_object.ssh_tunnel_is_connected = False
self.Patch(utils, "AutoConnect")
self.Patch(reconnect, "StartVnc")
- self.Patch(reconnect, "IsWebrtcEnable", return_value=False)
+ self.Patch(reconnect, "_IsWebrtcEnable", return_value=False)
#test reconnect remote instance when avd_type as gce.
instance_object.avd_type = "gce"
reconnect.ReconnectInstance(ssh_private_key_path, instance_object, fake_report)