Unverified Commit 6f781314 authored by Zachary Anderson's avatar Zachary Anderson Committed by GitHub

WIP: [flutter_tool] Fix amberctl host address (#64020)

parent ec24a819
...@@ -58,25 +58,30 @@ class FuchsiaAmberCtl { ...@@ -58,25 +58,30 @@ class FuchsiaAmberCtl {
/// Teaches the amber instance running on [device] about the Fuchsia package /// Teaches the amber instance running on [device] about the Fuchsia package
/// server accessible via [configUrl]. /// server accessible via [configUrl].
Future<bool> addSrc(FuchsiaDevice device, FuchsiaPackageServer server) async { Future<bool> addSrc(FuchsiaDevice device, FuchsiaPackageServer server) async {
final String configUrl = '${server.interfaceStrippedUrl}/config.json'; final String localIp = await device.hostAddress;
final RunResult result = final String configUrl = 'http://[$localIp]:${server.port}/config.json';
await device.shell('amber_ctl add_src -x -f $configUrl'); final RunResult result = await device.shell(
'amber_ctl add_src -x -f $configUrl',
);
return result.exitCode == 0; return result.exitCode == 0;
} }
/// Instructs the amber instance running on [device] to forget about the /// Instructs the amber instance running on [device] to forget about the
/// Fuchsia package server that it was accessing via [serverUrl]. /// Fuchsia package server that it was accessing via [serverUrl].
Future<bool> rmSrc(FuchsiaDevice device, FuchsiaPackageServer server) async { Future<bool> rmSrc(FuchsiaDevice device, FuchsiaPackageServer server) async {
final RunResult result = final String localIp = await device.hostAddress;
await device.shell('amber_ctl rm_src -n ${server.interfaceStrippedUrl}'); final RunResult result = await device.shell(
'amber_ctl rm_src -n http://[$localIp]:${server.port}/',
);
return result.exitCode == 0; return result.exitCode == 0;
} }
/// Instructs the amber instance running on [device] to prefetch the package /// Instructs the amber instance running on [device] to prefetch the package
/// [packageName]. /// [packageName].
Future<bool> getUp(FuchsiaDevice device, String packageName) async { Future<bool> getUp(FuchsiaDevice device, String packageName) async {
final RunResult result = final RunResult result = await device.shell(
await device.shell('amber_ctl get_up -n $packageName'); 'amber_ctl get_up -n $packageName',
);
return result.exitCode == 0; return result.exitCode == 0;
} }
...@@ -84,15 +89,21 @@ class FuchsiaAmberCtl { ...@@ -84,15 +89,21 @@ class FuchsiaAmberCtl {
/// pkg_resolver repo config, and teaches the pkg_resolver instance running /// pkg_resolver repo config, and teaches the pkg_resolver instance running
/// on [device] about the [FuchsiaPackageServer]. /// on [device] about the [FuchsiaPackageServer].
Future<bool> addRepoCfg(FuchsiaDevice device, FuchsiaPackageServer server) async { Future<bool> addRepoCfg(FuchsiaDevice device, FuchsiaPackageServer server) async {
final String configUrl = '${server.interfaceStrippedUrl}/config.json'; final String localIp = await device.hostAddress;
final RunResult result = final String configUrl = 'http://[$localIp]:${server.port}/config.json';
await device.shell('amber_ctl add_repo_cfg -n ${server.name} -f $configUrl'); final RunResult result = await device.shell(
'amber_ctl add_repo_cfg -n ${server.name} -f $configUrl',
);
return result.exitCode == 0; return result.exitCode == 0;
} }
/// Instructs the pkg_resolver instance running on [device] to prefetch the /// Instructs the pkg_resolver instance running on [device] to prefetch the
/// package [packageName]. /// package [packageName].
Future<bool> pkgCtlResolve(FuchsiaDevice device, FuchsiaPackageServer server, String packageName) async { Future<bool> pkgCtlResolve(
FuchsiaDevice device,
FuchsiaPackageServer server,
String packageName,
) async {
final String packageUrl = 'fuchsia-pkg://${server.name}/$packageName'; final String packageUrl = 'fuchsia-pkg://${server.name}/$packageName';
final RunResult result = await device.shell('pkgctl resolve $packageUrl'); final RunResult result = await device.shell('pkgctl resolve $packageUrl');
return result.exitCode == 0; return result.exitCode == 0;
...@@ -100,7 +111,10 @@ class FuchsiaAmberCtl { ...@@ -100,7 +111,10 @@ class FuchsiaAmberCtl {
/// Instructs the pkg_resolver instance running on [device] to forget about /// Instructs the pkg_resolver instance running on [device] to forget about
/// the Fuchsia package server that it was accessing via [serverUrl]. /// the Fuchsia package server that it was accessing via [serverUrl].
Future<bool> pkgCtlRepoRemove(FuchsiaDevice device, FuchsiaPackageServer server) async { Future<bool> pkgCtlRepoRemove(
FuchsiaDevice device,
FuchsiaPackageServer server,
) async {
final String repoUrl = 'fuchsia-pkg://${server.name}'; final String repoUrl = 'fuchsia-pkg://${server.name}';
final RunResult result = await device.shell('pkgctl repo rm $repoUrl'); final RunResult result = await device.shell('pkgctl repo rm $repoUrl');
return result.exitCode == 0; return result.exitCode == 0;
......
...@@ -580,6 +580,32 @@ class FuchsiaDevice extends Device { ...@@ -580,6 +580,32 @@ class FuchsiaDevice extends Device {
/// [true] if the current host address is IPv6. /// [true] if the current host address is IPv6.
bool get ipv6 => _ipv6 ??= isIPv6Address(id); bool get ipv6 => _ipv6 ??= isIPv6Address(id);
/// Return the address that the device should use to communicate with the
/// host.
Future<String> get hostAddress async {
if (_cachedHostAddress != null) {
return _cachedHostAddress;
}
final RunResult result = await shell('echo \$SSH_CONNECTION');
void fail() {
throwToolExit('Failed to get local address, aborting.\n$result');
}
if (result.exitCode != 0) {
fail();
}
final List<String> splitResult = result.stdout.split(' ');
if (splitResult.isEmpty) {
fail();
}
final String addr = splitResult[0].replaceAll('%', '%25');
if (addr.isEmpty) {
fail();
}
return _cachedHostAddress = addr;
}
String _cachedHostAddress;
/// List the ports currently running a dart observatory. /// List the ports currently running a dart observatory.
Future<List<int>> servicePorts() async { Future<List<int>> servicePorts() async {
const String findCommand = 'find /hub -name vmservice-port'; const String findCommand = 'find /hub -name vmservice-port';
......
...@@ -195,20 +195,11 @@ class FuchsiaPackageServer { ...@@ -195,20 +195,11 @@ class FuchsiaPackageServer {
Process _process; Process _process;
/// The URL that can be used by the device to access this package server.
String get url => Uri(scheme: 'http', host: _host, port: _port).toString();
/// The URL that is stripped of interface name if it is an ipv6 address,
/// which should be supplied to amber_ctl to configure access to host.
String get interfaceStrippedUrl => Uri(
scheme: 'http',
host: (isIPv6Address(_host.split('%').first)) ? '[${_host.split('%').first}]' : _host,
port: _port,
).toString();
// The name used to reference the server by fuchsia-pkg:// urls. // The name used to reference the server by fuchsia-pkg:// urls.
final String name; final String name;
int get port => _port;
/// Uses [FuchiaPM.newrepo] and [FuchsiaPM.serve] to spin up a new Fuchsia /// Uses [FuchiaPM.newrepo] and [FuchsiaPM.serve] to spin up a new Fuchsia
/// package server. /// package server.
/// ///
......
...@@ -246,6 +246,47 @@ void main() { ...@@ -246,6 +246,47 @@ void main() {
FuchsiaSdk: () => MockFuchsiaSdk(), FuchsiaSdk: () => MockFuchsiaSdk(),
ProcessManager: () => MockProcessManager(), ProcessManager: () => MockProcessManager(),
}); });
testUsingContext('hostAddress parsing works', () async {
when(globals.processManager.run(any)).thenAnswer((Invocation _) async {
return ProcessResult(
1,
0,
'fe80::8c6c:2fff:fe3d:c5e1%ethp0003 50666 fe80::5054:ff:fe63:5e7a%ethp0003 22',
'',
);
});
final FuchsiaDevice device = FuchsiaDevice('id');
expect(await device.hostAddress, 'fe80::8c6c:2fff:fe3d:c5e1%25ethp0003');
}, overrides: <Type, Generator>{
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
FuchsiaSdk: () => MockFuchsiaSdk(),
ProcessManager: () => MockProcessManager(),
});
testUsingContext('hostAddress parsing throws tool error on failure', () async {
when(globals.processManager.run(any)).thenAnswer((Invocation _) async {
return ProcessResult(1, 1, '', '');
});
final FuchsiaDevice device = FuchsiaDevice('id');
expect(() async => await device.hostAddress, throwsToolExit());
}, overrides: <Type, Generator>{
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
FuchsiaSdk: () => MockFuchsiaSdk(),
ProcessManager: () => MockProcessManager(),
});
testUsingContext('hostAddress parsing throws tool error on empty response', () async {
when(globals.processManager.run(any)).thenAnswer((Invocation _) async {
return ProcessResult(1, 0, '', '');
});
final FuchsiaDevice device = FuchsiaDevice('id');
expect(() async => await device.hostAddress, throwsToolExit());
}, overrides: <Type, Generator>{
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
FuchsiaSdk: () => MockFuchsiaSdk(),
ProcessManager: () => MockProcessManager(),
});
}); });
group('displays friendly error when', () { group('displays friendly error when', () {
......
...@@ -71,21 +71,6 @@ void main() { ...@@ -71,21 +71,6 @@ void main() {
FuchsiaArtifacts: () => mockFuchsiaArtifacts, FuchsiaArtifacts: () => mockFuchsiaArtifacts,
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
}); });
testWithoutContext('ipv6 formatting logic of FuchsiaPackageServer', () {
const String host = 'fe80::ec4:7aff:fecc:ea8f%eno2';
const int port = 23;
expect(
FuchsiaPackageServer('a', 'b', host, port).url,
'http://[fe80::ec4:7aff:fecc:ea8f%25eno2]:23',
);
expect(
FuchsiaPackageServer('a', 'b', host, port).interfaceStrippedUrl,
'http://[fe80::ec4:7aff:fecc:ea8f]:23',
);
});
}); });
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment