omaha_request_params.cc 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. //
  2. // Copyright (C) 2011 The Android Open Source Project
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. #include "update_engine/omaha_request_params.h"
  17. #include <errno.h>
  18. #include <fcntl.h>
  19. #include <sys/utsname.h>
  20. #include <map>
  21. #include <string>
  22. #include <vector>
  23. #include <base/files/file_util.h>
  24. #include <base/strings/string_util.h>
  25. #include <base/strings/stringprintf.h>
  26. #include <brillo/key_value_store.h>
  27. #include <brillo/strings/string_utils.h>
  28. #include <policy/device_policy.h>
  29. #include "update_engine/common/constants.h"
  30. #include "update_engine/common/hardware_interface.h"
  31. #include "update_engine/common/platform_constants.h"
  32. #include "update_engine/common/utils.h"
  33. #include "update_engine/system_state.h"
  34. #define CALL_MEMBER_FN(object, member) ((object).*(member))
  35. using std::map;
  36. using std::string;
  37. using std::vector;
  38. namespace chromeos_update_engine {
  39. const char OmahaRequestParams::kOsVersion[] = "Indy";
  40. const char* kChannelsByStability[] = {
  41. // This list has to be sorted from least stable to most stable channel.
  42. "canary-channel",
  43. "dev-channel",
  44. "beta-channel",
  45. "stable-channel",
  46. };
  47. OmahaRequestParams::~OmahaRequestParams() {
  48. if (!root_.empty())
  49. test::SetImagePropertiesRootPrefix(nullptr);
  50. }
  51. bool OmahaRequestParams::Init(const string& in_app_version,
  52. const string& in_update_url,
  53. bool in_interactive) {
  54. LOG(INFO) << "Initializing parameters for this update attempt";
  55. image_props_ = LoadImageProperties(system_state_);
  56. mutable_image_props_ = LoadMutableImageProperties(system_state_);
  57. // Sanity check the channel names.
  58. if (!IsValidChannel(image_props_.current_channel))
  59. image_props_.current_channel = "stable-channel";
  60. if (!IsValidChannel(mutable_image_props_.target_channel))
  61. mutable_image_props_.target_channel = image_props_.current_channel;
  62. UpdateDownloadChannel();
  63. LOG(INFO) << "Running from channel " << image_props_.current_channel;
  64. os_platform_ = constants::kOmahaPlatformName;
  65. if (!image_props_.system_version.empty()) {
  66. if (in_app_version == "ForcedUpdate") {
  67. image_props_.system_version = in_app_version;
  68. }
  69. os_version_ = image_props_.system_version;
  70. } else {
  71. os_version_ = OmahaRequestParams::kOsVersion;
  72. }
  73. if (!in_app_version.empty())
  74. image_props_.version = in_app_version;
  75. os_sp_ = image_props_.version + "_" + GetMachineType();
  76. app_lang_ = "en-US";
  77. hwid_ = system_state_->hardware()->GetHardwareClass();
  78. if (CollectECFWVersions()) {
  79. fw_version_ = system_state_->hardware()->GetFirmwareVersion();
  80. ec_version_ = system_state_->hardware()->GetECVersion();
  81. }
  82. if (image_props_.current_channel == mutable_image_props_.target_channel) {
  83. // deltas are only okay if the /.nodelta file does not exist. if we don't
  84. // know (i.e. stat() returns some unexpected error), then err on the side of
  85. // caution and say deltas are not okay.
  86. struct stat stbuf;
  87. delta_okay_ =
  88. (stat((root_ + "/.nodelta").c_str(), &stbuf) < 0) && (errno == ENOENT);
  89. } else {
  90. LOG(INFO) << "Disabling deltas as a channel change to "
  91. << mutable_image_props_.target_channel
  92. << " is pending, with is_powerwash_allowed="
  93. << utils::ToString(mutable_image_props_.is_powerwash_allowed);
  94. // For now, disable delta updates if the current channel is different from
  95. // the channel that we're sending to the update server because such updates
  96. // are destined to fail -- the current rootfs hash will be different than
  97. // the expected hash due to the different channel in /etc/lsb-release.
  98. delta_okay_ = false;
  99. }
  100. if (in_update_url.empty())
  101. update_url_ = image_props_.omaha_url;
  102. else
  103. update_url_ = in_update_url;
  104. // Set the interactive flag accordingly.
  105. interactive_ = in_interactive;
  106. dlc_module_ids_.clear();
  107. // Set false so it will do update by default.
  108. is_install_ = false;
  109. return true;
  110. }
  111. bool OmahaRequestParams::IsUpdateUrlOfficial() const {
  112. return (update_url_ == constants::kOmahaDefaultAUTestURL ||
  113. update_url_ == image_props_.omaha_url);
  114. }
  115. bool OmahaRequestParams::CollectECFWVersions() const {
  116. return base::StartsWith(
  117. hwid_, string("PARROT"), base::CompareCase::SENSITIVE) ||
  118. base::StartsWith(
  119. hwid_, string("SPRING"), base::CompareCase::SENSITIVE) ||
  120. base::StartsWith(hwid_, string("SNOW"), base::CompareCase::SENSITIVE);
  121. }
  122. bool OmahaRequestParams::SetTargetChannel(const string& new_target_channel,
  123. bool is_powerwash_allowed,
  124. string* error_message) {
  125. LOG(INFO) << "SetTargetChannel called with " << new_target_channel
  126. << ", Is Powerwash Allowed = "
  127. << utils::ToString(is_powerwash_allowed)
  128. << ". Current channel = " << image_props_.current_channel
  129. << ", existing target channel = "
  130. << mutable_image_props_.target_channel
  131. << ", download channel = " << download_channel_;
  132. if (!IsValidChannel(new_target_channel, error_message)) {
  133. return false;
  134. }
  135. MutableImageProperties new_props;
  136. new_props.target_channel = new_target_channel;
  137. new_props.is_powerwash_allowed = is_powerwash_allowed;
  138. if (!StoreMutableImageProperties(system_state_, new_props)) {
  139. if (error_message)
  140. *error_message = "Error storing the new channel value.";
  141. return false;
  142. }
  143. mutable_image_props_ = new_props;
  144. return true;
  145. }
  146. void OmahaRequestParams::UpdateDownloadChannel() {
  147. if (download_channel_ != mutable_image_props_.target_channel) {
  148. download_channel_ = mutable_image_props_.target_channel;
  149. LOG(INFO) << "Download channel for this attempt = " << download_channel_;
  150. }
  151. }
  152. string OmahaRequestParams::GetMachineType() const {
  153. struct utsname buf;
  154. string ret;
  155. if (uname(&buf) == 0)
  156. ret = buf.machine;
  157. return ret;
  158. }
  159. bool OmahaRequestParams::IsValidChannel(const string& channel,
  160. string* error_message) const {
  161. if (image_props_.allow_arbitrary_channels) {
  162. if (!base::EndsWith(channel, "-channel", base::CompareCase::SENSITIVE)) {
  163. if (error_message) {
  164. *error_message = base::StringPrintf(
  165. "Invalid channel name \"%s\", must ends with -channel.",
  166. channel.c_str());
  167. }
  168. return false;
  169. }
  170. return true;
  171. }
  172. if (GetChannelIndex(channel) < 0) {
  173. string valid_channels = brillo::string_utils::JoinRange(
  174. ", ", std::begin(kChannelsByStability), std::end(kChannelsByStability));
  175. if (error_message) {
  176. *error_message =
  177. base::StringPrintf("Invalid channel name \"%s\", valid names are: %s",
  178. channel.c_str(),
  179. valid_channels.c_str());
  180. }
  181. return false;
  182. }
  183. return true;
  184. }
  185. void OmahaRequestParams::set_root(const string& root) {
  186. root_ = root;
  187. test::SetImagePropertiesRootPrefix(root_.c_str());
  188. }
  189. int OmahaRequestParams::GetChannelIndex(const string& channel) const {
  190. for (size_t t = 0; t < arraysize(kChannelsByStability); ++t)
  191. if (channel == kChannelsByStability[t])
  192. return t;
  193. return -1;
  194. }
  195. bool OmahaRequestParams::ToMoreStableChannel() const {
  196. int current_channel_index = GetChannelIndex(image_props_.current_channel);
  197. int download_channel_index = GetChannelIndex(download_channel_);
  198. return download_channel_index > current_channel_index;
  199. }
  200. bool OmahaRequestParams::ShouldPowerwash() const {
  201. if (!mutable_image_props_.is_powerwash_allowed)
  202. return false;
  203. // If arbitrary channels are allowed, always powerwash on channel change.
  204. if (image_props_.allow_arbitrary_channels)
  205. return image_props_.current_channel != download_channel_;
  206. // Otherwise only powerwash if we are moving from less stable (higher version)
  207. // to more stable channel (lower version).
  208. return ToMoreStableChannel();
  209. }
  210. string OmahaRequestParams::GetAppId() const {
  211. return download_channel_ == "canary-channel" ? image_props_.canary_product_id
  212. : image_props_.product_id;
  213. }
  214. } // namespace chromeos_update_engine