download_action.h revision 9d911fa4ed05cb51319636a4b6ce94b0260156ae
149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Copyright (c) 2009 The Chromium OS Authors. All rights reserved. 249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Use of this source code is governed by a BSD-style license that can be 349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// found in the LICENSE file. 449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 5c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_DOWNLOAD_ACTION_H__ 6c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#define CHROMEOS_PLATFORM_UPDATE_ENGINE_DOWNLOAD_ACTION_H__ 749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <sys/types.h> 949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <sys/stat.h> 1049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <fcntl.h> 1149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 1249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <string> 1349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 1449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <curl/curl.h> 1549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 1649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include "base/scoped_ptr.h" 1749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include "update_engine/action.h" 1849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include "update_engine/decompressing_file_writer.h" 19f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes#include "update_engine/delta_performer.h" 2049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include "update_engine/file_writer.h" 2149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include "update_engine/http_fetcher.h" 22c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include "update_engine/install_plan.h" 2349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include "update_engine/omaha_hash_calculator.h" 24f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes#include "update_engine/split_file_writer.h" 2549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 26f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes// The Download Action downloads a specified url to disk. The url should 27f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes// point to either a full or delta update. If a full update, the file will 28f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes// be piped into a SplitFileWriter, which will direct it to the kernel 29f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes// and rootfs partitions. If it's a delta update, the destination kernel 30f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes// and rootfs should already contain the source-version that this delta 31f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes// update goes from. In this case, the update will be piped into a 32f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes// DeltaPerformer that will apply the delta to the disk. 3349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 3449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace chromeos_update_engine { 3549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 3663b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyesclass DownloadActionDelegate { 3763b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes public: 389d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov // Called right before starting the download with |active| set to 399d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov // true. Called after completing the download with |active| set to 409d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov // false. 419d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov virtual void SetDownloadStatus(bool active) = 0; 429d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov 439d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov // Called periodically after bytes are received. This method will be 449d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov // invoked only if the download is active. |bytes_received| is the 459d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov // number of bytes downloaded thus far. |total| is the number of 469d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov // bytes expected. 4763b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes virtual void BytesReceived(uint64_t bytes_received, uint64_t total) = 0; 4863b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes}; 4963b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes 5049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass DownloadAction; 5149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass NoneType; 5249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 5349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comtemplate<> 5449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass ActionTraits<DownloadAction> { 5549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public: 56c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com // Takes and returns an InstallPlan 57c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com typedef InstallPlan InputObjectType; 58c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com typedef InstallPlan OutputObjectType; 5949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}; 6049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 6149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass DownloadAction : public Action<DownloadAction>, 6249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public HttpFetcherDelegate { 6349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public: 6449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Takes ownership of the passed in HttpFetcher. Useful for testing. 6549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // A good calling pattern is: 66c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com // DownloadAction(new WhateverHttpFetcher); 67c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com DownloadAction(HttpFetcher* http_fetcher); 6849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com virtual ~DownloadAction(); 6949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com typedef ActionTraits<DownloadAction>::InputObjectType InputObjectType; 7049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com typedef ActionTraits<DownloadAction>::OutputObjectType OutputObjectType; 7149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com void PerformAction(); 7249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com void TerminateProcessing(); 7349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 74f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes // Testing 75f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes void SetTestFileWriter(FileWriter* writer) { 76f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes writer_ = writer; 77f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes } 78f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes 7949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Debugging/logging 80c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com static std::string StaticType() { return "DownloadAction"; } 81c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com std::string Type() const { return StaticType(); } 8249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 8363b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes // HttpFetcherDelegate methods (see http_fetcher.h) 8449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com virtual void ReceivedBytes(HttpFetcher *fetcher, 8549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com const char* bytes, int length); 8649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com virtual void TransferComplete(HttpFetcher *fetcher, bool successful); 8749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 8863b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes void set_delegate(DownloadActionDelegate* delegate) { 8963b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes delegate_ = delegate; 9063b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes } 9163b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes 9249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com private: 93f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes // The InstallPlan passed in 94f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes InstallPlan install_plan_; 9549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 9649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // The FileWriter that downloaded data should be written to. It will 97f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes // either point to *decompressing_file_writer_ or *delta_performer_. 9849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com FileWriter* writer_; 9949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 100f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes // These are used for full updates: 10149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com scoped_ptr<GzipDecompressingFileWriter> decompressing_file_writer_; 102f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes scoped_ptr<SplitFileWriter> split_file_writer_; 103f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes scoped_ptr<DirectFileWriter> kernel_file_writer_; 104f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes scoped_ptr<DirectFileWriter> rootfs_file_writer_; 10549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 106f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes // Used to apply a delta update: 107f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes scoped_ptr<DeltaPerformer> delta_performer_; 10849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 109f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes // Pointer to the HttpFetcher that does the http work. 11049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com scoped_ptr<HttpFetcher> http_fetcher_; 11149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 11249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com // Used to find the hash of the bytes downloaded 11349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com OmahaHashCalculator omaha_hash_calculator_; 1149d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov 11563b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes // For reporting status to outsiders 11663b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes DownloadActionDelegate* delegate_; 11763b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes uint64_t bytes_received_; 1189d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov 11949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com DISALLOW_COPY_AND_ASSIGN(DownloadAction); 12049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}; 12149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 12249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// We want to be sure that we're compiled with large file support on linux, 12349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// just in case we find ourselves downloading large images. 12449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comCOMPILE_ASSERT(8 == sizeof(off_t), off_t_not_64_bit); 12549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 12649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com} // namespace chromeos_update_engine 12749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com 128c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_DOWNLOAD_ACTION_H__ 129