]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/src/core/app-template.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / seastar / src / core / app-template.cc
1 /*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18 /*
19 * Copyright (C) 2014 Cloudius Systems, Ltd.
20 */
21
22 #include <seastar/core/app-template.hh>
23 #include <seastar/core/reactor.hh>
24 #include <seastar/core/scollectd.hh>
25 #include <seastar/core/metrics_api.hh>
26 #include <boost/program_options.hpp>
27 #include <seastar/core/print.hh>
28 #include <seastar/util/log.hh>
29 #include <seastar/util/log-cli.hh>
30 #include <boost/program_options.hpp>
31 #include <boost/make_shared.hpp>
32 #include <fstream>
33 #include <cstdlib>
34
35 namespace seastar {
36
37 namespace bpo = boost::program_options;
38
39 app_template::app_template(app_template::config cfg)
40 : _cfg(std::move(cfg))
41 , _opts(_cfg.name + " options")
42 , _conf_reader(get_default_configuration_reader()) {
43 _opts.add_options()
44 ("help,h", "show help message")
45 ;
46
47 _opts_conf_file.add(reactor::get_options_description(cfg.default_task_quota));
48 _opts_conf_file.add(seastar::metrics::get_options_description());
49 _opts_conf_file.add(smp::get_options_description());
50 _opts_conf_file.add(scollectd::get_options_description());
51 _opts_conf_file.add(log_cli::get_options_description());
52
53 _opts.add(_opts_conf_file);
54 }
55
56 app_template::configuration_reader app_template::get_default_configuration_reader() {
57 return [this] (bpo::variables_map& configuration) {
58 auto home = std::getenv("HOME");
59 if (home) {
60 std::ifstream ifs(std::string(home) + "/.config/seastar/seastar.conf");
61 if (ifs) {
62 bpo::store(bpo::parse_config_file(ifs, _opts_conf_file), configuration);
63 }
64 std::ifstream ifs_io(std::string(home) + "/.config/seastar/io.conf");
65 if (ifs_io) {
66 bpo::store(bpo::parse_config_file(ifs_io, _opts_conf_file), configuration);
67 }
68 }
69 };
70 }
71
72 void app_template::set_configuration_reader(configuration_reader conf_reader) {
73 _conf_reader = conf_reader;
74 }
75
76 boost::program_options::options_description& app_template::get_options_description() {
77 return _opts;
78 }
79
80 boost::program_options::options_description& app_template::get_conf_file_options_description() {
81 return _opts_conf_file;
82 }
83
84 boost::program_options::options_description_easy_init
85 app_template::add_options() {
86 return _opts.add_options();
87 }
88
89 void
90 app_template::add_positional_options(std::initializer_list<positional_option> options) {
91 for (auto&& o : options) {
92 _opts.add(boost::make_shared<bpo::option_description>(o.name, o.value_semantic, o.help));
93 _pos_opts.add(o.name, o.max_count);
94 }
95 }
96
97
98 bpo::variables_map&
99 app_template::configuration() {
100 return *_configuration;
101 }
102
103 int
104 app_template::run(int ac, char ** av, std::function<future<int> ()>&& func) {
105 return run_deprecated(ac, av, [func = std::move(func)] () mutable {
106 auto func_done = make_lw_shared<promise<>>();
107 engine().at_exit([func_done] { return func_done->get_future(); });
108 futurize_apply(func).finally([func_done] {
109 func_done->set_value();
110 }).then([] (int exit_code) {
111 return engine().exit(exit_code);
112 }).or_terminate();
113 });
114 }
115
116 int
117 app_template::run(int ac, char ** av, std::function<future<> ()>&& func) {
118 return run(ac, av, [func = std::move(func)] {
119 return func().then([] () {
120 return 0;
121 });
122 });
123 }
124
125 int
126 app_template::run_deprecated(int ac, char ** av, std::function<void ()>&& func) {
127 #ifdef SEASTAR_DEBUG
128 fmt::print("WARNING: debug mode. Not for benchmarking or production\n");
129 #endif
130 bpo::variables_map configuration;
131 try {
132 bpo::store(bpo::command_line_parser(ac, av)
133 .options(_opts)
134 .positional(_pos_opts)
135 .run()
136 , configuration);
137 _conf_reader(configuration);
138 } catch (bpo::error& e) {
139 fmt::print("error: {}\n\nTry --help.\n", e.what());
140 return 2;
141 }
142 if (configuration.count("help")) {
143 std::cout << _opts << "\n";
144 return 1;
145 }
146 if (configuration["help-loggers"].as<bool>()) {
147 log_cli::print_available_loggers(std::cout);
148 return 1;
149 }
150
151 bpo::notify(configuration);
152
153 // Needs to be before `smp::configure()`.
154 try {
155 apply_logging_settings(log_cli::extract_settings(configuration));
156 } catch (const std::runtime_error& exn) {
157 std::cout << "logging configuration error: " << exn.what() << '\n';
158 return 1;
159 }
160
161 configuration.emplace("argv0", boost::program_options::variable_value(std::string(av[0]), false));
162 try {
163 smp::configure(configuration);
164 } catch (...) {
165 std::cerr << "Could not initialize seastar: " << std::current_exception() << std::endl;
166 return 1;
167 }
168 _configuration = {std::move(configuration)};
169 engine().when_started().then([this] {
170 seastar::metrics::configure(this->configuration()).then([this] {
171 // set scollectd use the metrics configuration, so the later
172 // need to be set first
173 scollectd::configure( this->configuration());
174 });
175 }).then(
176 std::move(func)
177 ).then_wrapped([] (auto&& f) {
178 try {
179 f.get();
180 } catch (std::exception& ex) {
181 std::cout << "program failed with uncaught exception: " << ex.what() << "\n";
182 engine().exit(1);
183 }
184 });
185 auto exit_code = engine().run();
186 smp::cleanup();
187 return exit_code;
188 }
189
190 }