blob: 74e149f33c76dc52219d99db209382870ad34e96 [file] [log] [blame]
Darin Petkov73058b42010-10-06 16:32:19 -07001// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
adlr@google.com3defe6a2009-12-04 20:57:17 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "update_engine/omaha_response_handler_action.h"
Darin Petkov73058b42010-10-06 16:32:19 -07006
adlr@google.com3defe6a2009-12-04 20:57:17 +00007#include <string>
Darin Petkov73058b42010-10-06 16:32:19 -07008
9#include <base/logging.h>
10
Darin Petkov0406e402010-10-06 21:33:11 -070011#include "update_engine/delta_performer.h"
Darin Petkov73058b42010-10-06 16:32:19 -070012#include "update_engine/prefs_interface.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000013#include "update_engine/utils.h"
14
15using std::string;
16
17namespace chromeos_update_engine {
18
Darin Petkov6c118642010-10-21 12:06:30 -070019const char OmahaResponseHandlerAction::kDeadlineFile[] =
20 "/tmp/update-check-response-deadline";
21
Darin Petkovabc7bc02011-02-23 14:39:43 -080022OmahaResponseHandlerAction::OmahaResponseHandlerAction(PrefsInterface* prefs)
23 : prefs_(prefs),
24 got_no_update_response_(false),
25 key_path_(DeltaPerformer::kUpdatePayloadPublicKeyPath) {}
26
adlr@google.com3defe6a2009-12-04 20:57:17 +000027void OmahaResponseHandlerAction::PerformAction() {
28 CHECK(HasInputObject());
29 ScopedActionCompleter completer(processor_, this);
Darin Petkov6a5b3222010-07-13 14:55:28 -070030 const OmahaResponse& response = GetInputObject();
adlr@google.com3defe6a2009-12-04 20:57:17 +000031 if (!response.update_exists) {
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080032 got_no_update_response_ = true;
adlr@google.com3defe6a2009-12-04 20:57:17 +000033 LOG(INFO) << "There are no updates. Aborting.";
34 return;
35 }
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070036 install_plan_.download_url = response.codebase;
37 install_plan_.size = response.size;
38 install_plan_.download_hash = response.hash;
Darin Petkov0406e402010-10-06 21:33:11 -070039
40 install_plan_.is_resume =
41 DeltaPerformer::CanResumeUpdate(prefs_, response.hash);
42 if (!install_plan_.is_resume) {
Darin Petkov9b230572010-10-08 10:20:09 -070043 LOG_IF(WARNING, !DeltaPerformer::ResetUpdateProgress(prefs_, false))
Darin Petkov0406e402010-10-06 21:33:11 -070044 << "Unable to reset the update progress.";
45 LOG_IF(WARNING, !prefs_->SetString(kPrefsUpdateCheckResponseHash,
46 response.hash))
47 << "Unable to save the update check response hash.";
48 }
49
adlr@google.com3defe6a2009-12-04 20:57:17 +000050 TEST_AND_RETURN(GetInstallDev(
51 (!boot_device_.empty() ? boot_device_ : utils::BootDevice()),
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070052 &install_plan_.install_path));
53 install_plan_.kernel_install_path =
54 utils::BootKernelDevice(install_plan_.install_path);
adlr@google.com3defe6a2009-12-04 20:57:17 +000055
Andrew de los Reyes3270f742010-07-15 22:28:14 -070056 install_plan_.is_full_update = !response.is_delta;
Darin Petkovabc7bc02011-02-23 14:39:43 -080057 if (!response.is_delta && utils::FileExists(key_path_.c_str())) {
58 // Can't sign old style full payloads but signature is required so bail out.
59 completer.set_code(kActionCodeSignedDeltaPayloadExpectedError);
60 return;
61 }
adlr@google.com3defe6a2009-12-04 20:57:17 +000062
Andrew de los Reyesf98bff82010-05-06 13:33:25 -070063 TEST_AND_RETURN(HasOutputPipe());
adlr@google.com3defe6a2009-12-04 20:57:17 +000064 if (HasOutputPipe())
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070065 SetOutputObject(install_plan_);
adlr@google.com3defe6a2009-12-04 20:57:17 +000066 LOG(INFO) << "Using this install plan:";
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070067 install_plan_.Dump();
Darin Petkov6a5b3222010-07-13 14:55:28 -070068
Darin Petkov6c118642010-10-21 12:06:30 -070069 // Send the deadline data (if any) to Chrome through a file. This is a pretty
70 // hacky solution but should be OK for now.
71 //
72 // TODO(petkov): Rearchitect this to avoid communication through a
73 // file. Ideallly, we would include this information in D-Bus's GetStatus
74 // method and UpdateStatus signal. A potential issue is that update_engine may
75 // be unresponsive during an update download.
76 utils::WriteFile(kDeadlineFile,
77 response.deadline.data(),
78 response.deadline.size());
79 chmod(kDeadlineFile, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
80
Darin Petkovc1a8b422010-07-19 11:34:49 -070081 completer.set_code(kActionCodeSuccess);
adlr@google.com3defe6a2009-12-04 20:57:17 +000082}
83
84bool OmahaResponseHandlerAction::GetInstallDev(const std::string& boot_dev,
85 std::string* install_dev) {
Andrew de los Reyesf98bff82010-05-06 13:33:25 -070086 TEST_AND_RETURN_FALSE(utils::StringHasPrefix(boot_dev, "/dev/"));
adlr@google.com3defe6a2009-12-04 20:57:17 +000087 string ret(boot_dev);
Andrew de los Reyesf98bff82010-05-06 13:33:25 -070088 string::reverse_iterator it = ret.rbegin(); // last character in string
89 // Right now, we just switch '3' and '5' partition numbers.
90 TEST_AND_RETURN_FALSE((*it == '3') || (*it == '5'));
91 *it = (*it == '3') ? '5' : '3';
adlr@google.com3defe6a2009-12-04 20:57:17 +000092 *install_dev = ret;
93 return true;
94}
95
96} // namespace chromeos_update_engine