JaiaBot 2.0.0
JaiaBot micro-AUV software
 
Loading...
Searching...
No Matches
liaison_upgrade.h
Go to the documentation of this file.
1#ifndef LIAISON_UPGRADE_H
2#define LIAISON_UPGRADE_H
3
4#include <Wt/Http/Response.h>
5#include <Wt/WFileResource.h>
6
7#include <chrono>
8#include <future>
9
10#include <boost/asio/io_service.hpp>
11#include <boost/process.hpp>
12#include <boost/process/pipe.hpp>
13
14#include <goby/util/thirdparty/nlohmann/json.hpp>
15#include <goby/zeromq/liaison/liaison_container.h>
16
17#include "config.pb.h"
18
19namespace jaiabot
20{
21class LiaisonUpgrade : public goby::zeromq::LiaisonContainer
22{
23 public:
24 LiaisonUpgrade(const goby::apps::zeromq::protobuf::LiaisonConfig& cfg);
25
26 private:
27 class LogFileResource : public Wt::WResource
28 {
29 public:
30 LogFileResource() {}
31
32 void set_last_log(const std::string& log) { last_log_ = log; }
33
34 void handleRequest(const Wt::Http::Request& request, Wt::Http::Response& response) override
35 {
36 suggestFileName("jaiabot_upgrade_ansible_log_" + goby::time::file_str() + ".json");
37 response.addHeader("Content-Type", "application/json");
38 response.out() << last_log_;
39 }
40
41 private:
42 std::string last_log_;
43 };
44
45 class AutoScrollWidget : public Wt::WContainerWidget
46 {
47 public:
48 AutoScrollWidget()
49 {
50 this->setOverflow(Wt::Overflow::Auto,
51 Wt::Orientation::Horizontal | Wt::Orientation::Vertical);
52 this->setHeight(300);
53 }
54
55 void addText(Wt::WString line)
56 {
57 this->addNew<Wt::WText>(line + "<br/>");
58
59 // JavaScript to scroll to the bottom
60 std::string jsCode = "var obj = document.getElementById('" + this->id() +
61 "'); obj.scrollTop = obj.scrollHeight;";
62 Wt::WApplication::instance()->doJavaScript(jsCode);
63 }
64 };
65
67 {
68 AnsiblePlaybookConfig(const jaiabot::protobuf::UpgradeConfig::AnsiblePlaybook& playbook,
69 Wt::WContainerWidget* parent, LiaisonUpgrade* upgrade,
70 std::size_t playbook_index);
71 AnsiblePlaybookConfig() = delete;
72 AnsiblePlaybookConfig(const AnsiblePlaybookConfig&) = delete;
73 AnsiblePlaybookConfig(AnsiblePlaybookConfig&&) = default;
74
75 std::string file;
76 std::string stdout_file;
77 std::string json_file;
78
79 Wt::WPushButton* run_button{0};
80 Wt::WPushButton* log_button{0};
81 Wt::WPushButton* stdout_button{0};
82 Wt::WText* result_text{0};
83 Wt::WTable* result_table{0};
84 Wt::WGroupBox* stdout_group{0};
85 AutoScrollWidget* stdout_div{0};
86
87 std::vector<std::string>::const_iterator run_text_it;
88 // name -> value
89 std::map<std::string, std::string> input_var;
90 // name -> display name
91 std::map<std::string, std::string> output_var;
92 std::vector<std::string> output_var_order;
93
95 {
96 ProcessData(const protobuf::UpgradeConfig& cfg, const std::string& playbook_file,
97 const jaiabot::protobuf::UpgradeConfig::AnsiblePlaybook& pb_playbook,
98 const std::string& input_vars, const std::string& ansible_stdout_file,
99 const std::string& ansible_json_file);
101
102 boost::asio::io_service io;
103 std::future<std::string> stderr;
104 boost::process::child process;
105 std::thread io_thread;
106 std::ifstream stdout;
107 };
108 std::unique_ptr<ProcessData> pdata;
109 std::string last_log;
110 std::shared_ptr<LogFileResource> log_resource;
111 const jaiabot::protobuf::UpgradeConfig::AnsiblePlaybook& pb_playbook;
112
113 void show_stdout();
114 void hide_stdout();
115 };
117
118 struct Result
119 {
120 enum ResultType
121 {
122 FAILURE,
123 UNREACHABLE,
124 SUCCESS // not FAILURE or UNREACHABLE
125 };
126 ResultType result{SUCCESS};
127 std::map<std::string, std::string> output_vars;
128 };
129
130 void run_ansible_playbook(std::size_t playbook_index);
131 void set_input_var(int selection_index, Wt::WComboBox* selection, std::string name,
132 std::size_t playbook_index);
133
134 void process_ansible_json_result(nlohmann::json j, AnsiblePlaybookConfig& playbook);
135 void toggle_stdout(std::size_t playbook_index);
136
137 void loop();
138 void focus() override { timer_.start(); }
139 void unfocus() override { timer_.stop(); }
140
141 private:
142 struct SectionWidgets
143 {
144 Wt::WPanel* panel;
145 Wt::WContainerWidget* div;
146 };
147
148 std::map<std::string, SectionWidgets> sections;
149
150 const protobuf::UpgradeConfig& cfg_;
151 std::vector<AnsiblePlaybookConfig> playbooks_;
152 Wt::WTimer timer_;
153 static const std::vector<std::string> running_;
154 static const Wt::WColor color_success_;
155 static const Wt::WColor color_failure_;
156};
157
158} // namespace jaiabot
159
160#endif
LiaisonUpgrade(const goby::apps::zeromq::protobuf::LiaisonConfig &cfg)
friend struct AnsiblePlaybookConfig
ProcessData(const protobuf::UpgradeConfig &cfg, const std::string &playbook_file, const jaiabot::protobuf::UpgradeConfig::AnsiblePlaybook &pb_playbook, const std::string &input_vars, const std::string &ansible_stdout_file, const std::string &ansible_json_file)