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