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)); 352ce7da29SGunnar Mills 362ce7da29SGunnar Mills for (const auto& intf : interfaces) 372ce7da29SGunnar Mills { 38705f1bfcSSaqib Khan if (intf.first == VERSION_IFACE) 392ce7da29SGunnar Mills { 402ce7da29SGunnar Mills for (const auto& property : intf.second) 412ce7da29SGunnar Mills { 42705f1bfcSSaqib Khan if (property.first == "Purpose") 432ce7da29SGunnar Mills { 44705f1bfcSSaqib Khan std::string str = sdbusplus::message::variant_ns:: 45705f1bfcSSaqib Khan get<std::string>(property.second); 46705f1bfcSSaqib Khan purpose = server::Version:: 47705f1bfcSSaqib Khan convertVersionPurposeFromString(str); 48705f1bfcSSaqib Khan } 49705f1bfcSSaqib Khan else if (property.first == "Version") 50705f1bfcSSaqib Khan { 51705f1bfcSSaqib Khan version = sdbusplus::message::variant_ns:: 52705f1bfcSSaqib Khan get<std::string>(property.second); 53705f1bfcSSaqib Khan } 54705f1bfcSSaqib Khan } 55705f1bfcSSaqib Khan } 56705f1bfcSSaqib Khan } 57705f1bfcSSaqib Khan if (version.empty() || 58705f1bfcSSaqib Khan (purpose != server::Version::VersionPurpose::BMC && 59705f1bfcSSaqib Khan purpose != server::Version::VersionPurpose::System)) 602ce7da29SGunnar Mills { 61e75d10f5SPatrick Williams return; 622ce7da29SGunnar Mills } 632ce7da29SGunnar Mills 642ce7da29SGunnar Mills // Version id is the last item in the path 652ce7da29SGunnar Mills auto pos = path.rfind("/"); 662ce7da29SGunnar Mills if (pos == std::string::npos) 672ce7da29SGunnar Mills { 682ce7da29SGunnar Mills log<level::ERR>("No version id found in object path", 692ce7da29SGunnar Mills entry("OBJPATH=%s", path)); 70e75d10f5SPatrick Williams return; 712ce7da29SGunnar Mills } 722ce7da29SGunnar Mills 732ce7da29SGunnar Mills auto versionId = path.substr(pos + 1); 742ce7da29SGunnar Mills 75e75d10f5SPatrick Williams if (activations.find(versionId) == activations.end()) 762ce7da29SGunnar Mills { 7735e83f3eSSaqib Khan // Determine the Activation state by processing the given image dir. 7835e83f3eSSaqib Khan auto activationState = server::Activation::Activations::Invalid; 7935e83f3eSSaqib Khan ItemUpdater::ActivationStatus result = ItemUpdater:: 8035e83f3eSSaqib Khan validateSquashFSImage(versionId); 8135e83f3eSSaqib Khan if (result == ItemUpdater::ActivationStatus::ready) 8235e83f3eSSaqib Khan { 8335e83f3eSSaqib Khan activationState = server::Activation::Activations::Ready; 8435e83f3eSSaqib Khan } 8535e83f3eSSaqib Khan else if (result == ItemUpdater::ActivationStatus::active) 8635e83f3eSSaqib Khan { 8735e83f3eSSaqib Khan activationState = server::Activation::Activations::Active; 8835e83f3eSSaqib Khan } 8935e83f3eSSaqib Khan activations.insert(std::make_pair( 902ce7da29SGunnar Mills versionId, 91ec1b41c4SGunnar Mills std::make_unique<Activation>( 9235e83f3eSSaqib Khan bus, 9335e83f3eSSaqib Khan path, 9435e83f3eSSaqib Khan versionId, 9535e83f3eSSaqib Khan activationState))); 96705f1bfcSSaqib Khan versions.insert(std::make_pair( 97705f1bfcSSaqib Khan versionId, 98705f1bfcSSaqib Khan std::make_unique<phosphor::software:: 99705f1bfcSSaqib Khan manager::Version>( 100705f1bfcSSaqib Khan bus, 101705f1bfcSSaqib Khan path, 102705f1bfcSSaqib Khan version, 103705f1bfcSSaqib Khan purpose, 104705f1bfcSSaqib Khan ""))); 1052ce7da29SGunnar Mills } 106e75d10f5SPatrick Williams return; 107ec1b41c4SGunnar Mills } 108ec1b41c4SGunnar Mills 109*ba239881SSaqib Khan void ItemUpdater::processBMCImage() 110*ba239881SSaqib Khan { 111*ba239881SSaqib Khan auto purpose = server::Version::VersionPurpose::BMC; 112*ba239881SSaqib Khan auto version = phosphor::software::manager::Version::getBMCVersion(); 113*ba239881SSaqib Khan auto id = phosphor::software::manager::Version::getId(version); 114*ba239881SSaqib Khan auto path = std::string{SOFTWARE_OBJPATH} + '/' + id; 115*ba239881SSaqib Khan activations.insert(std::make_pair( 116*ba239881SSaqib Khan id, 117*ba239881SSaqib Khan std::make_unique<Activation>( 118*ba239881SSaqib Khan bus, 119*ba239881SSaqib Khan path, 120*ba239881SSaqib Khan id, 121*ba239881SSaqib Khan server::Activation::Activations::Active))); 122*ba239881SSaqib Khan versions.insert(std::make_pair( 123*ba239881SSaqib Khan id, 124*ba239881SSaqib Khan std::make_unique<phosphor::software:: 125*ba239881SSaqib Khan manager::Version>( 126*ba239881SSaqib Khan bus, 127*ba239881SSaqib Khan path, 128*ba239881SSaqib Khan version, 129*ba239881SSaqib Khan purpose, 130*ba239881SSaqib Khan ""))); 131*ba239881SSaqib Khan return; 132*ba239881SSaqib Khan } 133*ba239881SSaqib Khan 13435e83f3eSSaqib Khan ItemUpdater::ActivationStatus ItemUpdater::validateSquashFSImage( 13535e83f3eSSaqib Khan const std::string& versionId) 13635e83f3eSSaqib Khan { 13735e83f3eSSaqib Khan 13835e83f3eSSaqib Khan // TODO openbmc/openbmc#1715 Check the Common.FilePath to 13935e83f3eSSaqib Khan // determine the active image. 14035e83f3eSSaqib Khan fs::path imageDirPath(IMG_UPLOAD_DIR); 14135e83f3eSSaqib Khan imageDirPath /= versionId; 14235e83f3eSSaqib Khan if (!fs::is_directory(imageDirPath)) 14335e83f3eSSaqib Khan { 14435e83f3eSSaqib Khan return ItemUpdater::ActivationStatus::active; 14535e83f3eSSaqib Khan } 14635e83f3eSSaqib Khan 14735e83f3eSSaqib Khan fs::path file(imageDirPath); 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 { 15735e83f3eSSaqib Khan log<level::ERR>("Failed to find the SquashFS 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