blob: 91f478b644b096e4d2aa95f351d1abf61f913914 [file] [log] [blame]
Eddie James6d873712017-09-01 11:29:07 -05001#include "config.h"
Gunnar Millsb0ce9962018-09-07 13:39:10 -05002
Gunnar Mills392f2942017-04-12 11:04:37 -05003#include "version.hpp"
4
Gunnar Millsb0ce9962018-09-07 13:39:10 -05005#include "xyz/openbmc_project/Common/error.hpp"
6
7#include <openssl/sha.h>
8
9#include <fstream>
10#include <iostream>
11#include <phosphor-logging/elog-errors.hpp>
12#include <phosphor-logging/log.hpp>
13#include <sstream>
14#include <stdexcept>
15#include <string>
16
Gunnar Mills392f2942017-04-12 11:04:37 -050017namespace phosphor
18{
19namespace software
20{
21namespace manager
22{
23
24using namespace phosphor::logging;
Gunnar Millsaae1b2b2017-10-06 13:42:39 -050025using Argument = xyz::openbmc_project::Common::InvalidArgument;
26using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Gunnar Mills392f2942017-04-12 11:04:37 -050027
Gunnar Millscebd1022017-04-17 16:10:15 -050028std::string Version::getValue(const std::string& manifestFilePath,
29 std::string key)
Gunnar Mills392f2942017-04-12 11:04:37 -050030{
Gunnar Millscebd1022017-04-17 16:10:15 -050031 key = key + "=";
32 auto keySize = key.length();
Gunnar Mills392f2942017-04-12 11:04:37 -050033
34 if (manifestFilePath.empty())
35 {
36 log<level::ERR>("Error MANIFESTFilePath is empty");
Gunnar Millsaae1b2b2017-10-06 13:42:39 -050037 elog<InvalidArgument>(
Adriana Kobylak2285fe02018-02-27 15:36:59 -060038 Argument::ARGUMENT_NAME("manifestFilePath"),
39 Argument::ARGUMENT_VALUE(manifestFilePath.c_str()));
Gunnar Mills392f2942017-04-12 11:04:37 -050040 }
41
Gunnar Millscebd1022017-04-17 16:10:15 -050042 std::string value{};
Gunnar Mills392f2942017-04-12 11:04:37 -050043 std::ifstream efile;
44 std::string line;
Adriana Kobylak2285fe02018-02-27 15:36:59 -060045 efile.exceptions(std::ifstream::failbit | std::ifstream::badbit |
Gunnar Millsaae1b2b2017-10-06 13:42:39 -050046 std::ifstream::eofbit);
Gunnar Mills392f2942017-04-12 11:04:37 -050047
48 // Too many GCC bugs (53984, 66145) to do this the right way...
49 try
50 {
51 efile.open(manifestFilePath);
52 while (getline(efile, line))
53 {
Lei YU5a7363b2019-10-18 16:50:59 +080054 if (!line.empty() && line.back() == '\r')
55 {
56 // If the manifest has CRLF line terminators, e.g. is created on
57 // Windows, the line will contain \r at the end, remove it.
58 line.pop_back();
59 }
Gunnar Millscebd1022017-04-17 16:10:15 -050060 if (line.compare(0, keySize, key) == 0)
Gunnar Mills392f2942017-04-12 11:04:37 -050061 {
Gunnar Millscebd1022017-04-17 16:10:15 -050062 value = line.substr(keySize);
Gunnar Mills392f2942017-04-12 11:04:37 -050063 break;
64 }
65 }
66 efile.close();
67 }
68 catch (const std::exception& e)
69 {
Gunnar Millscebd1022017-04-17 16:10:15 -050070 log<level::ERR>("Error in reading MANIFEST file");
Gunnar Mills392f2942017-04-12 11:04:37 -050071 }
72
Gunnar Millscebd1022017-04-17 16:10:15 -050073 return value;
Gunnar Mills392f2942017-04-12 11:04:37 -050074}
75
76std::string Version::getId(const std::string& version)
77{
Gunnar Mills392f2942017-04-12 11:04:37 -050078
79 if (version.empty())
80 {
Gunnar Millscebd1022017-04-17 16:10:15 -050081 log<level::ERR>("Error version is empty");
Gunnar Millsaae1b2b2017-10-06 13:42:39 -050082 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Version"),
83 Argument::ARGUMENT_VALUE(version.c_str()));
Gunnar Mills392f2942017-04-12 11:04:37 -050084 }
85
Saqib Khan26a960d2017-09-19 14:23:28 -050086 unsigned char digest[SHA512_DIGEST_LENGTH];
87 SHA512_CTX ctx;
88 SHA512_Init(&ctx);
89 SHA512_Update(&ctx, version.c_str(), strlen(version.c_str()));
90 SHA512_Final(digest, &ctx);
Adriana Kobylak2285fe02018-02-27 15:36:59 -060091 char mdString[SHA512_DIGEST_LENGTH * 2 + 1];
Saqib Khan26a960d2017-09-19 14:23:28 -050092 for (int i = 0; i < SHA512_DIGEST_LENGTH; i++)
93 {
Adriana Kobylak2285fe02018-02-27 15:36:59 -060094 snprintf(&mdString[i * 2], 3, "%02x", (unsigned int)digest[i]);
Saqib Khan26a960d2017-09-19 14:23:28 -050095 }
96
97 // Only need 8 hex digits.
98 std::string hexId = std::string(mdString);
99 return (hexId.substr(0, 8));
Gunnar Mills392f2942017-04-12 11:04:37 -0500100}
101
Vijay Khemkab7c062e2019-09-18 17:15:57 -0700102std::string Version::getBMCMachine(const std::string& releaseFilePath)
103{
104 std::string machineKey = "OPENBMC_TARGET_MACHINE=";
105 std::string machine{};
106 std::ifstream efile(releaseFilePath);
107 std::string line;
108
109 while (getline(efile, line))
110 {
111 if (line.substr(0, machineKey.size()).find(machineKey) !=
112 std::string::npos)
113 {
114 std::size_t pos = line.find_first_of('"') + 1;
115 machine = line.substr(pos, line.find_last_of('"') - pos);
116 break;
117 }
118 }
119
120 if (machine.empty())
121 {
122 log<level::ERR>("Unable to find OPENBMC_TARGET_MACHINE");
123 elog<InternalFailure>();
124 }
125
126 return machine;
127}
128
Saqib Khan1eef62d2017-08-10 15:29:34 -0500129std::string Version::getBMCVersion(const std::string& releaseFilePath)
Saqib Khanba239882017-05-26 08:41:54 -0500130{
131 std::string versionKey = "VERSION_ID=";
132 std::string version{};
133 std::ifstream efile;
134 std::string line;
Saqib Khan1eef62d2017-08-10 15:29:34 -0500135 efile.open(releaseFilePath);
Saqib Khanba239882017-05-26 08:41:54 -0500136
137 while (getline(efile, line))
138 {
139 if (line.substr(0, versionKey.size()).find(versionKey) !=
140 std::string::npos)
141 {
142 std::size_t pos = line.find_first_of('"') + 1;
143 version = line.substr(pos, line.find_last_of('"') - pos);
144 break;
145 }
146 }
147 efile.close();
148
149 if (version.empty())
150 {
151 log<level::ERR>("Error BMC current version is empty");
Gunnar Millsaae1b2b2017-10-06 13:42:39 -0500152 elog<InternalFailure>();
Saqib Khanba239882017-05-26 08:41:54 -0500153 }
154
155 return version;
156}
157
Eddie James6d873712017-09-01 11:29:07 -0500158bool Version::isFunctional()
159{
160 return versionStr == getBMCVersion(OS_RELEASE_FILE);
161}
162
Saqib Khanee13e832017-10-23 12:53:11 -0500163void Delete::delete_()
164{
165 if (parent.eraseCallback)
166 {
167 parent.eraseCallback(parent.getId(parent.version()));
168 }
169}
170
Gunnar Mills392f2942017-04-12 11:04:37 -0500171} // namespace manager
172} // namespace software
Gunnar Millsfa34e022018-09-04 10:05:45 -0500173} // namespace phosphor