1 #pragma once 2 3 #include "fs.hpp" 4 #include "image_handler.hpp" 5 #include "status.hpp" 6 7 #include <nlohmann/json.hpp> 8 9 #include <memory> 10 #include <string> 11 #include <vector> 12 13 namespace ipmi_flash 14 { 15 /** 16 * build a systemd file triggerable action from json data 17 */ 18 std::unique_ptr<TriggerableActionInterface> 19 buildFileSystemd(const nlohmann::json& data); 20 21 /** 22 * build a systemd triggerable action from json data 23 */ 24 std::unique_ptr<TriggerableActionInterface> 25 buildSystemd(const nlohmann::json& data); 26 27 /** 28 * HandlerConfig associates a blobID with an ImageHandler and a set of 29 * supported actions of type T. 30 */ 31 template <typename T> 32 struct HandlerConfig 33 { 34 /* A string in the form: /flash/{unique}, s.t. unique is something like, 35 * flash, ubitar, statictar, or bios 36 */ 37 std::string blobId; 38 39 /* This owns a handler interface, this is typically going to be a file 40 * writer object. 41 */ 42 std::unique_ptr<ImageHandlerInterface> handler; 43 44 /* specifies actions to be taken in response to certain operations on a 45 * blob. 46 * Usually required but there are exceptions; the hashBlobId doesn't have 47 * an action pack. 48 */ 49 std::unique_ptr<T> actions; 50 }; 51 52 /* HandlersBuilderIfc is a helper class that builds Handlers from the json files 53 * found within a specified directory. 54 * The child class that inherits from HandlersBuilderIfc should implement 55 * buildHandlersConfigs to perform json validation and parsing. 56 * 57 */ 58 template <typename T> 59 struct HandlersBuilderIfc 60 { 61 virtual ~HandlersBuilderIfc() = default; 62 63 /** 64 * Given a folder of json configs, build the configurations. 65 * 66 * @param[in] directory - the directory to search (recurisvely). 67 * @return list of HandlerConfig objects. 68 */ 69 std::vector<HandlerConfig<T>> 70 buildHandlerConfigs(const std::string& directory) 71 { 72 73 std::vector<HandlerConfig<T>> output; 74 75 std::vector<std::string> jsonPaths = GetJsonList(directory); 76 for (const auto& path : jsonPaths) 77 { 78 std::ifstream jsonFile(path); 79 if (!jsonFile.is_open()) 80 { 81 std::fprintf(stderr, "Unable to open json file: %s\n", 82 path.c_str()); 83 continue; 84 } 85 86 auto data = nlohmann::json::parse(jsonFile, nullptr, false); 87 if (data.is_discarded()) 88 { 89 std::fprintf(stderr, "Parsing json failed: %s\n", path.c_str()); 90 continue; 91 } 92 93 std::vector<HandlerConfig<T>> configs = buildHandlerFromJson(data); 94 std::move(configs.begin(), configs.end(), 95 std::back_inserter(output)); 96 } 97 return output; 98 }; 99 100 /** 101 * Given a list of handlers as json data, construct the appropriate 102 * HandlerConfig objects. This method is meant to be called per json 103 * configuration file found. 104 * 105 * The list will only contain validly build HandlerConfig objects. Any 106 * invalid configuration is skipped. The hope is that the BMC firmware 107 * update configuration will never be invalid, but if another aspect is 108 * invalid, it can be fixed with a BMC firmware update once the bug is 109 * identified. 110 * 111 * This code does not validate that the blob specified is unique, that 112 * should be handled at a higher layer. 113 * 114 * @param[in] data - json data from a json file. 115 * @return list of HandlerConfig objects. 116 */ 117 virtual std::vector<HandlerConfig<T>> 118 buildHandlerFromJson(const nlohmann::json& data) = 0; 119 }; 120 } // namespace ipmi_flash 121