Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
6be32aa7
Commit
6be32aa7
authored
Sep 15, 2017
by
Zachary Anderson
Committed by
GitHub
Sep 15, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Fuchsia] Connect to the VM service using an ssh tunnel (#12100)
parent
d6580489
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
139 additions
and
42 deletions
+139
-42
fuchsia_reload.dart
packages/flutter_tools/lib/src/commands/fuchsia_reload.dart
+139
-42
No files found.
packages/flutter_tools/lib/src/commands/fuchsia_reload.dart
View file @
6be32aa7
...
@@ -27,6 +27,8 @@ import '../vmservice.dart';
...
@@ -27,6 +27,8 @@ import '../vmservice.dart';
// $ flutter fuchsia_reload -f ~/fuchsia -a 192.168.1.39 \
// $ flutter fuchsia_reload -f ~/fuchsia -a 192.168.1.39 \
// -g //lib/flutter/examples/flutter_gallery:flutter_gallery
// -g //lib/flutter/examples/flutter_gallery:flutter_gallery
final
String
ipv4Loopback
=
InternetAddress
.
LOOPBACK_IP_V4
.
address
;
class
FuchsiaReloadCommand
extends
FlutterCommand
{
class
FuchsiaReloadCommand
extends
FlutterCommand
{
FuchsiaReloadCommand
()
{
FuchsiaReloadCommand
()
{
addBuildModeFlags
(
defaultToRelease:
false
);
addBuildModeFlags
(
defaultToRelease:
false
);
...
@@ -89,46 +91,64 @@ class FuchsiaReloadCommand extends FlutterCommand {
...
@@ -89,46 +91,64 @@ class FuchsiaReloadCommand extends FlutterCommand {
_validateArguments
();
_validateArguments
();
// Find the network ports used on the device by VM service instances.
// Find the network ports used on the device by VM service instances.
final
List
<
int
>
s
ervicePorts
=
await
_getServicePorts
();
final
List
<
int
>
deviceS
ervicePorts
=
await
_getServicePorts
();
if
(
s
ervicePorts
.
isEmpty
)
if
(
deviceS
ervicePorts
.
isEmpty
)
throwToolExit
(
'Couldn
\'
t find any running Observatory instances.'
);
throwToolExit
(
'Couldn
\'
t find any running Observatory instances.'
);
for
(
int
port
in
s
ervicePorts
)
for
(
int
port
in
deviceS
ervicePorts
)
printTrace
(
'Fuchsia service port:
$port
'
);
printTrace
(
'Fuchsia service port:
$port
'
);
if
(
_list
)
{
// Set up ssh tunnels to forward the device ports to local ports.
await
_listVMs
(
servicePorts
);
final
List
<
_PortForwarder
>
forwardedPorts
=
await
_forwardPorts
(
return
;
deviceServicePorts
);
}
// Wrap everything in try/finally to make sure we kill the ssh processes
// doing the port forwarding.
try
{
final
List
<
int
>
servicePorts
=
forwardedPorts
.
map
(
(
_PortForwarder
pf
)
=>
pf
.
port
).
toList
();
if
(
_list
)
{
await
_listVMs
(
servicePorts
);
// Port forwarding stops when the command ends. Keep the program running
// until directed by the user so that Observatory URLs that we print
// continue to work.
printStatus
(
'Press Enter to exit.'
);
await
stdin
.
first
;
return
;
}
// Check that there are running VM services on the returned
// Check that there are running VM services on the returned
// ports, and find the Isolates that are running the target app.
// ports, and find the Isolates that are running the target app.
final
String
isolateName
=
'
$_binaryName
\
$main$_isolateNumber
'
;
final
String
isolateName
=
'
$_binaryName
\
$main$_isolateNumber
'
;
final
List
<
int
>
targetPorts
=
await
_filterPorts
(
servicePorts
,
isolateName
);
final
List
<
int
>
targetPorts
=
await
_filterPorts
(
if
(
targetPorts
.
isEmpty
)
servicePorts
,
isolateName
);
throwToolExit
(
'No VMs found running
$_binaryName
.'
);
if
(
targetPorts
.
isEmpty
)
for
(
int
port
in
targetPorts
)
throwToolExit
(
'No VMs found running
$_binaryName
.'
);
printTrace
(
'Found
$_binaryName
at
$port
'
);
for
(
int
port
in
targetPorts
)
printTrace
(
'Found
$_binaryName
at
$port
'
);
// Set up a device and hot runner and attach the hot runner to the first
// vm service we found.
// Set up a device and hot runner and attach the hot runner to the first
final
List
<
String
>
fullAddresses
=
targetPorts
.
map
(
// vm service we found.
(
int
p
)
=>
'
$_address
:
$p
'
final
List
<
String
>
fullAddresses
=
targetPorts
.
map
(
).
toList
();
(
int
p
)
=>
'
$ipv4Loopback
:
$p
'
final
List
<
Uri
>
observatoryUris
=
fullAddresses
.
map
(
).
toList
();
(
String
a
)
=>
Uri
.
parse
(
'http://
$a
'
)
final
List
<
Uri
>
observatoryUris
=
fullAddresses
.
map
(
).
toList
();
(
String
a
)
=>
Uri
.
parse
(
'http://
$a
'
)
final
FuchsiaDevice
device
=
new
FuchsiaDevice
(
fullAddresses
[
0
]);
).
toList
();
final
FlutterDevice
flutterDevice
=
new
FlutterDevice
(
device
);
final
FuchsiaDevice
device
=
new
FuchsiaDevice
(
fullAddresses
[
0
]);
flutterDevice
.
observatoryUris
=
observatoryUris
;
final
FlutterDevice
flutterDevice
=
new
FlutterDevice
(
device
);
final
HotRunner
hotRunner
=
new
HotRunner
(
flutterDevice
.
observatoryUris
=
observatoryUris
;
<
FlutterDevice
>[
flutterDevice
],
final
HotRunner
hotRunner
=
new
HotRunner
(
debuggingOptions:
new
DebuggingOptions
.
enabled
(
getBuildInfo
()),
<
FlutterDevice
>[
flutterDevice
],
target:
_target
,
debuggingOptions:
new
DebuggingOptions
.
enabled
(
getBuildInfo
()),
projectRootPath:
_fuchsiaProjectPath
,
target:
_target
,
packagesFilePath:
_dotPackagesPath
projectRootPath:
_fuchsiaProjectPath
,
);
packagesFilePath:
_dotPackagesPath
printStatus
(
'Connecting to
$_binaryName
'
);
);
await
hotRunner
.
attach
(
viewFilter:
isolateName
);
printStatus
(
'Connecting to
$_binaryName
'
);
await
hotRunner
.
attach
(
viewFilter:
isolateName
);
}
finally
{
await
Future
.
wait
(
forwardedPorts
.
map
((
_PortForwarder
pf
)
=>
pf
.
stop
()));
}
}
}
// A cache of VMService connections.
// A cache of VMService connections.
...
@@ -136,7 +156,7 @@ class FuchsiaReloadCommand extends FlutterCommand {
...
@@ -136,7 +156,7 @@ class FuchsiaReloadCommand extends FlutterCommand {
VMService
_getVMService
(
int
port
)
{
VMService
_getVMService
(
int
port
)
{
if
(!
_vmServiceCache
.
containsKey
(
port
))
{
if
(!
_vmServiceCache
.
containsKey
(
port
))
{
final
String
addr
=
'http://
$
_address
:
$port
'
;
final
String
addr
=
'http://
$
ipv4Loopback
:
$port
'
;
final
Uri
uri
=
Uri
.
parse
(
addr
);
final
Uri
uri
=
Uri
.
parse
(
addr
);
final
VMService
vmService
=
VMService
.
connect
(
uri
);
final
VMService
vmService
=
VMService
.
connect
(
uri
);
_vmServiceCache
[
port
]
=
vmService
;
_vmServiceCache
[
port
]
=
vmService
;
...
@@ -148,7 +168,7 @@ class FuchsiaReloadCommand extends FlutterCommand {
...
@@ -148,7 +168,7 @@ class FuchsiaReloadCommand extends FlutterCommand {
bool
connected
=
true
;
bool
connected
=
true
;
Socket
s
;
Socket
s
;
try
{
try
{
s
=
await
Socket
.
connect
(
"
$_address
"
,
port
);
s
=
await
Socket
.
connect
(
ipv4Loopback
,
port
);
}
catch
(
_
)
{
}
catch
(
_
)
{
connected
=
false
;
connected
=
false
;
}
}
...
@@ -343,6 +363,13 @@ class FuchsiaReloadCommand extends FlutterCommand {
...
@@ -343,6 +363,13 @@ class FuchsiaReloadCommand extends FlutterCommand {
return
<
String
>[
path
,
name
];
return
<
String
>[
path
,
name
];
}
}
Future
<
List
<
_PortForwarder
>>
_forwardPorts
(
List
<
int
>
remotePorts
)
{
final
String
config
=
'
$_fuchsiaRoot
/out/
$_buildType
/ssh-keys/ssh_config'
;
return
Future
.
wait
(
remotePorts
.
map
((
int
remotePort
)
{
return
_PortForwarder
.
start
(
config
,
_address
,
remotePort
);
}));
}
Future
<
List
<
int
>>
_getServicePorts
()
async
{
Future
<
List
<
int
>>
_getServicePorts
()
async
{
final
FuchsiaDeviceCommandRunner
runner
=
final
FuchsiaDeviceCommandRunner
runner
=
new
FuchsiaDeviceCommandRunner
(
_address
,
_fuchsiaRoot
,
_buildType
);
new
FuchsiaDeviceCommandRunner
(
_address
,
_fuchsiaRoot
,
_buildType
);
...
@@ -372,6 +399,77 @@ class FuchsiaReloadCommand extends FlutterCommand {
...
@@ -372,6 +399,77 @@ class FuchsiaReloadCommand extends FlutterCommand {
}
}
}
}
// Instances of this class represent a running ssh tunnel from the host to a
// VM service running on a Fuchsia device. [process] is the ssh process running
// the tunnel and [port] is the local port.
class
_PortForwarder
{
final
String
_remoteAddress
;
final
int
_remotePort
;
final
int
_localPort
;
final
Process
_process
;
final
String
_sshConfig
;
_PortForwarder
.
_
(
this
.
_remoteAddress
,
this
.
_remotePort
,
this
.
_localPort
,
this
.
_process
,
this
.
_sshConfig
);
int
get
port
=>
_localPort
;
static
Future
<
_PortForwarder
>
start
(
String
sshConfig
,
String
address
,
int
remotePort
)
async
{
final
int
localPort
=
await
_potentiallyAvailablePort
();
if
(
localPort
==
0
)
{
printStatus
(
'_PortForwarder failed to find a local port for
$address
:
$remotePort
'
);
return
new
_PortForwarder
.
_
(
null
,
0
,
0
,
null
,
null
);
}
final
List
<
String
>
command
=
<
String
>[
'ssh'
,
'-F'
,
sshConfig
,
'-nNT'
,
'-L'
,
'
$localPort
:
$ipv4Loopback
:
$remotePort
'
,
address
];
printTrace
(
"_PortForwarder running '
${command.join(' ')}
'"
);
final
Process
process
=
await
processManager
.
start
(
command
);
process
.
exitCode
.
then
((
int
c
)
{
printTrace
(
"'
${command.join(' ')}
' exited with exit code
$c
"
);
});
printTrace
(
'Set up forwarding from
$localPort
to
$address
:
$remotePort
'
);
return
new
_PortForwarder
.
_
(
address
,
remotePort
,
localPort
,
process
,
sshConfig
);
}
Future
<
Null
>
stop
()
async
{
// Kill the original ssh process if it is still around.
if
(
_process
!=
null
)
{
printTrace
(
'_PortForwarder killing
${_process.pid}
for port
$_localPort
'
);
_process
.
kill
();
}
// Cancel the forwarding request.
final
List
<
String
>
command
=
<
String
>[
'ssh'
,
'-F'
,
_sshConfig
,
'-O'
,
'cancel'
,
'-L'
,
'
$_localPort
:
$ipv4Loopback
:
$_remotePort
'
,
_remoteAddress
];
final
ProcessResult
result
=
await
processManager
.
run
(
command
);
printTrace
(
command
.
join
(
' '
));
if
(
result
.
exitCode
!=
0
)
{
printTrace
(
"Command failed:
\n
stdout:
${result.stdout}
\n
stderr:
${result.stderr}
"
);
}
}
static
Future
<
int
>
_potentiallyAvailablePort
()
async
{
int
port
=
0
;
ServerSocket
s
;
try
{
s
=
await
ServerSocket
.
bind
(
ipv4Loopback
,
0
);
port
=
s
.
port
;
}
catch
(
e
)
{
// Failures are signaled by a return value of 0 from this function.
printTrace
(
'_potentiallyAvailablePort failed:
$e
'
);
}
if
(
s
!=
null
)
await
s
.
close
();
return
port
;
}
}
class
FuchsiaDeviceCommandRunner
{
class
FuchsiaDeviceCommandRunner
{
// TODO(zra): Get rid of _address and instead use
// TODO(zra): Get rid of _address and instead use
...
@@ -384,10 +482,9 @@ class FuchsiaDeviceCommandRunner {
...
@@ -384,10 +482,9 @@ class FuchsiaDeviceCommandRunner {
Future
<
List
<
String
>>
run
(
String
command
)
async
{
Future
<
List
<
String
>>
run
(
String
command
)
async
{
final
String
config
=
'
$_fuchsiaRoot
/out/
$_buildType
/ssh-keys/ssh_config'
;
final
String
config
=
'
$_fuchsiaRoot
/out/
$_buildType
/ssh-keys/ssh_config'
;
final
List
<
String
>
args
=
<
String
>[
'-F'
,
config
,
_address
,
command
];
final
List
<
String
>
args
=
<
String
>[
'ssh'
,
'-F'
,
config
,
_address
,
command
];
printTrace
(
'ssh
${args.join(' ')}
'
);
printTrace
(
args
.
join
(
' '
));
final
ProcessResult
result
=
final
ProcessResult
result
=
await
processManager
.
run
(
args
);
await
processManager
.
run
(<
String
>[
'ssh'
,
'-F'
,
config
,
_address
,
command
]);
if
(
result
.
exitCode
!=
0
)
{
if
(
result
.
exitCode
!=
0
)
{
printStatus
(
"Command failed:
$command
\n
stdout:
${result.stdout}
\n
stderr:
${result.stderr}
"
);
printStatus
(
"Command failed:
$command
\n
stdout:
${result.stdout}
\n
stderr:
${result.stderr}
"
);
return
null
;
return
null
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment