blob: c8039973d2e9cf5042dc51356a6258086904c46b [file] [log] [blame]
Patrick Venture298930a2019-07-03 11:44:52 -07001/*
2 * Copyright 2019 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Jason Lingc893f432020-10-24 19:31:44 -070016#include "firmware_handlers_builder.hpp"
Patrick Venture298930a2019-07-03 11:44:52 -070017
18#include "file_handler.hpp"
Patrick Venturea6b4abd2019-07-19 10:58:55 -070019#include "fs.hpp"
William A. Kennington IIIbec23182021-01-21 18:10:52 -080020#include "general_systemd.hpp"
Patrick Ventured53d60a2020-04-07 09:01:34 -070021#include "skip_action.hpp"
Patrick Venture298930a2019-07-03 11:44:52 -070022
Patrick Venture9b37b092020-05-28 20:58:57 -070023#include <nlohmann/json.hpp>
Patrick Venture9b37b092020-05-28 20:58:57 -070024
Patrick Venturea6b4abd2019-07-19 10:58:55 -070025#include <algorithm>
Patrick Venture298930a2019-07-03 11:44:52 -070026#include <cstdio>
27#include <exception>
Patrick Venturea6b4abd2019-07-19 10:58:55 -070028#include <fstream>
Patrick Venture097435f2019-08-15 07:39:48 -070029#include <regex>
Patrick Venture298930a2019-07-03 11:44:52 -070030#include <string>
31#include <vector>
32
33namespace ipmi_flash
34{
Jason Lingc893f432020-10-24 19:31:44 -070035std::vector<HandlerConfig<ActionPack>>
36 FirmwareHandlersBuilder::buildHandlerFromJson(const nlohmann::json& data)
Patrick Venture9cce5a22019-08-06 09:24:46 -070037{
Jason Lingc893f432020-10-24 19:31:44 -070038 std::vector<HandlerConfig<ActionPack>> handlers;
Patrick Venture298930a2019-07-03 11:44:52 -070039
40 for (const auto& item : data)
41 {
42 try
43 {
Jason Lingc893f432020-10-24 19:31:44 -070044 HandlerConfig<ActionPack> output;
Patrick Venture298930a2019-07-03 11:44:52 -070045
46 /* at() throws an exception when the key is not present. */
47 item.at("blob").get_to(output.blobId);
48
Patrick Venture097435f2019-08-15 07:39:48 -070049 /* name must be: /flash/... */
50 if (!std::regex_match(output.blobId, std::regex("^\\/flash\\/.+")))
51 {
Patrick Williams42a44c22024-08-16 15:21:32 -040052 throw std::runtime_error(
53 "Invalid blob name: '" + output.blobId +
54 "' must start with /flash/");
Patrick Venture097435f2019-08-15 07:39:48 -070055 }
56
Patrick Venture298930a2019-07-03 11:44:52 -070057 /* handler is required. */
58 const auto& h = item.at("handler");
59 const std::string handlerType = h.at("type");
60 if (handlerType == "file")
61 {
62 const auto& path = h.at("path");
63 output.handler = std::make_unique<FileHandler>(path);
64 }
65 else
66 {
Patrick Williams42a44c22024-08-16 15:21:32 -040067 throw std::runtime_error(
68 "Invalid handler type: " + handlerType);
Patrick Venture298930a2019-07-03 11:44:52 -070069 }
70
71 /* actions are required (presently). */
72 const auto& a = item.at("actions");
73 std::unique_ptr<ActionPack> pack = std::make_unique<ActionPack>();
74
Patrick Ventured53d60a2020-04-07 09:01:34 -070075 /* to make an action optional, assign type "skip" */
Patrick Venture298930a2019-07-03 11:44:52 -070076 const auto& prep = a.at("preparation");
77 const std::string prepareType = prep.at("type");
78 if (prepareType == "systemd")
79 {
Patrick Venturee0216d22019-08-21 10:17:39 -070080 pack->preparation = std::move(buildSystemd(prep));
Patrick Venture298930a2019-07-03 11:44:52 -070081 }
Patrick Ventured53d60a2020-04-07 09:01:34 -070082 else if (prepareType == "skip")
83 {
84 pack->preparation = SkipAction::CreateSkipAction();
85 }
Patrick Venture298930a2019-07-03 11:44:52 -070086 else
87 {
Patrick Williams42a44c22024-08-16 15:21:32 -040088 throw std::runtime_error(
89 "Invalid preparation type: " + prepareType);
Patrick Venture298930a2019-07-03 11:44:52 -070090 }
91
92 const auto& verify = a.at("verification");
93 const std::string verifyType = verify.at("type");
94 if (verifyType == "fileSystemdVerify")
95 {
Patrick Venture9cce5a22019-08-06 09:24:46 -070096 pack->verification = std::move(buildFileSystemd(verify));
Patrick Venture298930a2019-07-03 11:44:52 -070097 }
William A. Kennington III2d434c82019-11-22 18:42:35 -080098 else if (verifyType == "systemd")
99 {
100 pack->verification = std::move(buildSystemd(verify));
101 }
Patrick Ventured53d60a2020-04-07 09:01:34 -0700102 else if (verifyType == "skip")
103 {
104 pack->verification = SkipAction::CreateSkipAction();
105 }
Patrick Venture298930a2019-07-03 11:44:52 -0700106 else
107 {
Patrick Williams42a44c22024-08-16 15:21:32 -0400108 throw std::runtime_error(
109 "Invalid verification type:" + verifyType);
Patrick Venture298930a2019-07-03 11:44:52 -0700110 }
111
112 const auto& update = a.at("update");
113 const std::string updateType = update.at("type");
114 if (updateType == "reboot")
115 {
Patrick Venturee0216d22019-08-21 10:17:39 -0700116 pack->update = SystemdNoFile::CreateSystemdNoFile(
Patrick Venture44564902019-08-21 09:46:32 -0700117 sdbusplus::bus::new_default(), "reboot.target",
118 "replace-irreversibly");
Patrick Venture298930a2019-07-03 11:44:52 -0700119 }
Patrick Venturec2baac92019-08-05 13:30:38 -0700120 else if (updateType == "fileSystemdUpdate")
121 {
Patrick Venture9cce5a22019-08-06 09:24:46 -0700122 pack->update = std::move(buildFileSystemd(update));
Patrick Venturec2baac92019-08-05 13:30:38 -0700123 }
Patrick Venture298930a2019-07-03 11:44:52 -0700124 else if (updateType == "systemd")
125 {
Patrick Venturee0216d22019-08-21 10:17:39 -0700126 pack->update = std::move(buildSystemd(update));
Patrick Venture298930a2019-07-03 11:44:52 -0700127 }
Patrick Ventured53d60a2020-04-07 09:01:34 -0700128 else if (updateType == "skip")
129 {
130 pack->update = SkipAction::CreateSkipAction();
131 }
Patrick Venture298930a2019-07-03 11:44:52 -0700132 else
133 {
134 throw std::runtime_error("Invalid update type: " + updateType);
135 }
136
137 output.actions = std::move(pack);
138 handlers.push_back(std::move(output));
139 }
140 catch (const std::exception& e)
141 {
142 /* TODO: Once phosphor-logging supports unit-test injection, fix
143 * this to log.
144 */
145 std::fprintf(stderr,
146 "Excepted building HandlerConfig from json: %s\n",
147 e.what());
148 }
149 }
150
151 return handlers;
152}
Patrick Venture298930a2019-07-03 11:44:52 -0700153} // namespace ipmi_flash