make building handlers from json more generic
Problem: version-handler, a new feature that will be added to this
repository will also parse json files from the same directory ipmi-flash
does. Currently buildjson is a mix of some code that can be reused and
other code that is pretty specific to firmware updates; this makes it
hard to reuse the code.
Solution: factor out the generic parts and place it in bmc and then
leave the specific parts in firmware-handler. Also code changes have
been made to buildjson: wrap functions in a templated class that leaves
feature specific parsing as a pure virtual method.
Tested:
Ran the unit tests, which do test the parsing functionality.
Signed-off-by: Jason Ling <jasonling@google.com>
Change-Id: I021dc829a82d1719b4cb862cdfb224eca629a44d
diff --git a/bmc/buildjson.cpp b/bmc/buildjson.cpp
new file mode 100644
index 0000000..c4bc4b5
--- /dev/null
+++ b/bmc/buildjson.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2019 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "buildjson.hpp"
+
+#include "file_handler.hpp"
+#include "fs.hpp"
+
+#include <nlohmann/json.hpp>
+#include <sdbusplus/bus.hpp>
+
+#include <algorithm>
+#include <cstdio>
+#include <exception>
+#include <fstream>
+#include <string>
+#include <vector>
+
+namespace ipmi_flash
+{
+
+std::unique_ptr<TriggerableActionInterface>
+ buildFileSystemd(const nlohmann::json& data)
+{
+ /* This type of action requires a path and unit, and optionally a mode. */
+ const auto& path = data.at("path");
+ const auto& unit = data.at("unit");
+
+ /* the mode parameter is optional. */
+ std::string systemdMode = "replace";
+ const auto& mode = data.find("mode");
+ if (mode != data.end())
+ {
+ systemdMode = data.at("mode").get<std::string>();
+ }
+
+ return SystemdWithStatusFile::CreateSystemdWithStatusFile(
+ sdbusplus::bus::new_default(), path, unit, systemdMode);
+}
+
+std::unique_ptr<TriggerableActionInterface>
+ buildSystemd(const nlohmann::json& data)
+{
+ /* This type of action requires a unit, and optionally a mode. */
+ const auto& unit = data.at("unit");
+
+ /* the mode parameter is optional. */
+ std::string systemdMode = "replace";
+ const auto& mode = data.find("mode");
+ if (mode != data.end())
+ {
+ systemdMode = data.at("mode").get<std::string>();
+ }
+
+ return SystemdNoFile::CreateSystemdNoFile(sdbusplus::bus::new_default(),
+ unit, systemdMode);
+}
+
+template <typename T>
+std::vector<HandlerConfig<T>>
+ HandlersBuilderIfc<T>::buildHandlerConfigs(const std::string& directory)
+{
+ std::vector<HandlerConfig<T>> output;
+
+ std::vector<std::string> jsonPaths = GetJsonList(directory);
+
+ for (const auto& path : jsonPaths)
+ {
+ std::ifstream jsonFile(path);
+ if (!jsonFile.is_open())
+ {
+ std::fprintf(stderr, "Unable to open json file: %s\n",
+ path.c_str());
+ continue;
+ }
+
+ auto data = nlohmann::json::parse(jsonFile, nullptr, false);
+ if (data.is_discarded())
+ {
+ std::fprintf(stderr, "Parsing json failed: %s\n", path.c_str());
+ }
+
+ std::vector<HandlerConfig<T>> configs = buildHandlerFromJson(data);
+ std::move(configs.begin(), configs.end(), std::back_inserter(output));
+ }
+ return output;
+}
+
+} // namespace ipmi_flash