virthttp  0.0
libvirt http interface
domain.hpp
Go to the documentation of this file.
1 #pragma once
2 #include <optional>
3 #include <tuple>
4 #include <rapidjson/rapidjson.h>
5 #include <virt_wrap/Error.hpp>
6 #include "wrapper/depends.hpp"
7 #include "wrapper/dispatch.hpp"
9 #include "wrapper/virt2json.hpp"
10 #include "base.hpp"
11 #include "flagwork.hpp"
12 #include "hdl_ctx.hpp"
13 #include "urlparser.hpp"
14 #include "virt_wrap.hpp"
15 
21  std::tuple<JDispatchVals<JTypeList<rapidjson::kStringType, rapidjson::kObjectType>, JTypeList<rapidjson::kArrayType>>, JDispatchVals<JAll>,
28 
32 constexpr std::array<JDispatch, std::tuple_size_v<DomainJDispatcherVals>> domain_jdispatchers = gen_jdispatchers(domain_jdispatcher_vals);
33 
40 
48  [[nodiscard]] constexpr auto search_all_flags(const TargetParser& target) const noexcept
49  -> std::optional<virt::enums::connection::list::domains::Flag> {
51  Flag flags = Flag::DEFAULT;
52  if (auto activity = target.getBool("active"); activity)
53  flags |= *activity ? Flag::ACTIVE : Flag::INACTIVE;
54  if (auto persistence = target.getBool("persistent"); persistence)
55  flags |= *persistence ? Flag::PERSISTENT : Flag::TRANSIENT;
56  if (auto savemgmt = target.getBool("managed_save"); savemgmt)
57  flags |= *savemgmt ? Flag::MANAGEDSAVE : Flag::NO_MANAGEDSAVE;
58  if (auto autostart = target.getBool("autostart"); autostart)
59  flags |= *autostart ? Flag::AUTOSTART : Flag::NO_AUTOSTART;
60  if (auto snapshot = target.getBool("has_snapshot"); snapshot)
61  flags |= *snapshot ? Flag::HAS_SNAPSHOT : Flag::NO_SNAPSHOT;
62 
63  const auto opt_flags = target_get_composable_flag<Flag>(target, "state");
64  if (!opt_flags)
65  return error(301), std::nullopt;
66  return {flags | *opt_flags};
67  }
68 };
69 
75  virt::Domain& dom;
76 
77  public:
81  explicit DomainHandlers(HandlerContext& ctx, virt::Domain& dom) : HandlerMethods(ctx), dom(dom) {}
82 
83  DependsOutcome create(const rapidjson::Value& obj) override {
84  if (obj.IsString()) {
85  dom = virt::Domain::createXML(conn, obj.GetString());
86  if (!dom)
87  return error(105), DependsOutcome::FAILURE;
88  rapidjson::Value res_val;
89  res_val.SetObject();
90  res_val.AddMember("created", true, json_res.GetAllocator());
91  json_res.result(std::move(res_val));
93  }
94  if (obj.IsObject())
95  return error(-1), DependsOutcome::FAILURE;
96  return error(0), DependsOutcome::FAILURE;
97  }
98 
99  DependsOutcome query(const rapidjson::Value& action) override {
100  rapidjson::Value res_val;
101  auto& jalloc = json_res.GetAllocator();
102  const auto& path_parts = target.getPathParts();
103  if (path_parts.size() < 5) {
104  res_val.SetObject();
105  const auto [state, max_mem, memory, nvirt_cpu, cpu_time] = dom.getInfo();
106  const auto os_type = dom.getOSType();
107  res_val.AddMember("name", rapidjson::Value(dom.getName(), jalloc), jalloc);
108  res_val.AddMember("uuid", dom.extractUUIDString(), jalloc);
109  res_val.AddMember("id", static_cast<int>(dom.getID()), jalloc);
110  res_val.AddMember("status", rapidjson::StringRef(virt::enums::domain::State(EHTag{}, state).to_string().data()), jalloc);
111  res_val.AddMember("os", rapidjson::Value(os_type.get(), jalloc), jalloc);
112  res_val.AddMember("ram", memory, jalloc);
113  res_val.AddMember("ram_max", max_mem, jalloc);
114  res_val.AddMember("cpu", nvirt_cpu, jalloc);
115  json_res.result(std::move(res_val));
117  }
118 
119 
120 
121  const auto outcome = parameterized_depends_scope(
122  subquery("xml_desc", "options", ti<virt::enums::domain::XMLFlags>, SUBQ_LIFT(dom.getXMLDesc), fwd_as_if_err(-2)),
123  subquery("fs_info", SUBQ_LIFT(dom.getFSInfo), fwd_as_if_err(201), // getting filesystem information failed
124  [&](auto fs_infos, auto& jalloc) {
125  rapidjson::Value jvres;
126  for (const virDomainFSInfo& fs_info : fs_infos) {
127  rapidjson::Value sub;
128  sub.AddMember("name", rapidjson::Value(fs_info.name, jalloc), jalloc);
129  sub.AddMember("mountpoint", rapidjson::Value(fs_info.mountpoint, jalloc), jalloc);
130  sub.AddMember("fs_type", rapidjson::Value(fs_info.fstype, jalloc), jalloc);
131  {
132  rapidjson::Value dev_aliases;
133  dev_aliases.SetArray();
134  for (const char* dev_alias : gsl::span{fs_info.devAlias, static_cast<long>(fs_info.ndevAlias)})
135  dev_aliases.PushBack(rapidjson::Value(dev_alias, jalloc), jalloc);
136  sub.AddMember("disk_dev_aliases", dev_aliases, jalloc);
137  }
138  jvres.PushBack(sub, jalloc);
139  }
140  return jvres;
141  }),
142  subquery("hostname", SUBQ_LIFT(dom.getHostname), fwd_as_if_err(-2)), subquery("time", SUBQ_LIFT(dom.getTime), fwd_as_if_err(-2)),
143  subquery(
144  "scheduler_type", SUBQ_LIFT(dom.getSchedulerType), [&](const auto& sp) { return fwd_err(sp.second, -2); },
145  [&](auto sp, auto& jalloc) {
146  rapidjson::Value ret{};
147  ret.SetObject();
148  ret.AddMember("type", rapidjson::Value(static_cast<const char*>(sp.first), jalloc), jalloc);
149  ret.AddMember("params_count", static_cast<int>(sp.second), jalloc);
150  return ret;
151  }),
152  subquery("launch_security_info", SUBQ_LIFT(dom.getLaunchSecurityInfo), fwd_as_if_err(-2)))(4, target, res_val, json_res.GetAllocator(),
153  [&](auto... args) { return error(args...); });
154  if (outcome == DependsOutcome::SUCCESS)
155  json_res.result(std::move(res_val));
156  return outcome;
157  }
158  DependsOutcome alter(const rapidjson::Value& action) override {
159  const auto& action_obj = *action.MemberBegin();
160  const auto& [action_name, action_val] = action_obj;
161  const auto hdl = domain_actions_table[std::string_view{action_name.GetString(), action_name.GetStringLength()}];
162  return hdl ? hdl(action_val, json_res, dom) : (error(123), DependsOutcome::FAILURE);
163  }
164  DependsOutcome vacuum(const rapidjson::Value& action) override {
165  auto& jalloc = json_res.GetAllocator();
166  auto success = [&] {
167  rapidjson::Value res_val;
168  res_val.SetObject();
169  res_val.AddMember("deleted", true, jalloc);
170  json_res.result(std::move(res_val));
172  };
173  auto failure = [&] {
174  rapidjson::Value msg_val;
175  msg_val.SetObject();
176  msg_val.AddMember("libvirt", rapidjson::Value(virt::extractLastError().message, jalloc), jalloc);
177  json_res.message(std::move(msg_val));
178  return error(216), DependsOutcome::FAILURE;
179  };
180  const auto opt_flags = target_get_composable_flag<virt::enums::domain::UndefineFlag>(target, "options");
181  if (!opt_flags)
182  return error(301), DependsOutcome::FAILURE;
183  return dom.undefine(*opt_flags) ? success() : failure();
184  }
185 };
DependsOutcome
Definition: depends.hpp:11
DomainHandlers(HandlerContext &ctx, virt::Domain &dom)
Definition: domain.hpp:81
auto extractUUIDString() const -> std::string
Definition: Domain.hpp:359
Definition: ListDomainFlag.hpp:6
std::tuple< JDispatchVals< JTypeList< rapidjson::kStringType, rapidjson::kObjectType >, JTypeList< rapidjson::kArrayType >>, JDispatchVals< JAll >, JDispatchVals< JTypeList< rapidjson::kObjectType >, JTypeList< rapidjson::kArrayType >>, JDispatchVals< JAll >> DomainJDispatcherVals
Definition: domain.hpp:22
UniqueZstring getXMLDesc(enums::domain::XMLFlags flag) const noexcept
Definition: Domain.hpp:426
constexpr auto gen_jdispatchers(const std::tuple< JDVs... > &tup) noexcept-> std::array< JDispatch, sizeof...(JDVs)>
Definition: dispatch.hpp:115
DependsOutcome query(const rapidjson::Value &action) override
Definition: domain.hpp:99
Definition: utility.hpp:55
constexpr DomainJDispatcherVals domain_jdispatcher_vals
Definition: domain.hpp:27
DependsOutcome create(const rapidjson::Value &obj) override
Definition: domain.hpp:83
Definition: State.hpp:7
Definition: domain.hpp:74
constexpr std::array< JDispatch, std::tuple_size_v< DomainJDispatcherVals > > domain_jdispatchers
Definition: domain.hpp:32
const TargetParser & target
the incoming request&#39;s URI target
Definition: hdl_ctx.hpp:14
Definition: dispatch.hpp:16
gsl::czstring getName() const noexcept
Definition: Domain.hpp:277
auto getOSType() const
Definition: Domain.hpp:368
Definition: dispatch.hpp:20
constexpr auto subquery
Perfect-forwarding lifted subq_impl::subquery.
Definition: flagwork.hpp:242
constexpr auto search_all_flags(const TargetParser &target) const noexcept-> std::optional< virt::enums::connection::list::domains::Flag >
Definition: domain.hpp:48
DependsOutcome vacuum(const rapidjson::Value &action) override
Definition: domain.hpp:164
virt::Connection & conn
the connection to perform libvirt operations through (plans to change to a vector) ...
Definition: hdl_ctx.hpp:12
static Domain createXML(Connection &, gsl::czstring<> xml, enums::domain::CreateFlag flags)
Definition: Domain.hpp:33
Definition: hdl_ctx.hpp:11
UniqueZstring getHostname() const noexcept
Definition: Domain.hpp:227
JsonRes & json_res
the result of running the handlers to be sent to the client
Definition: hdl_ctx.hpp:13
const auto fwd_as_if_err(int code)
Definition: hdl_ctx.hpp:32
DomainUnawareHandlers(HandlerContext &ctx)
Definition: domain.hpp:39
const auto fwd_err(bool fwd, int code)
Definition: hdl_ctx.hpp:27
void result(T &&val)
Definition: json_utils.hpp:45
Definition: domain.hpp:38
unsigned getID() const noexcept
Definition: Domain.hpp:283
auto getTime() const noexcept
Definition: Domain.hpp:335
constexpr auto parameterized_depends_scope(Fcns &&...depends) noexcept((std::is_nothrow_move_constructible_v< Fcns > &&...))
Definition: flagwork.hpp:60
constexpr const std::vector< std::string_view > & getPathParts() const noexcept
Definition: urlparser.hpp:83
Definition: base.hpp:34
Definition: Domain.hpp:96
void message(T &&val)
Definition: json_utils.hpp:50
#define SUBQ_LIFT(mem_fn)
Definition: flagwork.hpp:15
auto extractLastError() -> Error
Definition: Error.hpp:44
auto getSchedulerType() const noexcept-> std::pair< UniqueZstring, int >
Definition: Domain.hpp:289
Definition: urlparser.hpp:36
auto getLaunchSecurityInfo() const noexcept
Definition: Domain.hpp:257
auto getFSInfo() const noexcept
Definition: Domain.hpp:206
DomainActionsTable domain_actions_table
Definition: ListDomainFlag.hpp:8
bool undefine() noexcept
Definition: Domain.hpp:690
constexpr std::optional< bool > getBool(std::string_view key) const noexcept
Definition: urlparser.hpp:91
Info getInfo() const noexcept
Definition: Domain.hpp:241
auto error(Args &&...args) const noexcept(noexcept(json_res.error(std::forward< Args >(args)...))) -> decltype(json_res.error(std::forward< Args >(args)...))
Definition: hdl_ctx.hpp:22
DependsOutcome alter(const rapidjson::Value &action) override
Definition: domain.hpp:158