1856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// 2856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// Copyright (C) 2015 The Android Open Source Project 3856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// 4856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License"); 5856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// you may not use this file except in compliance with the License. 6856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// You may obtain a copy of the License at 7856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// 8856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// http://www.apache.org/licenses/LICENSE-2.0 9856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// 10856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// Unless required by applicable law or agreed to in writing, software 11856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS, 12856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// See the License for the specific language governing permissions and 14856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// limitations under the License. 15856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// 16856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 17856166594771c61973856f563e622ccb7dd48aa1Alex Deymo#include "update_engine/image_properties.h" 18856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 19856166594771c61973856f563e622ccb7dd48aa1Alex Deymo#include <string> 20856166594771c61973856f563e622ccb7dd48aa1Alex Deymo#include <vector> 21856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 22856166594771c61973856f563e622ccb7dd48aa1Alex Deymo#include <base/files/file_util.h> 23856166594771c61973856f563e622ccb7dd48aa1Alex Deymo#include <base/logging.h> 24856166594771c61973856f563e622ccb7dd48aa1Alex Deymo#include <brillo/key_value_store.h> 25856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 2639910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/constants.h" 2739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/hardware_interface.h" 2839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/platform_constants.h" 29afd8cea0060751f969f7d4d20b4c4100ff37626dAmin Hassani#include "update_engine/common/utils.h" 30856166594771c61973856f563e622ccb7dd48aa1Alex Deymo#include "update_engine/system_state.h" 31856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 32856166594771c61973856f563e622ccb7dd48aa1Alex Deymonamespace { 33856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 34856166594771c61973856f563e622ccb7dd48aa1Alex Deymoconst char kLsbRelease[] = "/etc/lsb-release"; 35856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 36856166594771c61973856f563e622ccb7dd48aa1Alex Deymoconst char kLsbReleaseAppIdKey[] = "CHROMEOS_RELEASE_APPID"; 37856166594771c61973856f563e622ccb7dd48aa1Alex Deymoconst char kLsbReleaseAutoUpdateServerKey[] = "CHROMEOS_AUSERVER"; 38856166594771c61973856f563e622ccb7dd48aa1Alex Deymoconst char kLsbReleaseBoardAppIdKey[] = "CHROMEOS_BOARD_APPID"; 39856166594771c61973856f563e622ccb7dd48aa1Alex Deymoconst char kLsbReleaseBoardKey[] = "CHROMEOS_RELEASE_BOARD"; 40856166594771c61973856f563e622ccb7dd48aa1Alex Deymoconst char kLsbReleaseCanaryAppIdKey[] = "CHROMEOS_CANARY_APPID"; 41856166594771c61973856f563e622ccb7dd48aa1Alex Deymoconst char kLsbReleaseIsPowerwashAllowedKey[] = "CHROMEOS_IS_POWERWASH_ALLOWED"; 42856166594771c61973856f563e622ccb7dd48aa1Alex Deymoconst char kLsbReleaseUpdateChannelKey[] = "CHROMEOS_RELEASE_TRACK"; 43856166594771c61973856f563e622ccb7dd48aa1Alex Deymoconst char kLsbReleaseVersionKey[] = "CHROMEOS_RELEASE_VERSION"; 44856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 45856166594771c61973856f563e622ccb7dd48aa1Alex Deymoconst char kDefaultAppId[] = "{87efface-864d-49a5-9bb3-4b050a7c227a}"; 46856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 47856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// A prefix added to the path, used for testing. 483be05c82442b2fbab693b6399f64610e8542462bAlex Deymoconst char* root_prefix = nullptr; 49856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 50856166594771c61973856f563e622ccb7dd48aa1Alex Deymostd::string GetStringWithDefault(const brillo::KeyValueStore& store, 51856166594771c61973856f563e622ccb7dd48aa1Alex Deymo const std::string& key, 52856166594771c61973856f563e622ccb7dd48aa1Alex Deymo const std::string& default_value) { 53856166594771c61973856f563e622ccb7dd48aa1Alex Deymo std::string result; 54856166594771c61973856f563e622ccb7dd48aa1Alex Deymo if (store.GetString(key, &result)) 55856166594771c61973856f563e622ccb7dd48aa1Alex Deymo return result; 56856166594771c61973856f563e622ccb7dd48aa1Alex Deymo LOG(INFO) << "Cannot load ImageProperty " << key << ", using default value " 57856166594771c61973856f563e622ccb7dd48aa1Alex Deymo << default_value; 58856166594771c61973856f563e622ccb7dd48aa1Alex Deymo return default_value; 59856166594771c61973856f563e622ccb7dd48aa1Alex Deymo} 60856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 61856166594771c61973856f563e622ccb7dd48aa1Alex Deymoenum class LsbReleaseSource { 62856166594771c61973856f563e622ccb7dd48aa1Alex Deymo kSystem, 63856166594771c61973856f563e622ccb7dd48aa1Alex Deymo kStateful, 64856166594771c61973856f563e622ccb7dd48aa1Alex Deymo}; 65856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 66856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// Loads the lsb-release properties into the key-value |store| reading the file 67856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// from either the system image or the stateful partition as specified by 68856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// |source|. The loaded values are added to the store, possibly overriding 69856166594771c61973856f563e622ccb7dd48aa1Alex Deymo// existing values. 70856166594771c61973856f563e622ccb7dd48aa1Alex Deymovoid LoadLsbRelease(LsbReleaseSource source, brillo::KeyValueStore* store) { 713be05c82442b2fbab693b6399f64610e8542462bAlex Deymo std::string path; 723be05c82442b2fbab693b6399f64610e8542462bAlex Deymo if (root_prefix) 733be05c82442b2fbab693b6399f64610e8542462bAlex Deymo path = root_prefix; 74856166594771c61973856f563e622ccb7dd48aa1Alex Deymo if (source == LsbReleaseSource::kStateful) 75856166594771c61973856f563e622ccb7dd48aa1Alex Deymo path += chromeos_update_engine::kStatefulPartition; 76856166594771c61973856f563e622ccb7dd48aa1Alex Deymo store->Load(base::FilePath(path + kLsbRelease)); 77856166594771c61973856f563e622ccb7dd48aa1Alex Deymo} 78856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 79856166594771c61973856f563e622ccb7dd48aa1Alex Deymo} // namespace 80856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 81856166594771c61973856f563e622ccb7dd48aa1Alex Deymonamespace chromeos_update_engine { 82856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 83856166594771c61973856f563e622ccb7dd48aa1Alex Deymonamespace test { 84856166594771c61973856f563e622ccb7dd48aa1Alex Deymovoid SetImagePropertiesRootPrefix(const char* test_root_prefix) { 85856166594771c61973856f563e622ccb7dd48aa1Alex Deymo root_prefix = test_root_prefix; 86856166594771c61973856f563e622ccb7dd48aa1Alex Deymo} 87856166594771c61973856f563e622ccb7dd48aa1Alex Deymo} // namespace test 88856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 89856166594771c61973856f563e622ccb7dd48aa1Alex DeymoImageProperties LoadImageProperties(SystemState* system_state) { 90856166594771c61973856f563e622ccb7dd48aa1Alex Deymo ImageProperties result; 91856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 92856166594771c61973856f563e622ccb7dd48aa1Alex Deymo brillo::KeyValueStore lsb_release; 93856166594771c61973856f563e622ccb7dd48aa1Alex Deymo LoadLsbRelease(LsbReleaseSource::kSystem, &lsb_release); 94856166594771c61973856f563e622ccb7dd48aa1Alex Deymo result.current_channel = GetStringWithDefault( 95856166594771c61973856f563e622ccb7dd48aa1Alex Deymo lsb_release, kLsbReleaseUpdateChannelKey, "stable-channel"); 96856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 97856166594771c61973856f563e622ccb7dd48aa1Alex Deymo // In dev-mode and unofficial build we can override the image properties set 98856166594771c61973856f563e622ccb7dd48aa1Alex Deymo // in the system image with the ones from the stateful partition, except the 99856166594771c61973856f563e622ccb7dd48aa1Alex Deymo // channel of the current image. 100856166594771c61973856f563e622ccb7dd48aa1Alex Deymo HardwareInterface* const hardware = system_state->hardware(); 101856166594771c61973856f563e622ccb7dd48aa1Alex Deymo if (!hardware->IsOfficialBuild() || !hardware->IsNormalBootMode()) 102856166594771c61973856f563e622ccb7dd48aa1Alex Deymo LoadLsbRelease(LsbReleaseSource::kStateful, &lsb_release); 103856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 104856166594771c61973856f563e622ccb7dd48aa1Alex Deymo // The release_app_id is used as the default appid, but can be override by 105856166594771c61973856f563e622ccb7dd48aa1Alex Deymo // the board appid in the general case or the canary appid for the canary 106856166594771c61973856f563e622ccb7dd48aa1Alex Deymo // channel only. 107856166594771c61973856f563e622ccb7dd48aa1Alex Deymo std::string release_app_id = 108856166594771c61973856f563e622ccb7dd48aa1Alex Deymo GetStringWithDefault(lsb_release, kLsbReleaseAppIdKey, kDefaultAppId); 109856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 110856166594771c61973856f563e622ccb7dd48aa1Alex Deymo result.product_id = GetStringWithDefault( 111856166594771c61973856f563e622ccb7dd48aa1Alex Deymo lsb_release, kLsbReleaseBoardAppIdKey, release_app_id); 112856166594771c61973856f563e622ccb7dd48aa1Alex Deymo result.canary_product_id = GetStringWithDefault( 113856166594771c61973856f563e622ccb7dd48aa1Alex Deymo lsb_release, kLsbReleaseCanaryAppIdKey, release_app_id); 114856166594771c61973856f563e622ccb7dd48aa1Alex Deymo result.board = GetStringWithDefault(lsb_release, kLsbReleaseBoardKey, ""); 115856166594771c61973856f563e622ccb7dd48aa1Alex Deymo result.version = GetStringWithDefault(lsb_release, kLsbReleaseVersionKey, ""); 116856166594771c61973856f563e622ccb7dd48aa1Alex Deymo result.omaha_url = 117856166594771c61973856f563e622ccb7dd48aa1Alex Deymo GetStringWithDefault(lsb_release, kLsbReleaseAutoUpdateServerKey, 118856166594771c61973856f563e622ccb7dd48aa1Alex Deymo constants::kOmahaDefaultProductionURL); 119ebf6e1228e6e42c19334bb8b3da62f4aef105deaAlex Deymo // Build fingerprint not used in Chrome OS. 120558fe6ad38c6c419a135ce1ed1e3d1152f55ff7cAlex Deymo result.build_fingerprint = ""; 1217f785f584d943308b06596f8d279e9c4b711adb6Sen Jiang result.allow_arbitrary_channels = false; 122856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 123856166594771c61973856f563e622ccb7dd48aa1Alex Deymo return result; 124856166594771c61973856f563e622ccb7dd48aa1Alex Deymo} 125856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 126856166594771c61973856f563e622ccb7dd48aa1Alex DeymoMutableImageProperties LoadMutableImageProperties(SystemState* system_state) { 127856166594771c61973856f563e622ccb7dd48aa1Alex Deymo MutableImageProperties result; 128856166594771c61973856f563e622ccb7dd48aa1Alex Deymo brillo::KeyValueStore lsb_release; 129856166594771c61973856f563e622ccb7dd48aa1Alex Deymo LoadLsbRelease(LsbReleaseSource::kSystem, &lsb_release); 130856166594771c61973856f563e622ccb7dd48aa1Alex Deymo LoadLsbRelease(LsbReleaseSource::kStateful, &lsb_release); 131856166594771c61973856f563e622ccb7dd48aa1Alex Deymo result.target_channel = GetStringWithDefault( 132856166594771c61973856f563e622ccb7dd48aa1Alex Deymo lsb_release, kLsbReleaseUpdateChannelKey, "stable-channel"); 133856166594771c61973856f563e622ccb7dd48aa1Alex Deymo if (!lsb_release.GetBoolean(kLsbReleaseIsPowerwashAllowedKey, 134856166594771c61973856f563e622ccb7dd48aa1Alex Deymo &result.is_powerwash_allowed)) 135856166594771c61973856f563e622ccb7dd48aa1Alex Deymo result.is_powerwash_allowed = false; 136856166594771c61973856f563e622ccb7dd48aa1Alex Deymo return result; 137856166594771c61973856f563e622ccb7dd48aa1Alex Deymo} 138856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 139856166594771c61973856f563e622ccb7dd48aa1Alex Deymobool StoreMutableImageProperties(SystemState* system_state, 140856166594771c61973856f563e622ccb7dd48aa1Alex Deymo const MutableImageProperties& properties) { 141856166594771c61973856f563e622ccb7dd48aa1Alex Deymo brillo::KeyValueStore lsb_release; 142856166594771c61973856f563e622ccb7dd48aa1Alex Deymo LoadLsbRelease(LsbReleaseSource::kStateful, &lsb_release); 143856166594771c61973856f563e622ccb7dd48aa1Alex Deymo lsb_release.SetString(kLsbReleaseUpdateChannelKey, properties.target_channel); 144856166594771c61973856f563e622ccb7dd48aa1Alex Deymo lsb_release.SetBoolean(kLsbReleaseIsPowerwashAllowedKey, 145856166594771c61973856f563e622ccb7dd48aa1Alex Deymo properties.is_powerwash_allowed); 146856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 1475378f5e3d9420521a1afff935ed37b726d42ead6Alex Deymo std::string root_prefix_str = root_prefix ? root_prefix : ""; 1485378f5e3d9420521a1afff935ed37b726d42ead6Alex Deymo base::FilePath path(root_prefix_str + kStatefulPartition + kLsbRelease); 149856166594771c61973856f563e622ccb7dd48aa1Alex Deymo if (!base::DirectoryExists(path.DirName())) 150856166594771c61973856f563e622ccb7dd48aa1Alex Deymo base::CreateDirectory(path.DirName()); 151856166594771c61973856f563e622ccb7dd48aa1Alex Deymo return lsb_release.Save(path); 152856166594771c61973856f563e622ccb7dd48aa1Alex Deymo} 153856166594771c61973856f563e622ccb7dd48aa1Alex Deymo 154afd8cea0060751f969f7d4d20b4c4100ff37626dAmin Hassanivoid LogImageProperties() { 155afd8cea0060751f969f7d4d20b4c4100ff37626dAmin Hassani std::string lsb_release; 156afd8cea0060751f969f7d4d20b4c4100ff37626dAmin Hassani if (utils::ReadFile(kLsbRelease, &lsb_release)) { 157afd8cea0060751f969f7d4d20b4c4100ff37626dAmin Hassani LOG(INFO) << "lsb-release inside the old rootfs:\n" << lsb_release; 158afd8cea0060751f969f7d4d20b4c4100ff37626dAmin Hassani } 159afd8cea0060751f969f7d4d20b4c4100ff37626dAmin Hassani 160afd8cea0060751f969f7d4d20b4c4100ff37626dAmin Hassani std::string stateful_lsb_release; 161afd8cea0060751f969f7d4d20b4c4100ff37626dAmin Hassani if (utils::ReadFile(std::string(kStatefulPartition) + kLsbRelease, 162afd8cea0060751f969f7d4d20b4c4100ff37626dAmin Hassani &stateful_lsb_release)) { 163afd8cea0060751f969f7d4d20b4c4100ff37626dAmin Hassani LOG(INFO) << "stateful lsb-release:\n" << stateful_lsb_release; 164afd8cea0060751f969f7d4d20b4c4100ff37626dAmin Hassani } 165afd8cea0060751f969f7d4d20b4c4100ff37626dAmin Hassani} 166afd8cea0060751f969f7d4d20b4c4100ff37626dAmin Hassani 167856166594771c61973856f563e622ccb7dd48aa1Alex Deymo} // namespace chromeos_update_engine 168