blob: aa66e22244026ad7d110979321a7c122f39e16b8 [file] [log] [blame]
#include "subprocess_utils.hpp"
#include <iterator>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
#include "boost/process.hpp" // NOLINT
#include "boost/system/error_code.hpp" // NOLINT
#include "logging.hpp"
#include "async_resp.hpp"
#include "error_messages.hpp"
#include "managed_store.hpp"
#ifdef UNIT_TEST_BUILD
#include "test/g3/mock_managed_store.hpp"
#endif
namespace redfish {
void childProcessRun(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::vector<std::string>& resetCmd) {
std::stringstream ss;
bool skipFirst = true;
for (const auto& str : resetCmd) {
if (skipFirst) {
skipFirst = false;
} else {
ss << " ";
}
ss << str;
}
BMCWEB_LOG_ALWAYS << "reset string:" << ss.str();
std::shared_ptr<std::vector<char>> buf =
std::make_shared<std::vector<char>>(4096);
std::shared_ptr<boost::process::async_pipe> ap =
std::make_shared<boost::process::async_pipe>(
managedStore::GetManagedObjectStore()->GetIoContext());
std::shared_ptr<boost::process::child> childProcess =
std::make_shared<boost::process::child>(
boost::process::search_path("systemd-run"),
boost::process::args(resetCmd), boost::process::std_err > *ap);
boost::asio::async_read(
*ap, boost::asio::buffer(*buf),
[ap, buf, asyncResp, childProcess](const boost::system::error_code& ec,
int size) {
if (ec && ec != boost::asio::error::eof) {
BMCWEB_LOG_ERROR << "Error in child process: " << ec.message();
messages::internalError(asyncResp->res);
return;
}
int exit = childProcess->exit_code();
BMCWEB_LOG_DEBUG << "Child process exited with code: " << exit;
asyncResp->res.jsonValue["ReturnCode"] = exit;
if (size != 0 && size <= static_cast<int>(buf->size())) {
asyncResp->res.jsonValue["Output"] =
std::string(buf->begin(), std::next(buf->begin(), size));
}
messages::success(asyncResp->res);
});
#ifdef UNIT_TEST_BUILD
asyncResp->res.jsonValue["ResetString"] = ss.str(); // used by unit test
#endif
}
} // namespace redfish