Skip to content

Commit 9212b37

Browse files
committed
Use textproto for package migration config file.
- Use LOCAL_DEBIAN_SUBSTITUTION_MARKER_FILE environment variable for local testing. ``` LOCAL_DEBIAN_SUBSTITUTION_MARKER_FILE=/tmp/debian_substitution_marker bazel run //cuttlefish/host/commands/cvd -- fetch --default_build=aosp-main/aosp_cf_x86_64_phone-trunk_staging-userdebug --target_directory=$HOME/dl ``` - Example config ``` symlinks: { target: "/usr/lib/cuttlefish-common/bin/logcat_receiver" link_name: "bin/logcat_receiver" } symlinks: { target: "/usr/lib/cuttlefish-common/modem_simulator/files/iccprofile_for_sim0.xml" link_name: "etc/modem_simulator/files/iccprofile_for_sim0.xml" } ``` - b/403354033
1 parent be5bfa0 commit 9212b37

File tree

3 files changed

+100
-31
lines changed

3 files changed

+100
-31
lines changed

base/cvd/cuttlefish/host/commands/cvd/fetch/BUILD.bazel

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ package(
55
default_visibility = ["//:android_cuttlefish"],
66
)
77

8+
proto_library(
9+
name = "host_pkg_migration_proto",
10+
srcs = ["host_pkg_migration.proto"],
11+
)
12+
13+
cc_proto_library(
14+
name = "host_pkg_migration_cc_proto",
15+
deps = [":host_pkg_migration_proto"],
16+
)
17+
818
cc_library(
919
name = "fetch",
1020
srcs = [
@@ -20,6 +30,7 @@ cc_library(
2030
copts = COPTS + [ "-Werror=sign-compare" ],
2131
strip_include_prefix = "//cuttlefish",
2232
deps = [
33+
":host_pkg_migration_cc_proto",
2334
"//cuttlefish/common/libs/utils",
2435
"//cuttlefish/common/libs/utils:environment",
2536
"//cuttlefish/common/libs/utils:result",
@@ -36,6 +47,7 @@ cc_library(
3647
"@fmt",
3748
"@gflags",
3849
"@jsoncpp",
50+
"@protobuf",
3951
"@rules_cc//cc/runfiles",
4052
],
4153
data = [

base/cvd/cuttlefish/host/commands/cvd/fetch/fetch_cvd.cc

Lines changed: 62 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "common/libs/utils/environment.h"
4040
#include "common/libs/utils/files.h"
4141
#include "common/libs/utils/result.h"
42+
#include "cuttlefish/host/commands/cvd/fetch/host_pkg_migration.pb.h"
4243
#include "host/commands/cvd/fetch/fetch_cvd_parser.h"
4344
#include "host/commands/cvd/fetch/fetch_tracer.h"
4445
#include "host/commands/cvd/utils/common.h"
@@ -55,6 +56,8 @@
5556
#include "host/libs/web/luci_build_api.h"
5657
#include "host/libs/web/oauth2_consent.h"
5758

59+
#include <google/protobuf/text_format.h>
60+
5861
#ifndef BAZEL_CURRENT_REPOSITORY
5962
#define BAZEL_CURRENT_REPOSITORY ""
6063
#endif
@@ -303,40 +306,10 @@ Result<void> EnsureDirectoriesExist(const std::string& host_tools_directory,
303306

304307
static constexpr std::string_view kInstallDir = "/usr/lib/cuttlefish-common/bin";
305308

306-
Result<void> FetchHostPackage(
307-
BuildApi& build_api, const Build& build, const std::string& target_dir,
308-
const bool keep_archives,
309-
std::vector<std::string> debian_package_executables,
310-
FetchTracer::Trace trace) {
311-
LOG(INFO) << "Preparing host package for " << build;
312-
// This function is called asynchronously, so it may take a while to start.
313-
// Complete a phase here to ensure that delay is not counted in the download
314-
// time.
315-
// The download time will still include time spent waiting for the mutex in
316-
// the build_api though.
317-
trace.CompletePhase("Async start delay");
318-
auto host_tools_name = GetFilepath(build).value_or("cvd-host_package.tar.gz");
319-
std::string host_tools_filepath =
320-
CF_EXPECT(build_api.DownloadFile(build, target_dir, host_tools_name));
321-
trace.CompletePhase("Download", FileSize(host_tools_filepath));
322-
323-
CF_EXPECT(
324-
ExtractArchiveContents(host_tools_filepath, target_dir, keep_archives));
325-
trace.CompletePhase("Extract");
326-
309+
Result<void> SubstituteWithFlag(const std::string& target_dir, const std::vector<std::string>& debian_package_executables) {
327310
std::string self_path;
328311
CF_EXPECT(android::base::Readlink("/proc/self/exe", &self_path));
329312
bool is_installed_cvd = self_path == fmt::format("{}/cvd", kInstallDir);
330-
331-
std::string sub_file = target_dir + "/etc/debian_substitution_marker";
332-
if (debian_package_executables.empty() && FileExists(sub_file)) {
333-
std::string sub_file_contents;
334-
CF_EXPECTF(android::base::ReadFileToString(sub_file, &sub_file_contents),
335-
"failed to read '{}'", sub_file);
336-
sub_file_contents = android::base::Trim(sub_file_contents);
337-
debian_package_executables = android::base::Tokenize(sub_file_contents, "\n");
338-
}
339-
340313
std::string runfiles_error;
341314
std::unique_ptr<Runfiles> runfiles;
342315
if (!debian_package_executables.empty() && !is_installed_cvd) {
@@ -375,6 +348,63 @@ Result<void> FetchHostPackage(
375348
CF_EXPECTF(unlink(to_substitute.c_str()) == 0, "{}", strerror(errno));
376349
CF_EXPECT(CreateSymLink(source, to_substitute));
377350
}
351+
return {};
352+
}
353+
354+
Result<void> SubstituteWithMarker(const std::string& target_dir, const std::string& marker_file) {
355+
std::string content;
356+
CF_EXPECTF(android::base::ReadFileToString(marker_file, &content),
357+
"failed to read '{}'", marker_file);
358+
fetch::HostPkgMigrationConfig config;
359+
CF_EXPECT(google::protobuf::TextFormat::ParseFromString(content, &config), "failed parsing debian_substitution_marker file");
360+
for (int j = 0; j < config.symlinks_size(); j++) {
361+
const fetch::Symlink& symlink = config.symlinks(j);
362+
std::string full_link_name =
363+
fmt::format("{}/{}", target_dir, symlink.link_name());
364+
// TODO: schuffelen - relax this check after migration completes
365+
CF_EXPECTF(FileExists(full_link_name),
366+
"Cannot substitute '{}', does not exist", full_link_name);
367+
CF_EXPECTF(unlink(full_link_name.c_str()) == 0, "{}", strerror(errno));
368+
CF_EXPECT(CreateSymLink(symlink.target(), full_link_name));
369+
}
370+
return {};
371+
}
372+
373+
Result<void> FetchHostPackage(
374+
BuildApi& build_api, const Build& build, const std::string& target_dir,
375+
const bool keep_archives,
376+
std::vector<std::string> debian_package_executables,
377+
FetchTracer::Trace trace) {
378+
LOG(INFO) << "Preparing host package for " << build;
379+
// This function is called asynchronously, so it may take a while to start.
380+
// Complete a phase here to ensure that delay is not counted in the download
381+
// time.
382+
// The download time will still include time spent waiting for the mutex in
383+
// the build_api though.
384+
trace.CompletePhase("Async start delay");
385+
auto host_tools_name = GetFilepath(build).value_or("cvd-host_package.tar.gz");
386+
std::string host_tools_filepath =
387+
CF_EXPECT(build_api.DownloadFile(build, target_dir, host_tools_name));
388+
trace.CompletePhase("Download", FileSize(host_tools_filepath));
389+
390+
CF_EXPECT(
391+
ExtractArchiveContents(host_tools_filepath, target_dir, keep_archives));
392+
trace.CompletePhase("Extract");
393+
394+
std::string marker_file = target_dir + "/etc/debian_substitution_marker";
395+
// Use a local debian_substitution_marker file for development purposes.
396+
std::optional<std::string> local_marker_file = StringFromEnv("LOCAL_DEBIAN_SUBSTITUTION_MARKER_FILE");
397+
if (local_marker_file.has_value()) {
398+
marker_file = local_marker_file.value();
399+
CF_EXPECTF(FileExists(marker_file), "local debian substitution marker file does not exist: {}", marker_file);
400+
LOG(INFO) << "using local debian substitution marker file: " << marker_file;
401+
}
402+
403+
if (debian_package_executables.empty() && FileExists(marker_file)) {
404+
CF_EXPECT(SubstituteWithMarker(target_dir, marker_file));
405+
} else {
406+
CF_EXPECT(SubstituteWithFlag(target_dir, debian_package_executables));
407+
}
378408
trace.CompletePhase("Substitute");
379409
return {};
380410
}
@@ -1034,6 +1064,7 @@ std::string GetFetchLogsFileName(const std::string& target_directory) {
10341064
}
10351065

10361066
Result<void> FetchCvdMain(const FetchFlags& flags) {
1067+
GOOGLE_PROTOBUF_VERIFY_VERSION;
10371068
const bool append_subdirectory = ShouldAppendSubdirectory(flags);
10381069
std::vector<Target> targets = GetFetchTargets(flags, append_subdirectory);
10391070
HostToolsTarget host_target = GetHostToolsTarget(flags, append_subdirectory);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (C) 2025 The Android Open Source Project
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
syntax = "proto3";
16+
17+
package fetch;
18+
19+
message HostPkgMigrationConfig {
20+
repeated Symlink symlinks = 1;
21+
}
22+
23+
message Symlink {
24+
string target = 1;
25+
string link_name = 2;
26+
}

0 commit comments

Comments
 (0)