135e83f3eSSaqib Khan #include <fstream> 2ec1b41c4SGunnar Mills #include <string> 32ce7da29SGunnar Mills #include <phosphor-logging/log.hpp> 4ec1b41c4SGunnar Mills #include "config.h" 52ce7da29SGunnar Mills #include "item_updater.hpp" 62ce7da29SGunnar Mills #include "xyz/openbmc_project/Software/Version/server.hpp" 735e83f3eSSaqib Khan #include <experimental/filesystem> 8705f1bfcSSaqib Khan #include "version.hpp" 9ec1b41c4SGunnar Mills 10ec1b41c4SGunnar Mills namespace phosphor 11ec1b41c4SGunnar Mills { 12ec1b41c4SGunnar Mills namespace software 13ec1b41c4SGunnar Mills { 14ec1b41c4SGunnar Mills namespace updater 15ec1b41c4SGunnar Mills { 16ec1b41c4SGunnar Mills 172ce7da29SGunnar Mills // When you see server:: you know we're referencing our base class 182ce7da29SGunnar Mills namespace server = sdbusplus::xyz::openbmc_project::Software::server; 192ce7da29SGunnar Mills 202ce7da29SGunnar Mills using namespace phosphor::logging; 2135e83f3eSSaqib Khan namespace fs = std::experimental::filesystem; 2235e83f3eSSaqib Khan 2335e83f3eSSaqib Khan constexpr auto bmcImage = "image-rofs"; 242ce7da29SGunnar Mills 25e75d10f5SPatrick Williams void ItemUpdater::createActivation(sdbusplus::message::message& msg) 26ec1b41c4SGunnar Mills { 272ce7da29SGunnar Mills sdbusplus::message::object_path objPath; 28705f1bfcSSaqib Khan auto purpose = server::Version::VersionPurpose::Unknown; 29705f1bfcSSaqib Khan std::string version; 302ce7da29SGunnar Mills std::map<std::string, 312ce7da29SGunnar Mills std::map<std::string, 322ce7da29SGunnar Mills sdbusplus::message::variant<std::string>>> interfaces; 33e75d10f5SPatrick Williams msg.read(objPath, interfaces); 342ce7da29SGunnar Mills std::string path(std::move(objPath)); 35*19177d3eSSaqib Khan std::string filePath; 362ce7da29SGunnar Mills 372ce7da29SGunnar Mills for (const auto& intf : interfaces) 382ce7da29SGunnar Mills { 39705f1bfcSSaqib Khan if (intf.first == VERSION_IFACE) 402ce7da29SGunnar Mills { 412ce7da29SGunnar Mills for (const auto& property : intf.second) 422ce7da29SGunnar Mills { 43705f1bfcSSaqib Khan if (property.first == "Purpose") 442ce7da29SGunnar Mills { 45705f1bfcSSaqib Khan std::string str = sdbusplus::message::variant_ns:: 46705f1bfcSSaqib Khan get<std::string>(property.second); 47705f1bfcSSaqib Khan purpose = server::Version:: 48705f1bfcSSaqib Khan convertVersionPurposeFromString(str); 49705f1bfcSSaqib Khan } 50705f1bfcSSaqib Khan else if (property.first == "Version") 51705f1bfcSSaqib Khan { 52705f1bfcSSaqib Khan version = sdbusplus::message::variant_ns:: 53705f1bfcSSaqib Khan get<std::string>(property.second); 54705f1bfcSSaqib Khan } 55705f1bfcSSaqib Khan } 56705f1bfcSSaqib Khan } 57*19177d3eSSaqib Khan else if (intf.first == FILEPATH_IFACE) 58*19177d3eSSaqib Khan { 59*19177d3eSSaqib Khan for (const auto& property : intf.second) 60*19177d3eSSaqib Khan { 61*19177d3eSSaqib Khan if (property.first == "Path") 62*19177d3eSSaqib Khan { 63*19177d3eSSaqib Khan filePath = sdbusplus::message::variant_ns::get< 64*19177d3eSSaqib Khan std::string>(property.second); 65*19177d3eSSaqib Khan } 66*19177d3eSSaqib Khan } 67*19177d3eSSaqib Khan } 68705f1bfcSSaqib Khan } 69705f1bfcSSaqib Khan if (version.empty() || 70*19177d3eSSaqib Khan filePath.empty() || 71705f1bfcSSaqib Khan (purpose != server::Version::VersionPurpose::BMC && 72705f1bfcSSaqib Khan purpose != server::Version::VersionPurpose::System)) 732ce7da29SGunnar Mills { 74e75d10f5SPatrick Williams return; 752ce7da29SGunnar Mills } 762ce7da29SGunnar Mills 772ce7da29SGunnar Mills // Version id is the last item in the path 782ce7da29SGunnar Mills auto pos = path.rfind("/"); 792ce7da29SGunnar Mills if (pos == std::string::npos) 802ce7da29SGunnar Mills { 812ce7da29SGunnar Mills log<level::ERR>("No version id found in object path", 822ce7da29SGunnar Mills entry("OBJPATH=%s", path)); 83e75d10f5SPatrick Williams return; 842ce7da29SGunnar Mills } 852ce7da29SGunnar Mills 862ce7da29SGunnar Mills auto versionId = path.substr(pos + 1); 872ce7da29SGunnar Mills 88e75d10f5SPatrick Williams if (activations.find(versionId) == activations.end()) 892ce7da29SGunnar Mills { 9035e83f3eSSaqib Khan // Determine the Activation state by processing the given image dir. 9135e83f3eSSaqib Khan auto activationState = server::Activation::Activations::Invalid; 9235e83f3eSSaqib Khan ItemUpdater::ActivationStatus result = ItemUpdater:: 93*19177d3eSSaqib Khan validateSquashFSImage(filePath); 9435e83f3eSSaqib Khan if (result == ItemUpdater::ActivationStatus::ready) 9535e83f3eSSaqib Khan { 9635e83f3eSSaqib Khan activationState = server::Activation::Activations::Ready; 9735e83f3eSSaqib Khan } 9835e83f3eSSaqib Khan activations.insert(std::make_pair( 992ce7da29SGunnar Mills versionId, 100ec1b41c4SGunnar Mills std::make_unique<Activation>( 10135e83f3eSSaqib Khan bus, 10235e83f3eSSaqib Khan path, 10335e83f3eSSaqib Khan versionId, 10435e83f3eSSaqib Khan activationState))); 105705f1bfcSSaqib Khan versions.insert(std::make_pair( 106705f1bfcSSaqib Khan versionId, 107705f1bfcSSaqib Khan std::make_unique<phosphor::software:: 108705f1bfcSSaqib Khan manager::Version>( 109705f1bfcSSaqib Khan bus, 110705f1bfcSSaqib Khan path, 111705f1bfcSSaqib Khan version, 112705f1bfcSSaqib Khan purpose, 113*19177d3eSSaqib Khan filePath))); 1142ce7da29SGunnar Mills } 115e75d10f5SPatrick Williams return; 116ec1b41c4SGunnar Mills } 117ec1b41c4SGunnar Mills 118ba239881SSaqib Khan void ItemUpdater::processBMCImage() 119ba239881SSaqib Khan { 120ba239881SSaqib Khan auto purpose = server::Version::VersionPurpose::BMC; 121ba239881SSaqib Khan auto version = phosphor::software::manager::Version::getBMCVersion(); 122ba239881SSaqib Khan auto id = phosphor::software::manager::Version::getId(version); 123ba239881SSaqib Khan auto path = std::string{SOFTWARE_OBJPATH} + '/' + id; 124ba239881SSaqib Khan activations.insert(std::make_pair( 125ba239881SSaqib Khan id, 126ba239881SSaqib Khan std::make_unique<Activation>( 127ba239881SSaqib Khan bus, 128ba239881SSaqib Khan path, 129ba239881SSaqib Khan id, 130ba239881SSaqib Khan server::Activation::Activations::Active))); 131ba239881SSaqib Khan versions.insert(std::make_pair( 132ba239881SSaqib Khan id, 133ba239881SSaqib Khan std::make_unique<phosphor::software:: 134ba239881SSaqib Khan manager::Version>( 135ba239881SSaqib Khan bus, 136ba239881SSaqib Khan path, 137ba239881SSaqib Khan version, 138ba239881SSaqib Khan purpose, 139ba239881SSaqib Khan ""))); 140ba239881SSaqib Khan return; 141ba239881SSaqib Khan } 142ba239881SSaqib Khan 14335e83f3eSSaqib Khan ItemUpdater::ActivationStatus ItemUpdater::validateSquashFSImage( 144*19177d3eSSaqib Khan const std::string& filePath) 14535e83f3eSSaqib Khan { 14635e83f3eSSaqib Khan 147*19177d3eSSaqib Khan fs::path file(filePath); 14835e83f3eSSaqib Khan file /= bmcImage; 14935e83f3eSSaqib Khan std::ifstream efile(file.c_str()); 15035e83f3eSSaqib Khan 15135e83f3eSSaqib Khan if (efile.good() == 1) 15235e83f3eSSaqib Khan { 15335e83f3eSSaqib Khan return ItemUpdater::ActivationStatus::ready; 15435e83f3eSSaqib Khan } 15535e83f3eSSaqib Khan else 15635e83f3eSSaqib Khan { 157*19177d3eSSaqib Khan log<level::ERR>("Failed to find the BMC image."); 15835e83f3eSSaqib Khan return ItemUpdater::ActivationStatus::invalid; 15935e83f3eSSaqib Khan } 16035e83f3eSSaqib Khan } 16135e83f3eSSaqib Khan 162ec1b41c4SGunnar Mills } // namespace updater 163ec1b41c4SGunnar Mills } // namespace software 164ec1b41c4SGunnar Mills } // namespace phosphor 165