blob: 724ffea9e2458f835673752603d92df83b71e960 [file] [log] [blame]
Gunnar Mills392f2942017-04-12 11:04:37 -05001#include <iostream>
2#include <string>
3#include <sstream>
4#include <fstream>
5#include <stdexcept>
Gunnar Millsaae1b2b2017-10-06 13:42:39 -05006#include <openssl/sha.h>
Gunnar Mills392f2942017-04-12 11:04:37 -05007#include <phosphor-logging/log.hpp>
Gunnar Millsaae1b2b2017-10-06 13:42:39 -05008#include <phosphor-logging/elog-errors.hpp>
9#include "xyz/openbmc_project/Common/error.hpp"
Eddie James6d873712017-09-01 11:29:07 -050010#include "config.h"
Gunnar Mills392f2942017-04-12 11:04:37 -050011#include "version.hpp"
12
13namespace phosphor
14{
15namespace software
16{
17namespace manager
18{
19
20using namespace phosphor::logging;
Gunnar Millsaae1b2b2017-10-06 13:42:39 -050021using Argument = xyz::openbmc_project::Common::InvalidArgument;
22using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Gunnar Mills392f2942017-04-12 11:04:37 -050023
Gunnar Millscebd1022017-04-17 16:10:15 -050024std::string Version::getValue(const std::string& manifestFilePath,
25 std::string key)
Gunnar Mills392f2942017-04-12 11:04:37 -050026{
Gunnar Millscebd1022017-04-17 16:10:15 -050027 key = key + "=";
28 auto keySize = key.length();
Gunnar Mills392f2942017-04-12 11:04:37 -050029
30 if (manifestFilePath.empty())
31 {
32 log<level::ERR>("Error MANIFESTFilePath is empty");
Gunnar Millsaae1b2b2017-10-06 13:42:39 -050033 elog<InvalidArgument>(
34 Argument::ARGUMENT_NAME("manifestFilePath"),
35 Argument::ARGUMENT_VALUE(manifestFilePath.c_str()));
Gunnar Mills392f2942017-04-12 11:04:37 -050036 }
37
Gunnar Millscebd1022017-04-17 16:10:15 -050038 std::string value{};
Gunnar Mills392f2942017-04-12 11:04:37 -050039 std::ifstream efile;
40 std::string line;
Gunnar Millsaae1b2b2017-10-06 13:42:39 -050041 efile.exceptions(std::ifstream::failbit |
42 std::ifstream::badbit |
43 std::ifstream::eofbit);
Gunnar Mills392f2942017-04-12 11:04:37 -050044
45 // Too many GCC bugs (53984, 66145) to do this the right way...
46 try
47 {
48 efile.open(manifestFilePath);
49 while (getline(efile, line))
50 {
Gunnar Millscebd1022017-04-17 16:10:15 -050051 if (line.compare(0, keySize, key) == 0)
Gunnar Mills392f2942017-04-12 11:04:37 -050052 {
Gunnar Millscebd1022017-04-17 16:10:15 -050053 value = line.substr(keySize);
Gunnar Mills392f2942017-04-12 11:04:37 -050054 break;
55 }
56 }
57 efile.close();
58 }
59 catch (const std::exception& e)
60 {
Gunnar Millscebd1022017-04-17 16:10:15 -050061 log<level::ERR>("Error in reading MANIFEST file");
Gunnar Mills392f2942017-04-12 11:04:37 -050062 }
63
Gunnar Millscebd1022017-04-17 16:10:15 -050064 return value;
Gunnar Mills392f2942017-04-12 11:04:37 -050065}
66
67std::string Version::getId(const std::string& version)
68{
Gunnar Mills392f2942017-04-12 11:04:37 -050069
70 if (version.empty())
71 {
Gunnar Millscebd1022017-04-17 16:10:15 -050072 log<level::ERR>("Error version is empty");
Gunnar Millsaae1b2b2017-10-06 13:42:39 -050073 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Version"),
74 Argument::ARGUMENT_VALUE(version.c_str()));
Gunnar Mills392f2942017-04-12 11:04:37 -050075 }
76
Saqib Khan26a960d2017-09-19 14:23:28 -050077 unsigned char digest[SHA512_DIGEST_LENGTH];
78 SHA512_CTX ctx;
79 SHA512_Init(&ctx);
80 SHA512_Update(&ctx, version.c_str(), strlen(version.c_str()));
81 SHA512_Final(digest, &ctx);
82 char mdString[SHA512_DIGEST_LENGTH*2+1];
83 for (int i = 0; i < SHA512_DIGEST_LENGTH; i++)
84 {
85 snprintf(&mdString[i*2], 3, "%02x", (unsigned int)digest[i]);
86 }
87
88 // Only need 8 hex digits.
89 std::string hexId = std::string(mdString);
90 return (hexId.substr(0, 8));
Gunnar Mills392f2942017-04-12 11:04:37 -050091}
92
Saqib Khan1eef62d2017-08-10 15:29:34 -050093std::string Version::getBMCVersion(const std::string& releaseFilePath)
Saqib Khanba239882017-05-26 08:41:54 -050094{
95 std::string versionKey = "VERSION_ID=";
96 std::string version{};
97 std::ifstream efile;
98 std::string line;
Saqib Khan1eef62d2017-08-10 15:29:34 -050099 efile.open(releaseFilePath);
Saqib Khanba239882017-05-26 08:41:54 -0500100
101 while (getline(efile, line))
102 {
103 if (line.substr(0, versionKey.size()).find(versionKey) !=
104 std::string::npos)
105 {
106 std::size_t pos = line.find_first_of('"') + 1;
107 version = line.substr(pos, line.find_last_of('"') - pos);
108 break;
109 }
110 }
111 efile.close();
112
113 if (version.empty())
114 {
115 log<level::ERR>("Error BMC current version is empty");
Gunnar Millsaae1b2b2017-10-06 13:42:39 -0500116 elog<InternalFailure>();
Saqib Khanba239882017-05-26 08:41:54 -0500117 }
118
119 return version;
120}
121
Eddie James6d873712017-09-01 11:29:07 -0500122bool Version::isFunctional()
123{
124 return versionStr == getBMCVersion(OS_RELEASE_FILE);
125}
126
Saqib Khanee13e832017-10-23 12:53:11 -0500127void Delete::delete_()
128{
129 if (parent.eraseCallback)
130 {
131 parent.eraseCallback(parent.getId(parent.version()));
132 }
133}
134
Gunnar Mills392f2942017-04-12 11:04:37 -0500135} // namespace manager
136} // namespace software
137} // namepsace phosphor