blob: 9a08f2eca029b8c94356870bb844fa41b162afef [file] [log] [blame]
Lei YU01539e72019-07-31 10:57:38 +08001#include "config.h"
2
3#include "item_updater.hpp"
4
5#include <filesystem>
6#include <phosphor-logging/elog-errors.hpp>
7#include <phosphor-logging/log.hpp>
8#include <xyz/openbmc_project/Common/error.hpp>
9
10namespace phosphor
11{
12namespace software
13{
14namespace updater
15{
16namespace server = sdbusplus::xyz::openbmc_project::Software::server;
17namespace fs = std::filesystem;
18
19using namespace sdbusplus::xyz::openbmc_project::Common::Error;
20using namespace phosphor::logging;
21
22void ItemUpdater::createActivation(sdbusplus::message::message& m)
23{
24 using SVersion = server::Version;
25 using VersionPurpose = SVersion::VersionPurpose;
26 namespace msg = sdbusplus::message;
27 namespace variant_ns = msg::variant_ns;
28
29 sdbusplus::message::object_path objPath;
30 std::map<std::string, std::map<std::string, msg::variant<std::string>>>
31 interfaces;
32 m.read(objPath, interfaces);
33
34 std::string path(std::move(objPath));
35 std::string filePath;
36 auto purpose = VersionPurpose::Unknown;
37 std::string version;
38
39 for (const auto& [interfaceName, propertyMap] : interfaces)
40 {
41 if (interfaceName == VERSION_IFACE)
42 {
43 for (const auto& [propertyName, propertyValue] : propertyMap)
44 {
45 if (propertyName == "Purpose")
46 {
47 // Only process the PSU images
48 auto value = SVersion::convertVersionPurposeFromString(
49 variant_ns::get<std::string>(propertyValue));
50
51 if (value == VersionPurpose::PSU)
52 {
53 purpose = value;
54 }
55 }
56 else if (propertyName == "Version")
57 {
58 version = variant_ns::get<std::string>(propertyValue);
59 }
60 }
61 }
62 else if (interfaceName == FILEPATH_IFACE)
63 {
64 const auto& it = propertyMap.find("Path");
65 if (it != propertyMap.end())
66 {
67 filePath = variant_ns::get<std::string>(it->second);
68 }
69 }
70 }
71 if ((filePath.empty()) || (purpose == VersionPurpose::Unknown))
72 {
73 return;
74 }
75
76 // Version id is the last item in the path
77 auto pos = path.rfind("/");
78 if (pos == std::string::npos)
79 {
80 log<level::ERR>("No version id found in object path",
81 entry("OBJPATH=%s", path.c_str()));
82 return;
83 }
84
85 auto versionId = path.substr(pos + 1);
86
87 if (activations.find(versionId) == activations.end())
88 {
89 // Determine the Activation state by processing the given image dir.
90 auto activationState = server::Activation::Activations::Ready;
91
92 fs::path manifestPath(filePath);
93 manifestPath /= MANIFEST_FILE;
94 std::string extendedVersion =
95 (Version::getValue(
96 manifestPath.string(),
97 std::map<std::string, std::string>{{"extended_version", ""}}))
98 .begin()
99 ->second;
100
101 auto activation = createActivationObject(
102 path, versionId, extendedVersion, activationState);
103 activations.emplace(versionId, std::move(activation));
104
105 auto versionPtr =
106 createVersionObject(path, versionId, version, purpose, filePath);
107 versions.emplace(versionId, std::move(versionPtr));
108 }
109 return;
110}
111
112void ItemUpdater::erase(std::string versionId)
113{
114 auto it = versions.find(versionId);
115 if (it == versions.end())
116 {
117 log<level::ERR>(("Error: Failed to find version " + versionId +
118 " in item updater versions map."
119 " Unable to remove.")
120 .c_str());
121 }
122 else
123 {
124 versions.erase(versionId);
125 }
126
127 // Removing entry in activations map
128 auto ita = activations.find(versionId);
129 if (ita == activations.end())
130 {
131 log<level::ERR>(("Error: Failed to find version " + versionId +
132 " in item updater activations map."
133 " Unable to remove.")
134 .c_str());
135 }
136 else
137 {
138 activations.erase(versionId);
139 }
140}
141
142void ItemUpdater::deleteAll()
143{
144 // TODO: when PSU's running firmware is implemented, delete all versions
145 // that are not the running firmware.
146}
147
148std::unique_ptr<Activation> ItemUpdater::createActivationObject(
149 const std::string& path, const std::string& versionId,
150 const std::string& extVersion,
151 sdbusplus::xyz::openbmc_project::Software::server::Activation::Activations
152 activationStatus)
153{
154 return std::make_unique<Activation>(bus, path, versionId, extVersion,
155 activationStatus);
156}
157
158std::unique_ptr<Version> ItemUpdater::createVersionObject(
159 const std::string& objPath, const std::string& versionId,
160 const std::string& versionString,
161 sdbusplus::xyz::openbmc_project::Software::server::Version::VersionPurpose
162 versionPurpose,
163 const std::string& filePath)
164{
165 auto version = std::make_unique<Version>(
166 bus, objPath, versionId, versionString, versionPurpose, filePath,
167 std::bind(&ItemUpdater::erase, this, std::placeholders::_1));
168 return version;
169}
170
171} // namespace updater
172} // namespace software
173} // namespace phosphor