xref: /openbmc/phosphor-ipmi-flash/bmc/buildjson.hpp (revision bec23189399cf5524352a4a42debd9ed43b31bfa)
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