blob: f7471c2c5bf3c744c11a90b2818f3d101519c97e [file] [log] [blame]
Saqib Khan167601b2017-06-18 23:33:46 -05001#include "version.hpp"
Gunnar Millsf6ed5892018-09-07 17:08:02 -05002
Leonel Gonzalez9c8adfa2017-07-12 11:08:40 -05003#include "item_updater.hpp"
Gunnar Millsf6ed5892018-09-07 17:08:02 -05004#include "xyz/openbmc_project/Common/error.hpp"
5
Saqib Khan2308b8b2017-09-19 15:33:06 -05006#include <openssl/sha.h>
Saqib Khan167601b2017-06-18 23:33:46 -05007
Gunnar Millsf6ed5892018-09-07 17:08:02 -05008#include <fstream>
9#include <iostream>
10#include <phosphor-logging/elog-errors.hpp>
11#include <phosphor-logging/log.hpp>
12#include <sstream>
13#include <stdexcept>
14#include <string>
15
Saqib Khan167601b2017-06-18 23:33:46 -050016namespace openpower
17{
18namespace software
19{
20namespace updater
21{
22
23using namespace sdbusplus::xyz::openbmc_project::Common::Error;
24using namespace phosphor::logging;
Gunnar Millsa93a07b2017-09-21 15:40:09 -050025using Argument = xyz::openbmc_project::Common::InvalidArgument;
Saqib Khan167601b2017-06-18 23:33:46 -050026
27std::string Version::getId(const std::string& version)
28{
Saqib Khan167601b2017-06-18 23:33:46 -050029
30 if (version.empty())
31 {
32 log<level::ERR>("Error version is empty");
Lei YU91add6d2019-03-01 14:23:40 +080033 return {};
Saqib Khan167601b2017-06-18 23:33:46 -050034 }
35
Saqib Khan2308b8b2017-09-19 15:33:06 -050036 unsigned char digest[SHA512_DIGEST_LENGTH];
37 SHA512_CTX ctx;
38 SHA512_Init(&ctx);
39 SHA512_Update(&ctx, version.c_str(), strlen(version.c_str()));
40 SHA512_Final(digest, &ctx);
Adriana Kobylak70dcb632018-02-27 15:46:52 -060041 char mdString[SHA512_DIGEST_LENGTH * 2 + 1];
Saqib Khan2308b8b2017-09-19 15:33:06 -050042 for (int i = 0; i < SHA512_DIGEST_LENGTH; i++)
43 {
Adriana Kobylak70dcb632018-02-27 15:46:52 -060044 snprintf(&mdString[i * 2], 3, "%02x", (unsigned int)digest[i]);
Saqib Khan2308b8b2017-09-19 15:33:06 -050045 }
46
47 // Only need 8 hex digits.
48 std::string hexId = std::string(mdString);
49 return (hexId.substr(0, 8));
Saqib Khan167601b2017-06-18 23:33:46 -050050}
51
Adriana Kobylak70dcb632018-02-27 15:46:52 -060052std::map<std::string, std::string>
53 Version::getValue(const std::string& filePath,
54 std::map<std::string, std::string> keys)
Saqib Khan167601b2017-06-18 23:33:46 -050055{
Saqib Khan167601b2017-06-18 23:33:46 -050056 if (filePath.empty())
57 {
58 log<level::ERR>("Error filePath is empty");
Gunnar Millsa93a07b2017-09-21 15:40:09 -050059 elog<InvalidArgument>(Argument::ARGUMENT_NAME("FilePath"),
60 Argument::ARGUMENT_VALUE(filePath.c_str()));
Saqib Khan167601b2017-06-18 23:33:46 -050061 }
62
63 std::ifstream efile;
64 std::string line;
Adriana Kobylak70dcb632018-02-27 15:46:52 -060065 efile.exceptions(std::ifstream::failbit | std::ifstream::badbit |
Gunnar Millsa93a07b2017-09-21 15:40:09 -050066 std::ifstream::eofbit);
Saqib Khan167601b2017-06-18 23:33:46 -050067
68 try
69 {
70 efile.open(filePath);
71 while (getline(efile, line))
72 {
Adriana Kobylak70dcb632018-02-27 15:46:52 -060073 for (auto& key : keys)
Saqib Khan167601b2017-06-18 23:33:46 -050074 {
75 auto value = key.first + "=";
76 auto keySize = value.length();
77 if (line.compare(0, keySize, value) == 0)
78 {
79 key.second = line.substr(keySize);
80 break;
81 }
82 }
83 }
84 efile.close();
85 }
86 catch (const std::exception& e)
87 {
Saqib Khane53222d2017-08-19 16:57:24 -050088 if (!efile.eof())
89 {
90 log<level::ERR>("Error in reading file");
91 }
92 efile.close();
Saqib Khan167601b2017-06-18 23:33:46 -050093 }
94
95 return keys;
96}
97
Lei YUdec8cf92019-02-21 17:47:05 +080098std::pair<std::string, std::string>
99 Version::getVersions(const std::string& versionPart)
100{
101 // versionPart contains strings like below:
102 // open-power-romulus-v2.2-rc1-48-g268344f-dirty
103 // buildroot-2018.11.1-7-g5d7cc8c
104 // skiboot-v6.2
105 std::istringstream iss(versionPart);
106 std::string line;
107 std::string version;
108 std::stringstream ss;
109 std::string extendedVersion;
110
111 if (!std::getline(iss, line))
112 {
113 log<level::ERR>("Unable to read from version",
114 entry("VERSION=%s", versionPart.c_str()));
115 return {};
116 }
117 version = line;
118
119 while (std::getline(iss, line))
120 {
121 // Each line starts with a tab, let's trim it
122 line.erase(line.begin(),
123 std::find_if(line.begin(), line.end(),
124 [](int c) { return !std::isspace(c); }));
125 ss << line << ',';
126 }
127 extendedVersion = ss.str();
128
129 // Erase the last ',', if there is one
130 if (!extendedVersion.empty())
131 {
132 extendedVersion.pop_back();
133 }
134 return {version, extendedVersion};
135}
136
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500137void Delete::delete_()
138{
139 if (parent.eraseCallback)
140 {
141 parent.eraseCallback(parent.getId(parent.version()));
142 }
143}
144
145void Version::updateDeleteInterface(sdbusplus::message::message& msg)
146{
147 std::string interface, chassisState;
Patrick Williams212102e2020-05-13 17:50:50 -0500148 std::map<std::string, std::variant<std::string>> properties;
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500149
150 msg.read(interface, properties);
151
152 for (const auto& p : properties)
153 {
154 if (p.first == "CurrentPowerState")
155 {
Patrick Williams550f31b2020-05-13 11:15:24 -0500156 chassisState = std::get<std::string>(p.second);
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500157 }
158 }
Adriana Kobylak90fdc702018-08-29 09:38:42 -0500159 if (chassisState.empty())
160 {
161 // The chassis power state property did not change, return.
162 return;
163 }
Saqib Khan7f80e0b2017-10-22 11:29:07 -0500164
165 if ((parent.isVersionFunctional(this->versionId)) &&
166 (chassisState != CHASSIS_STATE_OFF))
167 {
168 if (deleteObject)
169 {
170 deleteObject.reset(nullptr);
171 }
172 }
173 else
174 {
175 if (!deleteObject)
176 {
177 deleteObject = std::make_unique<Delete>(bus, objPath, *this);
178 }
179 }
180}
181
Saqib Khan167601b2017-06-18 23:33:46 -0500182} // namespace updater
183} // namespace software
184} // namespace openpower