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 */ 48 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 (recurisvely). 63 * @return list of HandlerConfig objects. 64 */ 65 std::vector<HandlerConfig<T>> buildHandlerConfigs(const char* directory) 66 { 67 68 std::vector<HandlerConfig<T>> output; 69 70 std::vector<std::string> jsonPaths = GetJsonList(directory); 71 for (const auto& path : jsonPaths) 72 { 73 std::ifstream jsonFile(path); 74 if (!jsonFile.is_open()) 75 { 76 std::fprintf(stderr, "Unable to open json file: %s\n", 77 path.c_str()); 78 continue; 79 } 80 81 auto data = nlohmann::json::parse(jsonFile, nullptr, false); 82 if (data.is_discarded()) 83 { 84 std::fprintf(stderr, "Parsing json failed: %s\n", path.c_str()); 85 continue; 86 } 87 88 std::vector<HandlerConfig<T>> configs = buildHandlerFromJson(data); 89 std::move(configs.begin(), configs.end(), 90 std::back_inserter(output)); 91 } 92 return output; 93 }; 94 95 /** 96 * Given a list of handlers as json data, construct the appropriate 97 * HandlerConfig objects. This method is meant to be called per json 98 * configuration file found. 99 * 100 * The list will only contain validly build HandlerConfig objects. Any 101 * invalid configuration is skipped. The hope is that the BMC firmware 102 * update configuration will never be invalid, but if another aspect is 103 * invalid, it can be fixed with a BMC firmware update once the bug is 104 * identified. 105 * 106 * This code does not validate that the blob specified is unique, that 107 * should be handled at a higher layer. 108 * 109 * @param[in] data - json data from a json file. 110 * @return list of HandlerConfig objects. 111 */ 112 virtual std::vector<HandlerConfig<T>> 113 buildHandlerFromJson(const nlohmann::json& data) = 0; 114 }; 115 } // namespace ipmi_flash 116