blob: d578281b6af09227eabce0dbc27930617cbf62fe [file] [log] [blame]
Patrick Williams6a85e8a2021-08-27 08:22:29 -05001#include "config.h"
2
3#include "msl_verify.hpp"
4
5#include "version.hpp"
6
zamiseck10ec9752022-04-27 12:39:50 -05007#include <phosphor-logging/elog-errors.hpp>
8#include <phosphor-logging/elog.hpp>
Patrick Williamsc9bb6422021-08-27 06:18:35 -05009#include <phosphor-logging/lg2.hpp>
zamiseck10ec9752022-04-27 12:39:50 -050010#include <xyz/openbmc_project/Software/Version/error.hpp>
Patrick Williams6a85e8a2021-08-27 08:22:29 -050011
12#include <regex>
13
Patrick Williamsc9bb6422021-08-27 06:18:35 -050014PHOSPHOR_LOG2_USING;
Patrick Williams6a85e8a2021-08-27 08:22:29 -050015
16int minimum_ship_level::compare(const Version& versionToCompare,
17 const Version& mslVersion)
18{
19 if (versionToCompare.major > mslVersion.major)
Pavithra Barithayace9a5c92024-06-25 02:24:07 -050020 {
Patrick Williams6a85e8a2021-08-27 08:22:29 -050021 return (1);
Pavithra Barithayace9a5c92024-06-25 02:24:07 -050022 }
Patrick Williams6a85e8a2021-08-27 08:22:29 -050023 if (versionToCompare.major < mslVersion.major)
Pavithra Barithayace9a5c92024-06-25 02:24:07 -050024 {
Patrick Williams6a85e8a2021-08-27 08:22:29 -050025 return (-1);
Pavithra Barithayace9a5c92024-06-25 02:24:07 -050026 }
Patrick Williams6a85e8a2021-08-27 08:22:29 -050027
28 if (versionToCompare.minor > mslVersion.minor)
Pavithra Barithayace9a5c92024-06-25 02:24:07 -050029 {
Patrick Williams6a85e8a2021-08-27 08:22:29 -050030 return (1);
Pavithra Barithayace9a5c92024-06-25 02:24:07 -050031 }
Patrick Williams6a85e8a2021-08-27 08:22:29 -050032 if (versionToCompare.minor < mslVersion.minor)
Pavithra Barithayace9a5c92024-06-25 02:24:07 -050033 {
Patrick Williams6a85e8a2021-08-27 08:22:29 -050034 return (-1);
Pavithra Barithayace9a5c92024-06-25 02:24:07 -050035 }
Patrick Williams6a85e8a2021-08-27 08:22:29 -050036
37 if (versionToCompare.rev > mslVersion.rev)
Pavithra Barithayace9a5c92024-06-25 02:24:07 -050038 {
Patrick Williams6a85e8a2021-08-27 08:22:29 -050039 return (1);
Pavithra Barithayace9a5c92024-06-25 02:24:07 -050040 }
Patrick Williams6a85e8a2021-08-27 08:22:29 -050041 if (versionToCompare.rev < mslVersion.rev)
Pavithra Barithayace9a5c92024-06-25 02:24:07 -050042 {
Patrick Williams6a85e8a2021-08-27 08:22:29 -050043 return (-1);
Pavithra Barithayace9a5c92024-06-25 02:24:07 -050044 }
Patrick Williams6a85e8a2021-08-27 08:22:29 -050045
46 // Both string are equal and there is no need to make an upgrade return 0.
47 return 0;
48}
49
50// parse Function copy inpVersion onto outVersion in Version format
51// {major,minor,rev}.
52void minimum_ship_level::parse(const std::string& inpVersion,
53 Version& outVersion)
54{
55 std::smatch match;
56 outVersion = {0, 0, 0};
57
58 std::regex rx{REGEX_BMC_MSL, std::regex::extended};
59
60 if (!std::regex_search(inpVersion, match, rx))
61 {
Patrick Williamsc9bb6422021-08-27 06:18:35 -050062 error("Unable to parse BMC version: {VERSION}", "VERSION", inpVersion);
Patrick Williams6a85e8a2021-08-27 08:22:29 -050063 return;
64 }
65
66 outVersion.major = std::stoi(match[2]);
67 outVersion.minor = std::stoi(match[3]);
68 outVersion.rev = std::stoi(match[4]);
69}
70
71bool minimum_ship_level::verify(const std::string& versionManifest)
72{
Patrick Williams6a85e8a2021-08-27 08:22:29 -050073 // If there is no msl or mslRegex return upgrade is needed.
Adriana Kobylak30352a62024-04-09 09:25:36 -050074 if (!enabled())
Patrick Williams6a85e8a2021-08-27 08:22:29 -050075 {
76 return true;
77 }
78
79 // Define mslVersion variable and populate in Version format
80 // {major,minor,rev} using parse function.
81
Adriana Kobylak30352a62024-04-09 09:25:36 -050082 std::string msl = getMinimumVersion();
Patrick Williams6a85e8a2021-08-27 08:22:29 -050083 Version mslVersion = {0, 0, 0};
84 parse(msl, mslVersion);
85
86 // Define actualVersion variable and populate in Version format
87 // {major,minor,rev} using parse function.
88 std::string tmpStr{};
89
90 tmpStr = versionManifest;
91 Version actualVersion = {0, 0, 0};
92 parse(versionManifest, actualVersion);
93
94 // Compare actualVersion vs MSL.
95 auto rc = compare(actualVersion, mslVersion);
96 if (rc < 0)
97 {
zamiseck10ec9752022-04-27 12:39:50 -050098 using namespace phosphor::logging;
Adriana Kobylakce82de52024-01-16 13:56:38 -060099 using IncompatibleErr = sdbusplus::error::xyz::openbmc_project::
100 software::version::Incompatible;
zamiseck10ec9752022-04-27 12:39:50 -0500101 using Incompatible =
Adriana Kobylakce82de52024-01-16 13:56:38 -0600102 xyz::openbmc_project::software::version::Incompatible;
zamiseck10ec9752022-04-27 12:39:50 -0500103 std::string purpose =
104 "xyz.openbmc_project.Software.Version.VersionPurpose.BMC";
105
Patrick Williamsc9bb6422021-08-27 06:18:35 -0500106 error(
107 "BMC Minimum Ship Level ({MIN_VERSION}) NOT met by {ACTUAL_VERSION}",
108 "MIN_VERSION", msl, "ACTUAL_VERSION", tmpStr, "VERSION_PURPOSE",
109 purpose);
zamiseck10ec9752022-04-27 12:39:50 -0500110 report<IncompatibleErr>(Incompatible::MIN_VERSION(msl.c_str()),
111 Incompatible::ACTUAL_VERSION(tmpStr.c_str()),
112 Incompatible::VERSION_PURPOSE(purpose.c_str()));
Patrick Williams6a85e8a2021-08-27 08:22:29 -0500113 return false;
114 }
115
116 return true;
117}
Adriana Kobylak30352a62024-04-09 09:25:36 -0500118
119bool minimum_ship_level::enabled()
120{
121 std::string msl = getMinimumVersion();
122 std::string mslRegex{REGEX_BMC_MSL};
Pavithra Barithaya2d5704e2024-06-26 02:35:08 -0500123 return !msl.empty() && !mslRegex.empty();
Adriana Kobylak30352a62024-04-09 09:25:36 -0500124}
125
126std::string minimum_ship_level::getMinimumVersion()
127{
128 return BMC_MSL;
129}