diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc index 19a399520e9243..af28d040481e7a 100644 --- a/src/main/cpp/blaze.cc +++ b/src/main/cpp/blaze.cc @@ -1007,6 +1007,10 @@ static DurationMillis ExtractData(const string &self_path, << "install base directory '" << install_base << "' could not be created. It exists but is not a directory."; } + // If --trust_install_base is true, we skip the following checks. + if (startup_options.trust_install_base) { + return DurationMillis(); + } blaze_util::Path install_dir(install_base); // Check that all files are present and have timestamps from BlessFiles(). std::unique_ptr mtime( @@ -1486,9 +1490,21 @@ static int GetExitCodeForAbruptExit(const blaze_util::Path &output_base) { return custom_exit_code; } -void PrintVersionInfo(const string &self_path, const string &product_name) { +void PrintVersionInfo(const string &self_path, + const string &product_name, + const StartupOptions &startup_options) { string build_label; - ExtractBuildLabel(self_path, &build_label); + if (startup_options.trust_install_base) { + blaze_util::Path install_base(startup_options.install_base); + string build_label_path = install_base.GetRelative("build-label.txt").AsNativePath(); + if (!blaze_util::ReadFile(build_label_path, &build_label)) { + BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR) + << "Cannot read build-label.txt file from install base: " + << build_label_path; + } + } else { + ExtractBuildLabel(self_path, &build_label); + } printf("%s %s\n", product_name.c_str(), build_label.c_str()); } @@ -1582,11 +1598,6 @@ int Main(int argc, const char *const *argv, WorkspaceLayout *workspace_layout, const string self_path = GetSelfPath(argv[0]); - if (argc == 2 && strcmp(argv[1], "--version") == 0) { - PrintVersionInfo(self_path, option_processor->GetLowercaseProductName()); - return blaze_exit_code::SUCCESS; - } - string cwd = GetCanonicalCwd(); LoggingInfo logging_info(CheckAndGetBinaryPath(cwd, argv[0]), start_time); @@ -1617,11 +1628,23 @@ int Main(int argc, const char *const *argv, WorkspaceLayout *workspace_layout, StartupOptions *startup_options = option_processor->GetParsedStartupOptions(); startup_options->MaybeLogStartupOptionWarnings(); + // Check --install_base is provided when --trust_install_base is enabled + if (startup_options->trust_install_base && startup_options->install_base.empty()) { + BAZEL_DIE(blaze_exit_code::BAD_ARGV) + << "--trust_install_base requires --install_base to be provided"; + } + SetDebugLog(startup_options->client_debug); + // If client_debug was false, this is ignored, so it's accurate. BAZEL_LOG(INFO) << "Debug logging requested, sending all client log " "statements to stderr"; + if (startup_options->version) { + PrintVersionInfo(self_path, option_processor->GetLowercaseProductName(), *startup_options); + return blaze_exit_code::SUCCESS; + } + if (startup_options->unlimit_coredumps) { UnlimitCoredumps(); } @@ -1637,7 +1660,28 @@ int Main(int argc, const char *const *argv, WorkspaceLayout *workspace_layout, vector archive_contents; string install_md5; - DetermineArchiveContents(self_path, &archive_contents, &install_md5); + if (startup_options->trust_install_base) { + blaze_util::Path install_base(startup_options->install_base); + + // Read install_md5 value from /install_base_key + string install_key_path = install_base.GetRelative("install_base_key").AsNativePath(); + if (!blaze_util::ReadFile(install_key_path, &install_md5)) { + BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR) + << "Cannot read install_base_key file from install base: " + << install_key_path; + } + + // Read all archive content entries + blaze_util::GetAllFilesUnder(startup_options->install_base, &archive_contents); + std::size_t pos = install_base.AsNativePath().length() + 1; + for (int i = 0; i < archive_contents.size(); i++) { + blaze_util::Path entry(archive_contents[i]); + archive_contents[i] = entry.AsNativePath().substr(pos); + } + std::sort(archive_contents.begin(), archive_contents.end()); + } else { + DetermineArchiveContents(self_path, &archive_contents, &install_md5); + } UpdateConfiguration(install_md5, workspace, IsServerMode(option_processor->GetCommand()), diff --git a/src/main/cpp/startup_options.cc b/src/main/cpp/startup_options.cc index f9b2fda40180ea..8f23c38093284e 100644 --- a/src/main/cpp/startup_options.cc +++ b/src/main/cpp/startup_options.cc @@ -96,7 +96,9 @@ StartupOptions::StartupOptions(const string &product_name, #endif unlimit_coredumps(false), incompatible_enable_execution_transition(false), - windows_enable_symlinks(false) { + windows_enable_symlinks(false), + version(false), + trust_install_base(false) { if (blaze::IsRunningWithinTest()) { output_root = blaze_util::MakeAbsolute(blaze::GetPathEnv("TEST_TMPDIR")); max_idle_secs = 15; @@ -147,6 +149,10 @@ StartupOptions::StartupOptions(const string &product_name, RegisterNullaryStartupFlag("write_command_log", &write_command_log); RegisterNullaryStartupFlag("windows_enable_symlinks", &windows_enable_symlinks); + RegisterNullaryStartupFlag("version", + &version); + RegisterNullaryStartupFlag("trust_install_base", + &trust_install_base); RegisterUnaryStartupFlag("command_port"); RegisterUnaryStartupFlag("connect_timeout_secs"); RegisterUnaryStartupFlag("digest_function"); diff --git a/src/main/cpp/startup_options.h b/src/main/cpp/startup_options.h index cc9ca667811b72..3a7efc7561fb4e 100644 --- a/src/main/cpp/startup_options.h +++ b/src/main/cpp/startup_options.h @@ -277,6 +277,15 @@ class StartupOptions { // developer mode to be enabled. bool windows_enable_symlinks; + // Whether to print version info and exit. + bool version; + + // Whether to trust the install base directory provided by --install_base + // and skip all the checks. This will allow running the Bazel client without + // appending the zip archive when a install base is available, eg. for Debian + // installation. + bool trust_install_base; + protected: // Constructor for subclasses only so that site-specific extensions of this // class can override the product name. The product_name must be the