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