AU: Update Downloader to support our image formats.
The downloader used to be dumb in the sense that it would pipe output
to either a DirectFileWriter or a DirectFileWriter via a
GzipDecompressingFileWriter, depending on if we were downloading an
update that was compressed or not. Sadly, things have gotten more
complex: we need to download to two partitions (kernel + rootfs), and
we may stream data via a DeltaPerformer (a type of FileWriter) to the
disk. Thus, the Downloader streams to either
1. gzip decompress->split_writer->direct to disk OR
2. delta performer
Other misc changes: Change FilesystemCopierAction to support
optionally copying the kernel partition rather than root partition.
InstallPlan struct: add an entry for destiation kernel partition.
Test Utils: a new ScopedTempFile class
Utils: support for getting the booted kernel partition device.
BUG=None
TEST=attached unittests
Review URL: http://codereview.chromium.org/1694025
diff --git a/download_action.cc b/download_action.cc
index 6da6719..5387821 100644
--- a/download_action.cc
+++ b/download_action.cc
@@ -13,44 +13,60 @@
namespace chromeos_update_engine {
DownloadAction::DownloadAction(HttpFetcher* http_fetcher)
- : size_(0),
- should_decompress_(false),
- writer_(NULL),
+ : writer_(NULL),
http_fetcher_(http_fetcher) {}
DownloadAction::~DownloadAction() {}
void DownloadAction::PerformAction() {
http_fetcher_->set_delegate(this);
- CHECK(!writer_);
- direct_file_writer_.reset(new DirectFileWriter);
// Get the InstallPlan and read it
CHECK(HasInputObject());
- InstallPlan install_plan(GetInputObject());
+ install_plan_ = GetInputObject();
- should_decompress_ = install_plan.is_full_update;
- url_ = install_plan.download_url;
- output_path_ = install_plan.install_path;
- hash_ = install_plan.download_hash;
- install_plan.Dump();
+ install_plan_.Dump();
- if (should_decompress_) {
- decompressing_file_writer_.reset(
- new GzipDecompressingFileWriter(direct_file_writer_.get()));
- writer_ = decompressing_file_writer_.get();
+ if (writer_) {
+ LOG(INFO) << "Using writer for test.";
} else {
- writer_ = direct_file_writer_.get();
+ if (install_plan_.is_full_update) {
+ kernel_file_writer_.reset(new DirectFileWriter);
+ rootfs_file_writer_.reset(new DirectFileWriter);
+ split_file_writer_.reset(new SplitFileWriter(kernel_file_writer_.get(),
+ rootfs_file_writer_.get()));
+ split_file_writer_->SetFirstOpenArgs(
+ install_plan_.kernel_install_path.c_str(),
+ O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE,
+ 0644);
+ decompressing_file_writer_.reset(
+ new GzipDecompressingFileWriter(split_file_writer_.get()));
+ writer_ = decompressing_file_writer_.get();
+ } else {
+ delta_performer_.reset(new DeltaPerformer);
+ writer_ = delta_performer_.get();
+ }
}
- int rc = writer_->Open(output_path_.c_str(),
- O_TRUNC | O_WRONLY | O_CREAT | O_LARGEFILE, 0644);
+ int rc = writer_->Open(install_plan_.install_path.c_str(),
+ O_TRUNC | O_WRONLY | O_CREAT | O_LARGEFILE,
+ 0644);
if (rc < 0) {
- LOG(ERROR) << "Unable to open output file " << output_path_;
+ LOG(ERROR) << "Unable to open output file " << install_plan_.install_path;
// report error to processor
processor_->ActionComplete(this, false);
return;
}
- http_fetcher_->BeginTransfer(url_);
+ if (!install_plan_.is_full_update) {
+ if (!delta_performer_->OpenKernel(
+ install_plan_.kernel_install_path.c_str())) {
+ LOG(ERROR) << "Unable to open kernel file "
+ << install_plan_.kernel_install_path.c_str();
+ writer_->Close();
+ processor_->ActionComplete(this, false);
+ return;
+ }
+ }
+ http_fetcher_->BeginTransfer(install_plan_.download_url);
}
void DownloadAction::TerminateProcessing() {
@@ -76,9 +92,10 @@
if (successful) {
// Make sure hash is correct
omaha_hash_calculator_.Finalize();
- if (omaha_hash_calculator_.hash() != hash_) {
- LOG(ERROR) << "Download of " << url_ << " failed. Expect hash "
- << hash_ << " but got hash " << omaha_hash_calculator_.hash();
+ if (omaha_hash_calculator_.hash() != install_plan_.download_hash) {
+ LOG(ERROR) << "Download of " << install_plan_.download_url
+ << " failed. Expect hash " << install_plan_.download_hash
+ << " but got hash " << omaha_hash_calculator_.hash();
successful = false;
}
}