Start a temporary ClickHouse server, run init scripts, then stop it.
| 598 | |
| 599 | /// Start a temporary ClickHouse server, run init scripts, then stop it. |
| 600 | bool initClickHouseDB( |
| 601 | const std::string & config_file, |
| 602 | const std::string & data_dir, |
| 603 | const std::string & clickhouse_user, |
| 604 | const std::string & clickhouse_password, |
| 605 | uid_t run_uid, |
| 606 | gid_t run_gid, |
| 607 | const std::vector<std::string> & extra_server_args, |
| 608 | bool always_run_initdb) |
| 609 | { |
| 610 | /// Skip if data directory is already initialised and CLICKHOUSE_ALWAYS_RUN_INITDB_SCRIPTS is unset. |
| 611 | bool database_exists = fs::is_directory(data_dir + "/data"); |
| 612 | if (!always_run_initdb && database_exists) |
| 613 | { |
| 614 | std::cerr << "docker-init: ClickHouse data directory appears to contain a database; " |
| 615 | "skipping initialization\n"; |
| 616 | return true; |
| 617 | } |
| 618 | |
| 619 | std::string clickhouse_db = getEnv("CLICKHOUSE_DB"); |
| 620 | |
| 621 | /// Check whether /docker-entrypoint-initdb.d has any files. |
| 622 | std::error_code ec; |
| 623 | bool has_init_files = fs::is_directory("/docker-entrypoint-initdb.d", ec) |
| 624 | && fs::directory_iterator("/docker-entrypoint-initdb.d", ec) != fs::directory_iterator{}; |
| 625 | |
| 626 | if (!has_init_files && clickhouse_db.empty()) |
| 627 | return true; |
| 628 | |
| 629 | std::string native_port = extractConfigValue(config_file, "tcp_port"); |
| 630 | if (native_port.empty()) |
| 631 | native_port = "9000"; |
| 632 | |
| 633 | std::string run_as = std::to_string(run_uid) + ":" + std::to_string(run_gid); |
| 634 | |
| 635 | /// Start a temporary server bound only to localhost. |
| 636 | /// The "--" separator is required: positional arguments after "--" override config.xml |
| 637 | /// properties (e.g. --listen_host=127.0.0.1), while options before "--" are parsed by |
| 638 | /// Poco and must be registered. Without "--", Poco rejects "--listen_host" as unknown. |
| 639 | std::vector<std::string> server_args = { |
| 640 | g_clickhouse_binary, "su", run_as, "clickhouse-server", |
| 641 | "--config-file=" + config_file, |
| 642 | "--", "--listen_host=127.0.0.1", |
| 643 | }; |
| 644 | for (const auto & arg : extra_server_args) |
| 645 | server_args.push_back(arg); |
| 646 | |
| 647 | if (g_shutdown_requested) |
| 648 | return true; |
| 649 | |
| 650 | pid_t server_pid = fork(); |
| 651 | if (server_pid < 0) |
| 652 | { |
| 653 | std::cerr << "docker-init: failed to fork temporary server\n"; |
| 654 | return false; |
| 655 | } |
| 656 | |
| 657 | if (server_pid == 0) |
no test coverage detected