xref: /openbmc/openpower-vpd-parser/wait-vpd-parser/src/wait_vpd_parser.cpp (revision 3e1cb49d2d469b79cafbd6372d071acb66ee612e)
1 #include "config.h"
2 
3 #include "constants.hpp"
4 #include "logger.hpp"
5 #include "utility/dbus_utility.hpp"
6 
7 #include <CLI/CLI.hpp>
8 
9 #include <chrono>
10 #include <thread>
11 
12 /**
13  * @brief API to check for VPD collection status
14  *
15  * This API checks for VPD manager collection status by reading the
16  * "CollectionStatus" property exposed by vpd-manager on Dbus. The read logic
17  * uses a retry loop with a specific number of retries with specific sleep time
18  * between each retry.
19  *
20  * @param[in] i_retryLimit - Maximum number of retries
21  * @param[in] i_sleepDurationInSeconds - Sleep time in seconds between each
22  * retry
23  *
24  * @return If "CollectionStatus" property is "Completed", returns 0, otherwise
25  * returns 1.
26  */
27 int checkVpdCollectionStatus(const unsigned i_retryLimit,
28                              const unsigned i_sleepDurationInSeconds) noexcept
29 {
30     auto l_logger = vpd::Logger::getLoggerInstance();
31 
32     try
33     {
34         l_logger->logMessage(
35             "Checking every " + std::to_string(i_sleepDurationInSeconds) +
36             "s for VPD collection status ....");
37 
38         for (unsigned l_retries = i_retryLimit;
39              l_retries != vpd::constants::VALUE_0; --l_retries)
40         {
41             // check at specified time interval
42             std::this_thread::sleep_for(
43                 std::chrono::seconds(i_sleepDurationInSeconds));
44 
45             // TODO: revisit this once "CollectionStatus" property is moved to
46             // xyz interface
47             const auto l_propValue = vpd::dbusUtility::readDbusProperty(
48                 IFACE, OBJPATH, IFACE, "CollectionStatus");
49 
50             if (auto l_val = std::get_if<std::string>(&l_propValue))
51             {
52                 if (*l_val == "Completed")
53                 {
54                     l_logger->logMessage("VPD collection is completed");
55                     return vpd::constants::VALUE_0;
56                 }
57             }
58 
59             l_logger->logMessage(
60                 "Waiting for VPD status update. Retries remaining: " +
61                 std::to_string(l_retries));
62         }
63 
64         l_logger->logMessage(
65             "Exit wait for VPD services to finish with timeout");
66     }
67     catch (const std::exception& l_ex)
68     {
69         l_logger->logMessage("Error while checking VPD collection status: " +
70                              std::string(l_ex.what()));
71     }
72 
73     return vpd::constants::VALUE_1;
74 }
75 
76 int main(int argc, char** argv)
77 {
78     CLI::App l_app{"Wait VPD parser app"};
79 
80     // default retry limit and sleep duration values
81     unsigned l_retryLimit{100};
82     unsigned l_sleepDurationInSeconds{2};
83 
84     l_app.add_option("--retryLimit, -r", l_retryLimit, "Retry limit");
85     l_app.add_option("--sleepDurationInSeconds, -s", l_sleepDurationInSeconds,
86                      "Sleep duration in seconds between each retry");
87 
88     CLI11_PARSE(l_app, argc, argv);
89 
90     return checkVpdCollectionStatus(l_retryLimit, l_sleepDurationInSeconds);
91 }
92