1 #pragma once 2 3 #include "fs.hpp" 4 #include "handler_config.hpp" 5 #include "status.hpp" 6 7 #include <nlohmann/json.hpp> 8 9 #include <array> 10 #include <memory> 11 #include <string> 12 #include <vector> 13 14 namespace ipmi_flash 15 { 16 /** 17 * build a systemd file triggerable action from json data 18 */ 19 std::unique_ptr<TriggerableActionInterface> 20 buildFileSystemd(const nlohmann::json& data); 21 22 /** 23 * build a systemd triggerable action from json data 24 */ 25 std::unique_ptr<TriggerableActionInterface> 26 buildSystemd(const nlohmann::json& data); 27 28 constexpr std::array defaultConfigPaths = { 29 "/usr/share/phosphor-ipmi-flash", 30 "/run/phosphor-ipmi-flash", 31 }; 32 33 /* HandlersBuilderIfc is a helper class that builds Handlers from the json files 34 * found within a specified directory. 35 * The child class that inherits from HandlersBuilderIfc should implement 36 * buildHandlersConfigs to perform json validation and parsing. 37 * 38 */ 39 template <typename T> 40 struct HandlersBuilderIfc 41 { 42 virtual ~HandlersBuilderIfc() = default; 43 44 /** 45 * Builds configurations from the default set of paths used by the blob 46 * handler. 47 */ buildHandlerConfigsFromDefaultPathsipmi_flash::HandlersBuilderIfc48 std::vector<HandlerConfig<T>> buildHandlerConfigsFromDefaultPaths() 49 { 50 std::vector<HandlerConfig<T>> ret; 51 for (auto path : defaultConfigPaths) 52 { 53 auto tmp = buildHandlerConfigs(path); 54 std::move(tmp.begin(), tmp.end(), std::back_inserter(ret)); 55 } 56 return ret; 57 } 58 59 /** 60 * Given a folder of json configs, build the configurations. 61 * 62 * @param[in] directory - the directory to search (recursively). 63 * @return list of HandlerConfig objects. 64 */ buildHandlerConfigsipmi_flash::HandlersBuilderIfc65 std::vector<HandlerConfig<T>> buildHandlerConfigs(const char* directory) 66 { 67 std::vector<HandlerConfig<T>> output; 68 69 std::vector<std::string> jsonPaths = GetJsonList(directory); 70 for (const auto& path : jsonPaths) 71 { 72 std::ifstream jsonFile(path); 73 if (!jsonFile.is_open()) 74 { 75 std::fprintf(stderr, "Unable to open json file: %s\n", 76 path.c_str()); 77 continue; 78 } 79 80 auto data = nlohmann::json::parse(jsonFile, nullptr, false); 81 if (data.is_discarded()) 82 { 83 std::fprintf(stderr, "Parsing json failed: %s\n", path.c_str()); 84 continue; 85 } 86 87 std::vector<HandlerConfig<T>> configs = buildHandlerFromJson(data); 88 std::move(configs.begin(), configs.end(), 89 std::back_inserter(output)); 90 } 91 return output; 92 }; 93 94 /** 95 * Given a list of handlers as json data, construct the appropriate 96 * HandlerConfig objects. This method is meant to be called per json 97 * configuration file found. 98 * 99 * The list will only contain validly build HandlerConfig objects. Any 100 * invalid configuration is skipped. The hope is that the BMC firmware 101 * update configuration will never be invalid, but if another aspect is 102 * invalid, it can be fixed with a BMC firmware update once the bug is 103 * identified. 104 * 105 * This code does not validate that the blob specified is unique, that 106 * should be handled at a higher layer. 107 * 108 * @param[in] data - json data from a json file. 109 * @return list of HandlerConfig objects. 110 */ 111 virtual std::vector<HandlerConfig<T>> 112 buildHandlerFromJson(const nlohmann::json& data) = 0; 113 }; 114 } // namespace ipmi_flash 115