Unverified Commit aed4315a authored by Chase Latta's avatar Chase Latta Committed by GitHub

Replace amber_ctl with pkgctl for Fuchsia (#89785)

Fuchsia is deprecating amber_ctl and replacing it with pkgctl.
This change removes the FuchsiaAmberCtl class and replaces it
with the FuchsiaPkgctl class and updates the usages appropriately.

BUG: fxbug.dev/83865
parent eb5ae39f
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import '../base/process.dart';
import 'fuchsia_device.dart';
import 'fuchsia_pm.dart';
// usage: amber_ctl <command> [opts]
// Commands
// get_up - get an update for a package
// Options
// -n: name of the package
// -v: version of the package to retrieve, if none is supplied any
// package instance could match
// -m: merkle root of the package to retrieve, if none is supplied
// any package instance could match
//
// get_blob - get the specified content blob
// -i: content ID of the blob
//
// add_src - add a source to the list we can use
// -n: name of the update source (optional, with URL)
// -f: file path or url to a source config file
// -h: SHA256 hash of source config file (optional, with URL)
// -x: do not disable other active sources (if the provided source is
// enabled)
//
// add_repo_cfg - add a repository config to the set of known repositories,
// using a source config
// -n: name of the update source (optional, with URL)
// -f: file path or url to a source config file
// -h: SHA256 hash of source config file (optional, with URL)
//
// rm_src - remove a source, if it exists
// -n: name of the update source
//
// list_srcs - list the set of sources we can use
//
// enable_src
// -n: name of the update source
// -x: do not disable other active sources
//
// disable_src
// -n: name of the update source
//
// system_update - check for, download, and apply any available system
// update
//
// gc - trigger a garbage collection
//
// print_state - print go routine state of amber process
/// Simple wrapper for interacting with the 'amber_ctl' tool running on the
/// Fuchsia device.
class FuchsiaAmberCtl {
/// Teaches the amber instance running on [device] about the Fuchsia package
/// server accessible via [configUrl].
Future<bool> addSrc(FuchsiaDevice device, FuchsiaPackageServer server) async {
final String localIp = await device.hostAddress;
final String configUrl = 'http://[$localIp]:${server.port}/config.json';
final RunResult result = await device.shell(
'amber_ctl add_src -x -f $configUrl',
);
return result.exitCode == 0;
}
/// Instructs the amber instance running on [device] to forget about the
/// Fuchsia package server that it was accessing via [serverUrl].
Future<bool> rmSrc(FuchsiaDevice device, FuchsiaPackageServer server) async {
final String localIp = await device.hostAddress;
final RunResult result = await device.shell(
'amber_ctl rm_src -n http://[$localIp]:${server.port}/',
);
return result.exitCode == 0;
}
/// Instructs the amber instance running on [device] to prefetch the package
/// [packageName].
Future<bool> getUp(FuchsiaDevice device, String packageName) async {
final RunResult result = await device.shell(
'amber_ctl get_up -n $packageName',
);
return result.exitCode == 0;
}
/// Converts the amber source config created when [server] was set up to a
/// pkg_resolver repo config, and teaches the pkg_resolver instance running
/// on [device] about the [FuchsiaPackageServer].
Future<bool> addRepoCfg(FuchsiaDevice device, FuchsiaPackageServer server) async {
final String localIp = await device.hostAddress;
final String configUrl = 'http://[$localIp]:${server.port}/config.json';
final RunResult result = await device.shell(
'amber_ctl add_repo_cfg -n ${server.name} -f $configUrl',
);
return result.exitCode == 0;
}
/// Instructs the pkg_resolver instance running on [device] to prefetch the
/// package [packageName].
Future<bool> pkgCtlResolve(
FuchsiaDevice device,
FuchsiaPackageServer server,
String packageName,
) async {
final String packageUrl = 'fuchsia-pkg://${server.name}/$packageName';
final RunResult result = await device.shell('pkgctl resolve $packageUrl');
return result.exitCode == 0;
}
/// Instructs the pkg_resolver instance running on [device] to forget about
/// the Fuchsia package server that it was accessing via [serverUrl].
Future<bool> pkgCtlRepoRemove(
FuchsiaDevice device,
FuchsiaPackageServer server,
) async {
final String repoUrl = 'fuchsia-pkg://${server.name}';
final RunResult result = await device.shell('pkgctl repo rm $repoUrl');
return result.exitCode == 0;
}
}
......@@ -26,12 +26,12 @@ import '../globals.dart' as globals;
import '../project.dart';
import '../vmservice.dart';
import 'amber_ctl.dart';
import 'application_package.dart';
import 'fuchsia_build.dart';
import 'fuchsia_pm.dart';
import 'fuchsia_sdk.dart';
import 'fuchsia_workflow.dart';
import 'pkgctl.dart';
import 'session_control.dart';
import 'tiles_ctl.dart';
......@@ -40,14 +40,15 @@ FuchsiaDeviceTools get fuchsiaDeviceTools => context.get<FuchsiaDeviceTools>();
/// Fuchsia device-side tools.
class FuchsiaDeviceTools {
FuchsiaAmberCtl _amberCtl;
FuchsiaAmberCtl get amberCtl => _amberCtl ??= FuchsiaAmberCtl();
FuchsiaPkgctl _pkgctl;
FuchsiaPkgctl get pkgctl => _pkgctl ??= FuchsiaPkgctl();
FuchsiaTilesCtl _tilesCtl;
FuchsiaTilesCtl get tilesCtl => _tilesCtl ??= FuchsiaTilesCtl();
FuchsiaSessionControl _sessionControl;
FuchsiaSessionControl get sessionControl => _sessionControl ??= FuchsiaSessionControl();
FuchsiaSessionControl get sessionControl =>
_sessionControl ??= FuchsiaSessionControl();
}
final String _ipv4Loopback = InternetAddress.loopbackIPv4.address;
......@@ -369,56 +370,39 @@ class FuchsiaDevice extends Device {
bool serverRegistered = false;
String fuchsiaUrl;
try {
if (await isSession) {
// Prefetch session_control
if (!await fuchsiaDeviceTools.amberCtl.getUp(this, 'session_control')) {
globals.printError('Failed to get amber to prefetch session_control');
return LaunchResult.failed();
}
} else {
// Ask amber to pre-fetch some things we'll need before setting up our own
// package server. This is to avoid relying on amber correctly using
// multiple package servers, support for which is in flux.
if (!await fuchsiaDeviceTools.amberCtl.getUp(this, 'tiles')) {
globals.printError('Failed to get amber to prefetch tiles');
return LaunchResult.failed();
}
if (!await fuchsiaDeviceTools.amberCtl.getUp(this, 'tiles_ctl')) {
globals.printError('Failed to get amber to prefetch tiles_ctl');
return LaunchResult.failed();
}
}
// Start up a package server.
const String packageServerName = FuchsiaPackageServer.toolHost;
fuchsiaPackageServer = FuchsiaPackageServer(
packageRepo.path, packageServerName, '', port);
fuchsiaPackageServer =
FuchsiaPackageServer(packageRepo.path, packageServerName, '', port);
if (!await fuchsiaPackageServer.start()) {
globals.printError('Failed to start the Fuchsia package server');
return LaunchResult.failed();
}
// Serve the application's package.
final File farArchive = package.farArchive(
debuggingOptions.buildInfo.mode);
final File farArchive =
package.farArchive(debuggingOptions.buildInfo.mode);
if (!await fuchsiaPackageServer.addPackage(farArchive)) {
globals.printError('Failed to add package to the package server');
return LaunchResult.failed();
}
// Serve the flutter_runner.
final File flutterRunnerArchive = globals.fs.file(globals.artifacts.getArtifactPath(
final File flutterRunnerArchive =
globals.fs.file(globals.artifacts.getArtifactPath(
Artifact.fuchsiaFlutterRunner,
platform: await targetPlatform,
mode: debuggingOptions.buildInfo.mode,
));
if (!await fuchsiaPackageServer.addPackage(flutterRunnerArchive)) {
globals.printError('Failed to add flutter_runner package to the package server');
globals.printError(
'Failed to add flutter_runner package to the package server');
return LaunchResult.failed();
}
// Teach the package controller about the package server.
if (!await fuchsiaDeviceTools.amberCtl.addRepoCfg(this, fuchsiaPackageServer)) {
if (!await fuchsiaDeviceTools.pkgctl
.addRepo(this, fuchsiaPackageServer)) {
globals.printError('Failed to teach amber about the package server');
return LaunchResult.failed();
}
......@@ -439,20 +423,23 @@ class FuchsiaDevice extends Device {
flutterRunnerName = 'flutter_jit_runner';
}
}
if (!await fuchsiaDeviceTools.amberCtl.pkgCtlResolve(
this, fuchsiaPackageServer, flutterRunnerName)) {
globals.printError('Failed to get pkgctl to prefetch the flutter_runner');
if (!await fuchsiaDeviceTools.pkgctl
.resolve(this, fuchsiaPackageServer.name, flutterRunnerName)) {
globals
.printError('Failed to get pkgctl to prefetch the flutter_runner');
return LaunchResult.failed();
}
// Tell the package controller to prefetch the app.
if (!await fuchsiaDeviceTools.amberCtl.pkgCtlResolve(
this, fuchsiaPackageServer, appName)) {
if (!await fuchsiaDeviceTools.pkgctl
.resolve(this, fuchsiaPackageServer.name, appName)) {
globals.printError('Failed to get pkgctl to prefetch the package');
return LaunchResult.failed();
}
fuchsiaUrl = 'fuchsia-pkg://$packageServerName/$appName#meta/$appName.cmx';
fuchsiaUrl =
'fuchsia-pkg://$packageServerName/$appName#meta/$appName.cmx';
if (await isSession) {
// Instruct session_control to start the app
......@@ -463,12 +450,14 @@ class FuchsiaDevice extends Device {
} else {
// Ensure tiles_ctl is started, and start the app.
if (!await FuchsiaTilesCtl.ensureStarted(this)) {
globals.printError('Failed to ensure that tiles is started on the device');
globals.printError(
'Failed to ensure that tiles is started on the device');
return LaunchResult.failed();
}
// Instruct tiles_ctl to start the app.
if (!await fuchsiaDeviceTools.tilesCtl.add(this, fuchsiaUrl, <String>[])) {
if (!await fuchsiaDeviceTools.tilesCtl
.add(this, fuchsiaUrl, <String>[])) {
globals.printError('Failed to add the app to tiles');
return LaunchResult.failed();
}
......@@ -477,17 +466,18 @@ class FuchsiaDevice extends Device {
// Try to un-teach the package controller about the package server if
// needed.
if (serverRegistered) {
await fuchsiaDeviceTools.amberCtl.pkgCtlRepoRemove(this, fuchsiaPackageServer);
await fuchsiaDeviceTools.pkgctl.rmRepo(this, fuchsiaPackageServer);
}
// Shutdown the package server and delete the package repo;
globals.printTrace("Shutting down the tool's package server.");
fuchsiaPackageServer?.stop();
globals.printTrace("Removing the tool's package repo: at ${packageRepo.path}");
globals.printTrace(
"Removing the tool's package repo: at ${packageRepo.path}");
try {
packageRepo.deleteSync(recursive: true);
} on Exception catch (e) {
globals.printError('Failed to remove Fuchsia package repo directory '
'at ${packageRepo.path}: $e.');
'at ${packageRepo.path}: $e.');
}
status.cancel();
}
......@@ -496,11 +486,12 @@ class FuchsiaDevice extends Device {
globals.printTrace('App successfully started in a release mode.');
return LaunchResult.succeeded();
}
globals.printTrace('App started in a non-release mode. Setting up vmservice connection.');
globals.printTrace(
'App started in a non-release mode. Setting up vmservice connection.');
// In a debug or profile build, try to find the observatory uri.
final FuchsiaIsolateDiscoveryProtocol discovery =
getIsolateDiscoveryProtocol(appName);
getIsolateDiscoveryProtocol(appName);
try {
final Uri observatoryUri = await discovery.uri;
return LaunchResult.succeeded(observatoryUri: observatoryUri);
......@@ -535,14 +526,15 @@ class FuchsiaDevice extends Device {
const TargetPlatform defaultTargetPlatform = TargetPlatform.fuchsia_arm64;
if (!globals.fuchsiaArtifacts.hasSshConfig) {
globals.printTrace('Could not determine Fuchsia target platform because '
'Fuchsia ssh configuration is missing.\n'
'Defaulting to arm64.');
'Fuchsia ssh configuration is missing.\n'
'Defaulting to arm64.');
return defaultTargetPlatform;
}
final RunResult result = await shell('uname -m');
if (result.exitCode != 0) {
globals.printError('Could not determine Fuchsia target platform type:\n$result\n'
'Defaulting to arm64.');
globals.printError(
'Could not determine Fuchsia target platform type:\n$result\n'
'Defaulting to arm64.');
return defaultTargetPlatform;
}
final String machine = result.stdout.trim();
......@@ -553,7 +545,7 @@ class FuchsiaDevice extends Device {
return TargetPlatform.fuchsia_x64;
default:
globals.printError('Unknown Fuchsia target platform "$machine". '
'Defaulting to arm64.');
'Defaulting to arm64.');
return defaultTargetPlatform;
}
}
......
......@@ -41,20 +41,28 @@ class FuchsiaKernelCompiler {
}
final String? platformDill = globals.artifacts?.getArtifactPath(
Artifact.platformKernelDill,
platform: TargetPlatform.fuchsia_arm64, // This file is not arch-specific.
platform: TargetPlatform.fuchsia_arm64, // This file is not arch-specific.
mode: buildInfo.mode,
);
if (platformDill == null || !globals.fs.isFileSync(platformDill)) {
throwToolExit('Fuchsia platform file not found at "$platformDill"');
}
List<String> flags = <String>[
'--target', 'flutter_runner',
'--platform', platformDill,
'--filesystem-scheme', 'main-root',
'--filesystem-root', fsRoot,
'--packages', '$multiRootScheme:///$relativePackagesFile',
'--output', globals.fs.path.join(outDir, '$appName.dil'),
'--component-name', appName,
'--no-sound-null-safety',
'--target',
'flutter_runner',
'--platform',
platformDill,
'--filesystem-scheme',
'main-root',
'--filesystem-root',
fsRoot,
'--packages',
'$multiRootScheme:///$relativePackagesFile',
'--output',
globals.fs.path.join(outDir, '$appName.dil'),
'--component-name',
appName,
...getBuildInfoFlags(buildInfo: buildInfo, manifestPath: manifestPath)
];
......
......@@ -104,6 +104,8 @@ class FuchsiaPM {
repoPath,
'-l',
'$host:$port',
'-c',
'2',
];
final Process process = await globals.processUtils.start(command);
process.stdout
......@@ -165,14 +167,15 @@ class FuchsiaPM {
/// server.stop();
/// }
class FuchsiaPackageServer {
factory FuchsiaPackageServer(String repo, String name, String host, int port) {
factory FuchsiaPackageServer(
String repo, String name, String host, int port) {
return FuchsiaPackageServer._(repo, name, host, port);
}
FuchsiaPackageServer._(this._repo, this.name, this._host, this._port);
static const String deviceHost = 'fuchsia.com';
static const String toolHost = 'flutter_tool';
static const String toolHost = 'flutter-tool';
final String _repo;
final String _host;
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import '../base/process.dart';
import 'fuchsia_device.dart';
import 'fuchsia_pm.dart';
/// Simple wrapper for interacting with the 'pkgctl' tool running on the
/// Fuchsia device.
class FuchsiaPkgctl {
/// Teaches pkgctl on [device] about the Fuchsia package server
Future<bool> addRepo(
FuchsiaDevice device, FuchsiaPackageServer server) async {
final String localIp = await device.hostAddress;
final String configUrl = 'http://[$localIp]:${server.port}/config.json';
final RunResult result =
await device.shell('pkgctl repo add url -n ${server.name} $configUrl');
return result.exitCode == 0;
}
/// Instructs pkgctl instance running on [device] to forget about the
/// Fuchsia package server with the given name
/// pkgctl repo rm fuchsia-pkg://mycorp.com
Future<bool> rmRepo(FuchsiaDevice device, FuchsiaPackageServer server) async {
final RunResult result = await device.shell(
'pkgctl repo rm fuchsia-pkg://${server.name}',
);
return result.exitCode == 0;
}
/// Instructs the pkgctl instance running on [device] to prefetch the package
/// with the given [packageUrl] hosted in the given [serverName].
Future<bool> resolve(
FuchsiaDevice device,
String serverName,
String packageName,
) async {
final String packageUrl = 'fuchsia-pkg://$serverName/$packageName';
final RunResult result = await device.shell('pkgctl resolve $packageUrl');
return result.exitCode == 0;
}
}
......@@ -16,7 +16,6 @@ import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/fuchsia/amber_ctl.dart';
import 'package:flutter_tools/src/fuchsia/application_package.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_dev_finder.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_device.dart';
......@@ -24,6 +23,7 @@ import 'package:flutter_tools/src/fuchsia/fuchsia_ffx.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_kernel_compiler.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_pm.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_sdk.dart';
import 'package:flutter_tools/src/fuchsia/pkgctl.dart';
import 'package:flutter_tools/src/fuchsia/session_control.dart';
import 'package:flutter_tools/src/fuchsia/tiles_ctl.dart';
import 'package:flutter_tools/src/globals_null_migrated.dart' as globals;
......@@ -389,7 +389,8 @@ void main() {
OperatingSystemUtils: () => osUtils,
});
testUsingContext('fail with correct LaunchResult when amber fails', () async {
testUsingContext('fail with correct LaunchResult when pkgctl fails',
() async {
final LaunchResult launchResult =
await setupAndStartApp(prebuilt: true, mode: BuildMode.release);
expect(launchResult.started, isFalse);
......@@ -398,7 +399,7 @@ void main() {
Artifacts: () => artifacts,
FileSystem: () => memoryFileSystem,
ProcessManager: () => fakeSuccessfulProcessManager,
FuchsiaDeviceTools: () => FakeFuchsiaDeviceTools(amber: FailingAmberCtl()),
FuchsiaDeviceTools: () => FakeFuchsiaDeviceTools(pkgctl: FailingPkgctl()),
FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig),
FuchsiaSdk: () => fuchsiaSdk,
OperatingSystemUtils: () => osUtils,
......@@ -478,66 +479,40 @@ class FakeFuchsiaIsolateDiscoveryProtocol implements FuchsiaIsolateDiscoveryProt
void dispose() {}
}
class FakeFuchsiaAmberCtl implements FuchsiaAmberCtl {
class FakeFuchsiaPkgctl implements FuchsiaPkgctl {
@override
Future<bool> addSrc(FuchsiaDevice device, FuchsiaPackageServer server) async {
Future<bool> addRepo(
FuchsiaDevice device, FuchsiaPackageServer server) async {
return true;
}
@override
Future<bool> rmSrc(FuchsiaDevice device, FuchsiaPackageServer server) async {
Future<bool> resolve(
FuchsiaDevice device, String serverName, String packageName) async {
return true;
}
@override
Future<bool> getUp(FuchsiaDevice device, String packageName) async {
return true;
}
@override
Future<bool> addRepoCfg(FuchsiaDevice device, FuchsiaPackageServer server) async {
return true;
}
@override
Future<bool> pkgCtlResolve(FuchsiaDevice device, FuchsiaPackageServer server, String packageName) async {
return true;
}
@override
Future<bool> pkgCtlRepoRemove(FuchsiaDevice device, FuchsiaPackageServer server) async {
Future<bool> rmRepo(FuchsiaDevice device, FuchsiaPackageServer server) async {
return true;
}
}
class FailingAmberCtl implements FuchsiaAmberCtl {
@override
Future<bool> addSrc(FuchsiaDevice device, FuchsiaPackageServer server) async {
return false;
}
@override
Future<bool> rmSrc(FuchsiaDevice device, FuchsiaPackageServer server) async {
return false;
}
@override
Future<bool> getUp(FuchsiaDevice device, String packageName) async {
return false;
}
class FailingPkgctl implements FuchsiaPkgctl {
@override
Future<bool> addRepoCfg(FuchsiaDevice device, FuchsiaPackageServer server) async {
Future<bool> addRepo(
FuchsiaDevice device, FuchsiaPackageServer server) async {
return false;
}
@override
Future<bool> pkgCtlResolve(FuchsiaDevice device, FuchsiaPackageServer server, String packageName) async {
Future<bool> resolve(
FuchsiaDevice device, String serverName, String packageName) async {
return false;
}
@override
Future<bool> pkgCtlRepoRemove(FuchsiaDevice device, FuchsiaPackageServer server) async {
Future<bool> rmRepo(FuchsiaDevice device, FuchsiaPackageServer server) async {
return false;
}
}
......@@ -633,15 +608,15 @@ class FailingFuchsiaSessionControl implements FuchsiaSessionControl {
class FakeFuchsiaDeviceTools implements FuchsiaDeviceTools {
FakeFuchsiaDeviceTools({
FuchsiaAmberCtl amber,
FuchsiaPkgctl pkgctl,
FuchsiaTilesCtl tiles,
FuchsiaSessionControl sessionControl,
}) : amberCtl = amber ?? FakeFuchsiaAmberCtl(),
tilesCtl = tiles ?? FakeFuchsiaTilesCtl(),
sessionControl = sessionControl ?? FakeFuchsiaSessionControl();
}) : pkgctl = pkgctl ?? FakeFuchsiaPkgctl(),
tilesCtl = tiles ?? FakeFuchsiaTilesCtl(),
sessionControl = sessionControl ?? FakeFuchsiaSessionControl();
@override
final FuchsiaAmberCtl amberCtl;
final FuchsiaPkgctl pkgctl;
@override
final FuchsiaTilesCtl tilesCtl;
......
......@@ -35,6 +35,8 @@ void main() {
'<repo>',
'-l',
'127.0.0.1:43819',
'-c',
'2',
]));
await FuchsiaPM().serve('<repo>', '127.0.0.1', 43819);
......@@ -52,6 +54,8 @@ void main() {
'<repo>',
'-l',
'[fe80::ec4:7aff:fecc:ea8f%eno2]:43819',
'-c',
'2'
]));
await FuchsiaPM().serve('<repo>', 'fe80::ec4:7aff:fecc:ea8f%eno2', 43819);
......
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