Merge "Host tool executables in the scylla main executable" from Botond

"
A big problem with scylla tool executables is that they include the
entire scylla codebase and thus they are just as big as the scylla
executable itself, making them impractical to deploy on production
machines. We could try to combat this by selectively including only the
actually needed dependencies but even ignoring the huge churn of
sorting out our depedency hell (which we should do at one point anyway),
some tools may genuinely depend on most of the scylla codebase.

A better solution is to host the tool executables in the scylla
executable itself, switching between the actual main function to run
some way. The tools themselves don't contain a lot of code so
this won't cause any considerable bloat in the size of the scylla
executable itself.
This series does exactly this, folds all the tool executables into the
scylla one, with main() switching between the actual main it will
delegate to based on a argv[1] command line argument. If this is a known
tool name, the respective tool's main will be invoked.
If it is "server", missing or unrecognized, the scylla main is invoked.

Originally this series used argv[0] as the mean to switch between the
main to run. This approach was abandoned for the approach mentioned above
for the following reasons:
* No launcher script, hard link, soft link or similar games are needed to
  launch a specific tool.
* No packaging needed, all tools are automatically deployed.
* Explicit tool selection, no surprises after renaming scylla to
  something else.
* Tools are discoverable via scylla's description.
* Follows the trend set by modern command line multi-command or multi-app
  programs, like git.

Fixes: #7801

Tests: unit(dev)
"

* 'tools-in-scylla-exec-v5' of https://github.com/denesb/scylla:
  main,tools,configure.py: fold tools into scylla exec
  tools: prepare for inclusion in scylla's main
  main: add skeleton switching code on argv[1]
  main: extract scylla specific code into scylla_main()
This commit is contained in:
Avi Kivity
2022-01-04 16:50:00 +02:00
5 changed files with 93 additions and 13 deletions

View File

@@ -569,8 +569,6 @@ raft_tests = set([
apps = set([
'scylla',
'test/tools/cql_repl',
'tools/scylla-types',
'tools/scylla-sstable',
])
tests = scylla_tests | perf_tests | raft_tests
@@ -1147,12 +1145,11 @@ scylla_tests_dependencies = scylla_core + idls + scylla_tests_generic_dependenci
scylla_raft_dependencies = scylla_raft_core + ['utils/uuid.cc']
scylla_tools = ['tools/scylla-types.cc', 'tools/scylla-sstable.cc', 'tools/schema_loader.cc']
deps = {
'scylla': idls + ['main.cc'] + scylla_core + api + alternator + redis,
'scylla': idls + ['main.cc'] + scylla_core + api + alternator + redis + scylla_tools,
'test/tools/cql_repl': idls + ['test/tools/cql_repl.cc'] + scylla_core + scylla_tests_generic_dependencies,
#FIXME: we don't need all of scylla_core here, only the types module, need to modularize scylla_core.
'tools/scylla-types': idls + ['tools/scylla-types.cc'] + scylla_core,
'tools/scylla-sstable': idls + ['tools/scylla-sstable.cc', 'tools/schema_loader.cc'] + scylla_core,
}
pure_boost_tests = set([

58
main.cc
View File

@@ -96,6 +96,7 @@
#include "service/storage_proxy.hh"
#include "alternator/controller.hh"
#include "alternator/ttl.hh"
#include "tools/entry_point.hh"
#include "service/raft/raft_group_registry.hh"
@@ -399,7 +400,7 @@ sharded<database>* the_database;
sharded<streaming::stream_manager> *the_stream_manager;
}
int main(int ac, char** av) {
static int scylla_main(int ac, char** av) {
// Allow core dumps. The would be disabled by default if
// CAP_SYS_NICE was added to the binary, as is suggested by the
// epoll backend.
@@ -410,14 +411,24 @@ int main(int ac, char** av) {
}
try {
// early check to avoid triggering
if (!cpu_sanity()) {
_exit(71);
}
runtime::init_uptime();
std::setvbuf(stdout, nullptr, _IOLBF, 1000);
app_template::config app_cfg;
app_cfg.name = "Scylla";
app_cfg.description =
R"(scylla - NoSQL data store using the seastar framework, compatible with Apache Cassandra
For more information, see https://github.com/scylladb/scylla.
The scylla executable hosts multiple apps:
* server (default) - the scylla server itself.
* types - a command-line tool to examine values belonging to scylla types.
* sstable - a multifunctional command-line tool to examine the content of sstables.
Usage: scylla {app_name} [...]
For more information about individual apps, run: scylla {app_name} --help
)";
app_cfg.default_task_quota = 500us;
app_cfg.auto_handle_sigint_sigterm = false;
app_cfg.max_networking_aio_io_control_blocks = 50000;
@@ -1457,3 +1468,40 @@ int main(int ac, char** av) {
return 7; // 1 has a special meaning for upstart
}
}
int main(int ac, char** av) {
// early check to avoid triggering
if (!cpu_sanity()) {
_exit(71);
}
std::function<int(int, char**)> main_func;
std::string exec_name;
if (ac >= 2) {
exec_name = av[1];
}
bool recognized = true;
if (exec_name == "server") {
main_func = scylla_main;
} else if (exec_name == "types") {
main_func = tools::scylla_types_main;
} else if (exec_name == "sstable") {
main_func = tools::scylla_sstable_main;
} else {
fmt::print("Unrecognized or missing app name (argv[1]={}), assuming server\n", exec_name);
main_func = scylla_main;
recognized = false;
}
if (recognized) {
// shift args to consume the recognized app name
--ac;
for (int i = 1; i < ac; ++i) {
std::swap(av[i], av[i + 1]);
}
}
return main_func(ac, av);
}

27
tools/entry_point.hh Normal file
View File

@@ -0,0 +1,27 @@
/*
* Copyright (C) 2021-present ScyllaDB
*/
/*
* This file is part of Scylla.
*
* Scylla is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Scylla is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Scylla. If not, see <http://www.gnu.org/licenses/>.
*/
namespace tools {
int scylla_types_main(int argc, char** argv);
int scylla_sstable_main(int argc, char** argv);
} // namespace tools

View File

@@ -1110,7 +1110,9 @@ const std::vector<operation> operations{
} // anonymous namespace
int main(int argc, char** argv) {
namespace tools {
int scylla_sstable_main(int argc, char** argv) {
app_template::config app_cfg;
app_cfg.name = app_name;
@@ -1243,3 +1245,5 @@ $ scylla-sstable --validate /path/to/md-123456-big-Data.db /path/to/md-123457-bi
});
});
}
} // namespace tools

View File

@@ -167,7 +167,9 @@ const std::vector<action_handler> action_handlers = {
}
int main(int argc, char** argv) {
namespace tools {
int scylla_types_main(int argc, char** argv) {
namespace bpo = boost::program_options;
app_template::config app_cfg;
@@ -254,3 +256,5 @@ $ scylla-types --print --prefix-compound -t TimeUUIDType -t Int32Type 0010d00819
return make_ready_future<>();
});
}
} // namespace tools