Support extracting into arbitrary directories.
Only supports creating the last directory in the given path if it does
not already exist.
Bug: 137304531
Test: ./fetch_cvd -directory=cuttlefish_assembly
Change-Id: Icf7096a3434a6f93001d71e8f5800d297da36d3c
diff --git a/common/libs/utils/files.cpp b/common/libs/utils/files.cpp
index 1ba9b8d..3d0ba06 100644
--- a/common/libs/utils/files.cpp
+++ b/common/libs/utils/files.cpp
@@ -88,4 +88,11 @@
return remove(file.c_str()) == 0;
}
+std::string CurrentDirectory() {
+ char* path = getcwd(nullptr, 0);
+ std::string ret(path);
+ free(path);
+ return ret;
+}
+
} // namespace cvd
diff --git a/common/libs/utils/files.h b/common/libs/utils/files.h
index ff761db..d42edc5 100644
--- a/common/libs/utils/files.h
+++ b/common/libs/utils/files.h
@@ -32,4 +32,6 @@
// argument.
// path must not contain ~
std::string AbsolutePath(const std::string& path);
+
+std::string CurrentDirectory();
} // namespace cvd
diff --git a/host/commands/fetcher/main.cc b/host/commands/fetcher/main.cc
index f675118..7b460e3 100644
--- a/host/commands/fetcher/main.cc
+++ b/host/commands/fetcher/main.cc
@@ -21,6 +21,7 @@
#include "gflags/gflags.h"
#include <glog/logging.h>
+#include "common/libs/utils/files.h"
#include "common/libs/utils/subprocess.h"
#include "build_api.h"
@@ -31,8 +32,12 @@
DEFINE_string(branch, "aosp-master", "Branch when build_id=\"latest\"");
DEFINE_string(target, "aosp_cf_x86_phone-userdebug", "Build target");
DEFINE_string(credential_source, "", "Build API credential source");
-DEFINE_string(system_image_build_target, "", "Alternate target for the system image");
-DEFINE_string(system_image_build_id, "", "Alternate build for the system image");
+DEFINE_string(system_image_build_target, "", "Alternate target for the system "
+ "image");
+DEFINE_string(system_image_build_id, "", "Alternate build for the system "
+ "image");
+DEFINE_string(directory, cvd::CurrentDirectory(), "Target directory to fetch "
+ "files into");
namespace {
@@ -50,6 +55,7 @@
bool download_images(BuildApi* build_api, const std::string& target,
const std::string& build_id,
+ const std::string& target_directory,
const std::vector<std::string>& images) {
std::string img_zip_name = target_image_zip(target, build_id);
auto artifacts = build_api->Artifacts(build_id, target, "latest");
@@ -62,33 +68,37 @@
<< " did not have " << img_zip_name;
return false;
}
+ std::string local_path = target_directory + "/" + img_zip_name;
build_api->ArtifactToFile(build_id, target, "latest",
- img_zip_name, img_zip_name);
+ img_zip_name, local_path);
// -o for "overwrite"
- std::vector<std::string> command = {"/usr/bin/unzip", "-o", img_zip_name};
+ std::vector<std::string> command = {"/usr/bin/unzip", "-o", local_path,
+ "-d", target_directory};
for (const auto& image_file : images) {
command.push_back(image_file);
}
int result = cvd::execute(command);
if (result != 0) {
- LOG(ERROR) << "Could not extract " << img_zip_name << "; ran command";
+ LOG(ERROR) << "Could not extract " << local_path << "; ran command";
for (const auto& argument : command) {
LOG(ERROR) << argument;
}
return false;
}
- if (unlink(img_zip_name.c_str()) != 0) {
- LOG(ERROR) << "Could not delete " << img_zip_name;
+ if (unlink(local_path.c_str()) != 0) {
+ LOG(ERROR) << "Could not delete " << local_path;
}
return true;
}
bool download_images(BuildApi* build_api, const std::string& target,
- const std::string& build_id) {
- return download_images(build_api, target, build_id, {});
+ const std::string& build_id,
+ const std::string& target_directory) {
+ return download_images(build_api, target, build_id, target_directory, {});
}
bool download_host_package(BuildApi* build_api, const std::string& target,
- const std::string& build_id) {
+ const std::string& build_id,
+ const std::string& target_directory) {
auto artifacts = build_api->Artifacts(build_id, target, "latest");
bool has_host_package = false;
for (const auto& artifact : artifacts) {
@@ -99,14 +109,14 @@
<< " did not have " << HOST_TOOLS;
return false;
}
- build_api->ArtifactToFile(build_id, target, "latest",
- HOST_TOOLS, HOST_TOOLS);
- if (cvd::execute({"/bin/tar", "xvf", HOST_TOOLS}) != 0) {
- LOG(FATAL) << "Could not extract " << HOST_TOOLS;
+ std::string local_path = target_directory + "/" + HOST_TOOLS;
+ build_api->ArtifactToFile(build_id, target, "latest", HOST_TOOLS, local_path);
+ if (cvd::execute({"/bin/tar", "xvf", local_path, "-C", target_directory}) != 0) {
+ LOG(FATAL) << "Could not extract " << local_path;
return false;
}
if (unlink(HOST_TOOLS.c_str()) != 0) {
- LOG(ERROR) << "Could not delete " << HOST_TOOLS;
+ LOG(ERROR) << "Could not delete " << local_path;
}
return true;
}
@@ -117,6 +127,11 @@
::android::base::InitLogging(argv, android::base::StderrLogger);
gflags::ParseCommandLineFlags(&argc, &argv, true);
+ std::string target_dir = cvd::AbsolutePath(FLAGS_directory);
+ if (!cvd::DirectoryExists(target_dir) && mkdir(target_dir.c_str(), 0777) != 0) {
+ LOG(FATAL) << "Could not create " << target_dir;
+ }
+
curl_global_init(CURL_GLOBAL_DEFAULT);
{
std::unique_ptr<CredentialSource> credential_source;
@@ -131,11 +146,12 @@
build_id = build_api.LatestBuildId(FLAGS_branch, FLAGS_target);
}
- if (!download_host_package(&build_api, FLAGS_target, build_id)) {
+ if (!download_host_package(&build_api, FLAGS_target, build_id,
+ target_dir)) {
LOG(FATAL) << "Could not download host package with target "
<< FLAGS_target << " and build id " << build_id;
}
- if (!download_images(&build_api, FLAGS_target, build_id)) {
+ if (!download_images(&build_api, FLAGS_target, build_id, target_dir)) {
LOG(FATAL) << "Could not download images with target "
<< FLAGS_target << " and build id " << build_id;
}
@@ -143,7 +159,8 @@
std::string system_target = FLAGS_system_image_build_target == ""
? FLAGS_target
: FLAGS_system_image_build_target;
- if (!download_images(&build_api, system_target, FLAGS_system_image_build_id, {"system.img"})) {
+ if (!download_images(&build_api, system_target, FLAGS_system_image_build_id,
+ target_dir, {"system.img"})) {
LOG(FATAL) << "Could not download system image at target "
<< FLAGS_target << " and build id " << FLAGS_system_image_build_id;
}