blob: 9c94b199c7ffab0e1e58f48bee2791e2ffca1d2f [file] [log] [blame]
Saqib Khan35e83f32017-05-22 11:37:32 -05001#include <fstream>
Gunnar Millsec1b41c2017-05-02 12:20:36 -05002#include <string>
Gunnar Mills2ce7da22017-05-04 15:37:56 -05003#include <phosphor-logging/log.hpp>
Gunnar Millsec1b41c2017-05-02 12:20:36 -05004#include "config.h"
Gunnar Mills2ce7da22017-05-04 15:37:56 -05005#include "item_updater.hpp"
6#include "xyz/openbmc_project/Software/Version/server.hpp"
Saqib Khan35e83f32017-05-22 11:37:32 -05007#include <experimental/filesystem>
Saqib Khan705f1bf2017-06-09 23:58:38 -05008#include "version.hpp"
Gunnar Millsec1b41c2017-05-02 12:20:36 -05009
10namespace phosphor
11{
12namespace software
13{
14namespace updater
15{
16
Gunnar Mills2ce7da22017-05-04 15:37:56 -050017// When you see server:: you know we're referencing our base class
18namespace server = sdbusplus::xyz::openbmc_project::Software::server;
19
20using namespace phosphor::logging;
Saqib Khan35e83f32017-05-22 11:37:32 -050021namespace fs = std::experimental::filesystem;
22
23constexpr auto bmcImage = "image-rofs";
Gunnar Mills2ce7da22017-05-04 15:37:56 -050024
Patrick Williamse75d10f2017-05-30 16:56:32 -050025void ItemUpdater::createActivation(sdbusplus::message::message& msg)
Gunnar Millsec1b41c2017-05-02 12:20:36 -050026{
Saqib Khan84a0e692017-06-28 17:27:01 -050027
28 using SVersion = server::Version;
29 using VersionPurpose = SVersion::VersionPurpose;
30 namespace mesg = sdbusplus::message;
31 namespace variant_ns = mesg::variant_ns;
32
33 mesg::object_path objPath;
34 auto purpose = VersionPurpose::Unknown;
Saqib Khan705f1bf2017-06-09 23:58:38 -050035 std::string version;
Gunnar Mills2ce7da22017-05-04 15:37:56 -050036 std::map<std::string,
Patrick Williamse75d10f2017-05-30 16:56:32 -050037 std::map<std::string,
Saqib Khan84a0e692017-06-28 17:27:01 -050038 mesg::variant<std::string>>> interfaces;
Patrick Williamse75d10f2017-05-30 16:56:32 -050039 msg.read(objPath, interfaces);
Gunnar Mills2ce7da22017-05-04 15:37:56 -050040 std::string path(std::move(objPath));
Saqib Khan19177d32017-06-20 08:11:49 -050041 std::string filePath;
Gunnar Mills2ce7da22017-05-04 15:37:56 -050042
43 for (const auto& intf : interfaces)
44 {
Saqib Khan705f1bf2017-06-09 23:58:38 -050045 if (intf.first == VERSION_IFACE)
Gunnar Mills2ce7da22017-05-04 15:37:56 -050046 {
Saqib Khan705f1bf2017-06-09 23:58:38 -050047 for (const auto& property : intf.second)
Gunnar Mills2ce7da22017-05-04 15:37:56 -050048 {
Saqib Khan705f1bf2017-06-09 23:58:38 -050049 if (property.first == "Purpose")
Gunnar Mills2ce7da22017-05-04 15:37:56 -050050 {
Saqib Khan84a0e692017-06-28 17:27:01 -050051 auto value = SVersion::convertVersionPurposeFromString(
52 variant_ns::get<std::string>(property.second));
53 if (value == VersionPurpose::BMC ||
54 value == VersionPurpose::System)
55 {
56 purpose = value;
57 }
Saqib Khan705f1bf2017-06-09 23:58:38 -050058 }
59 else if (property.first == "Version")
60 {
Saqib Khan84a0e692017-06-28 17:27:01 -050061 version = variant_ns::get<std::string>(property.second);
Gunnar Mills2ce7da22017-05-04 15:37:56 -050062 }
63 }
64 }
Saqib Khan19177d32017-06-20 08:11:49 -050065 else if (intf.first == FILEPATH_IFACE)
66 {
67 for (const auto& property : intf.second)
68 {
69 if (property.first == "Path")
70 {
Saqib Khan84a0e692017-06-28 17:27:01 -050071 filePath = variant_ns::get<std::string>(property.second);
Saqib Khan19177d32017-06-20 08:11:49 -050072 }
73 }
74 }
Gunnar Mills2ce7da22017-05-04 15:37:56 -050075 }
Saqib Khan705f1bf2017-06-09 23:58:38 -050076 if (version.empty() ||
Saqib Khan19177d32017-06-20 08:11:49 -050077 filePath.empty() ||
Saqib Khan84a0e692017-06-28 17:27:01 -050078 purpose == VersionPurpose::Unknown)
Saqib Khan705f1bf2017-06-09 23:58:38 -050079 {
80 return;
81 }
Gunnar Mills2ce7da22017-05-04 15:37:56 -050082
83 // Version id is the last item in the path
84 auto pos = path.rfind("/");
85 if (pos == std::string::npos)
86 {
87 log<level::ERR>("No version id found in object path",
88 entry("OBJPATH=%s", path));
Patrick Williamse75d10f2017-05-30 16:56:32 -050089 return;
Gunnar Mills2ce7da22017-05-04 15:37:56 -050090 }
91
92 auto versionId = path.substr(pos + 1);
93
Patrick Williamse75d10f2017-05-30 16:56:32 -050094 if (activations.find(versionId) == activations.end())
Gunnar Mills2ce7da22017-05-04 15:37:56 -050095 {
Saqib Khan35e83f32017-05-22 11:37:32 -050096 // Determine the Activation state by processing the given image dir.
97 auto activationState = server::Activation::Activations::Invalid;
98 ItemUpdater::ActivationStatus result = ItemUpdater::
Saqib Khan19177d32017-06-20 08:11:49 -050099 validateSquashFSImage(filePath);
Saqib Khan35e83f32017-05-22 11:37:32 -0500100 if (result == ItemUpdater::ActivationStatus::ready)
101 {
102 activationState = server::Activation::Activations::Ready;
103 }
Saqib Khan35e83f32017-05-22 11:37:32 -0500104 activations.insert(std::make_pair(
Saqib Khan705f1bf2017-06-09 23:58:38 -0500105 versionId,
106 std::make_unique<Activation>(
107 bus,
108 path,
Saqib Khan35e83f32017-05-22 11:37:32 -0500109 versionId,
Saqib Khan705f1bf2017-06-09 23:58:38 -0500110 activationState)));
111 versions.insert(std::make_pair(
112 versionId,
113 std::make_unique<phosphor::software::
114 manager::Version>(
115 bus,
116 path,
117 version,
118 purpose,
Saqib Khan19177d32017-06-20 08:11:49 -0500119 filePath)));
Gunnar Mills2ce7da22017-05-04 15:37:56 -0500120 }
Patrick Williamse75d10f2017-05-30 16:56:32 -0500121 return;
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500122}
123
Saqib Khanba239882017-05-26 08:41:54 -0500124void ItemUpdater::processBMCImage()
125{
126 auto purpose = server::Version::VersionPurpose::BMC;
127 auto version = phosphor::software::manager::Version::getBMCVersion();
128 auto id = phosphor::software::manager::Version::getId(version);
129 auto path = std::string{SOFTWARE_OBJPATH} + '/' + id;
130 activations.insert(std::make_pair(
131 id,
132 std::make_unique<Activation>(
133 bus,
134 path,
135 id,
136 server::Activation::Activations::Active)));
137 versions.insert(std::make_pair(
138 id,
139 std::make_unique<phosphor::software::
140 manager::Version>(
141 bus,
142 path,
143 version,
144 purpose,
145 "")));
146 return;
147}
148
Saqib Khan35e83f32017-05-22 11:37:32 -0500149ItemUpdater::ActivationStatus ItemUpdater::validateSquashFSImage(
Saqib Khan19177d32017-06-20 08:11:49 -0500150 const std::string& filePath)
Saqib Khan35e83f32017-05-22 11:37:32 -0500151{
152
Saqib Khan19177d32017-06-20 08:11:49 -0500153 fs::path file(filePath);
Saqib Khan35e83f32017-05-22 11:37:32 -0500154 file /= bmcImage;
155 std::ifstream efile(file.c_str());
156
157 if (efile.good() == 1)
158 {
159 return ItemUpdater::ActivationStatus::ready;
160 }
161 else
162 {
Saqib Khan19177d32017-06-20 08:11:49 -0500163 log<level::ERR>("Failed to find the BMC image.");
Saqib Khan35e83f32017-05-22 11:37:32 -0500164 return ItemUpdater::ActivationStatus::invalid;
165 }
166}
167
Gunnar Millsec1b41c2017-05-02 12:20:36 -0500168} // namespace updater
169} // namespace software
170} // namespace phosphor