Allow additional expose_dirs in flutter_runner (flutter/engine#30749)

Users can add an expose_dirs entry to the program field in a
component's cml file to optionally expose extra directories
from their out/ directory.

BUG: fxbug.dev/89690
This commit is contained in:
Chase Latta 2022-01-10 10:44:21 -08:00 committed by GitHub
parent 41e0c394ee
commit 0f99fadcf2
4 changed files with 125 additions and 27 deletions

View File

@ -51,6 +51,7 @@ constexpr char kAssetsKey[] = "assets";
// "args" are how the component specifies arguments to the runner.
constexpr char kArgsKey[] = "args";
constexpr char kOldGenHeapSizeKey[] = "old_gen_heap_size";
constexpr char kExposeDirsKey[] = "expose_dirs";
constexpr char kTmpPath[] = "/tmp";
constexpr char kServiceRootPath[] = "/svc";
@ -88,6 +89,18 @@ void ParseArgs(std::vector<std::string>& args, ProgramMetadata* metadata) {
<< old_gen_heap_size_option;
}
}
std::string expose_dirs_option;
if (parsed_args.GetOptionValue(kExposeDirsKey, &expose_dirs_option)) {
// Parse the comma delimited string
std::vector<std::string> expose_dirs;
std::stringstream s(expose_dirs_option);
while (s.good()) {
std::string dir;
getline(s, dir, ','); // get first string delimited by comma
metadata->expose_dirs.push_back(dir);
}
}
}
} // namespace
@ -258,32 +271,41 @@ ComponentV2::ComponentV2(
fuchsia::io::OPEN_RIGHT_WRITABLE,
cloned_directory_ptr_.NewRequest());
cloned_directory_ptr_.events().OnOpen =
[this](zx_status_t status, std::unique_ptr<fuchsia::io::NodeInfo> info) {
cloned_directory_ptr_.Unbind();
if (status != ZX_OK) {
FML_LOG(ERROR)
<< "could not bind out directory for flutter component("
<< debug_label_ << "): " << zx_status_get_string(status);
return;
}
const char* other_dirs[] = {"debug", "ctrl", "diagnostics"};
// add other directories as RemoteDirs.
for (auto& dir_str : other_dirs) {
fuchsia::io::DirectoryHandle dir;
auto request = dir.NewRequest().TakeChannel();
auto status = fdio_service_connect_at(directory_ptr_.channel().get(),
dir_str, request.release());
if (status == ZX_OK) {
outgoing_dir_->AddEntry(
dir_str, std::make_unique<vfs::RemoteDir>(dir.TakeChannel()));
} else {
FML_LOG(ERROR) << "could not add out directory entry(" << dir_str
<< ") for flutter component(" << debug_label_
<< "): " << zx_status_get_string(status);
}
}
};
// Collect our standard set of directories along with directories that are
// included in the cml file to expose.
std::vector<std::string> other_dirs = {"debug", "ctrl", "diagnostics"};
for (auto dir : metadata.expose_dirs) {
other_dirs.push_back(dir);
}
cloned_directory_ptr_.events()
.OnOpen = [this, other_dirs](
zx_status_t status,
std::unique_ptr<fuchsia::io::NodeInfo> info) {
cloned_directory_ptr_.Unbind();
if (status != ZX_OK) {
FML_LOG(ERROR) << "could not bind out directory for flutter component("
<< debug_label_ << "): " << zx_status_get_string(status);
return;
}
// add other directories as RemoteDirs.
for (auto& dir_str : other_dirs) {
fuchsia::io::DirectoryHandle dir;
auto request = dir.NewRequest().TakeChannel();
auto status = fdio_service_connect_at(directory_ptr_.channel().get(),
dir_str.c_str(), request.release());
if (status == ZX_OK) {
outgoing_dir_->AddEntry(
dir_str.c_str(),
std::make_unique<vfs::RemoteDir>(dir.TakeChannel()));
} else {
FML_LOG(ERROR) << "could not add out directory entry(" << dir_str
<< ") for flutter component(" << debug_label_
<< "): " << zx_status_get_string(status);
}
}
};
cloned_directory_ptr_.set_error_handler(
[this](zx_status_t status) { cloned_directory_ptr_.Unbind(); });

View File

@ -103,5 +103,78 @@ TEST(ComponentV2, ParseProgramMetadataOldGenHeapSizeInvalid) {
EXPECT_EQ(result.old_gen_heap_size, std::nullopt);
}
TEST(ComponentV2, ParseProgramMetadataNoExposeDirs) {
// Should always have a valid expose_dirs entry
std::vector<fuchsia::data::DictionaryEntry> entries;
fuchsia::data::Dictionary program_metadata;
program_metadata.set_entries(std::move(entries));
ProgramMetadata result = ComponentV2::ParseProgramMetadata(program_metadata);
EXPECT_EQ(result.expose_dirs.empty(), true);
}
TEST(ComponentV2, ParseProgramMetadataWithSingleExposeDirs) {
// Can parse a single exposed dir
std::vector<fuchsia::data::DictionaryEntry> entries;
fuchsia::data::DictionaryEntry args_entry;
args_entry.key = "args";
args_entry.value = std::make_unique<fuchsia::data::DictionaryValue>(
fuchsia::data::DictionaryValue::WithStrVec({"--expose_dirs=foo"}));
entries.push_back(std::move(args_entry));
fuchsia::data::Dictionary program_metadata;
program_metadata.set_entries(std::move(entries));
ProgramMetadata result = ComponentV2::ParseProgramMetadata(program_metadata);
ASSERT_EQ(result.expose_dirs.size(), 1u);
EXPECT_EQ(result.expose_dirs[0], "foo");
}
TEST(ComponentV2, ParseProgramMetadataWithMultipleExposeDirs) {
// Can parse a multiple exposed dirs
std::vector<fuchsia::data::DictionaryEntry> entries;
fuchsia::data::DictionaryEntry args_entry;
args_entry.key = "args";
args_entry.value = std::make_unique<fuchsia::data::DictionaryValue>(
fuchsia::data::DictionaryValue::WithStrVec(
{"--expose_dirs=foo,bar,baz"}));
entries.push_back(std::move(args_entry));
fuchsia::data::Dictionary program_metadata;
program_metadata.set_entries(std::move(entries));
ProgramMetadata result = ComponentV2::ParseProgramMetadata(program_metadata);
ASSERT_EQ(result.expose_dirs.size(), 3u);
EXPECT_EQ(result.expose_dirs[0], "foo");
EXPECT_EQ(result.expose_dirs[1], "bar");
EXPECT_EQ(result.expose_dirs[2], "baz");
}
TEST(ComponentV2, ParseProgramMetadataWithSingleExposeDirsAndOtherArgs) {
// Can parse a single exposed dir when other args are present
std::vector<fuchsia::data::DictionaryEntry> entries;
fuchsia::data::DictionaryEntry args_entry;
args_entry.key = "args";
args_entry.value = std::make_unique<fuchsia::data::DictionaryValue>(
fuchsia::data::DictionaryValue::WithStrVec(
{"--expose_dirs=foo", "--foo=bar"}));
entries.push_back(std::move(args_entry));
fuchsia::data::Dictionary program_metadata;
program_metadata.set_entries(std::move(entries));
ProgramMetadata result = ComponentV2::ParseProgramMetadata(program_metadata);
ASSERT_EQ(result.expose_dirs.size(), 1u);
EXPECT_EQ(result.expose_dirs[0], "foo");
}
} // anonymous namespace
} // namespace flutter_runner

View File

@ -26,6 +26,9 @@ struct ProgramMetadata {
/// The preferred heap size for the Flutter component in megabytes.
std::optional<int64_t> old_gen_heap_size = std::nullopt;
/// A list of additional directories that we will expose in out/
std::vector<std::string> expose_dirs;
};
} // namespace flutter_runner

View File

@ -247,7 +247,7 @@ while true; do
config_url="http://${addr}:${port}/config.json"
if [[ ${component_framework_version} == 2 ]]; then
run_ssh_command pkgctl repo add \
run_ssh_command pkgctl repo add url \
-n "engine" \
"${config_url}"
else