Verified Commit e0b754a1 authored by Alberto Miranda's avatar Alberto Miranda ♨️
Browse files

Add control utils for `cargo`

- `cargo_ping`: Send a ping to a Cargo server
- `cargo_shutdown`: Send a shutdwon request to a Cargo server
parent 6da96341
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -322,6 +322,7 @@ endif ()
add_subdirectory(etc)
add_subdirectory(lib)
add_subdirectory(src)
add_subdirectory(util)

if(CARGO_BUILD_TESTS)
  add_subdirectory(tests)
+12 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ master_server::master_server(std::string name, std::string address,

#define EXPAND(rpc_name) #rpc_name##s, &master_server::rpc_name
    provider::define(EXPAND(ping));
    provider::define(EXPAND(shutdown));
    provider::define(EXPAND(transfer_datasets));
    provider::define(EXPAND(transfer_status));

@@ -161,6 +162,17 @@ master_server::ping(const network::request& req) {
    req.respond(resp);
}

void master_server::shutdown(const network::request& req) {
    using network::get_address;
    using network::rpc_info;
    using proto::generic_response;

    const auto rpc = rpc_info::create(RPC_NAME(), get_address(req));

    LOGGER_INFO("rpc {:>} body: {{}}", rpc);
    server::shutdown();
}

void
master_server::transfer_datasets(const network::request& req,
                                 const std::vector<dataset>& sources,
+3 −0
Original line number Diff line number Diff line
@@ -47,6 +47,9 @@ private:
    void
    ping(const network::request& req);

    void
    shutdown(const network::request& req);

    void
    transfer_datasets(const network::request& req,
                      const std::vector<cargo::dataset>& sources,

util/CMakeLists.txt

0 → 100644
+57 −0
Original line number Diff line number Diff line
################################################################################
# Copyright 2022-2023, Barcelona Supercomputing Center (BSC), Spain            #
#                                                                              #
# This software was partially supported by the EuroHPC-funded project ADMIRE   #
#   (Project ID: 956748, https://www.admire-eurohpc.eu).                       #
#                                                                              #
# This file is part of Cargo.                                                  #
#                                                                              #
# Cargo is free software: you can redistribute it and/or modify                #
# it under the terms of the GNU General Public License as published by         #
# the Free Software Foundation, either version 3 of the License, or            #
# (at your option) any later version.                                          #
#                                                                              #
# Cargo 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 Cargo.  If not, see <https://www.gnu.org/licenses/>.              #
#                                                                              #
# SPDX-License-Identifier: GPL-3.0-or-later                                    #
################################################################################

add_executable(cargo_ping)

target_sources(cargo_ping
  PRIVATE
    ping.cpp
)

target_link_libraries(cargo_ping
  PUBLIC
    fmt::fmt
    CLI11::CLI11
    net::rpc_client
    cargo
)

add_executable(cargo_shutdown)

target_sources(cargo_shutdown
  PRIVATE
    shutdown.cpp
)

target_link_libraries(cargo_shutdown
        PUBLIC
        fmt::fmt
        CLI11::CLI11
        net::rpc_client
        cargo
)

install(TARGETS cargo_ping cargo_shutdown
        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

util/ping.cpp

0 → 100644
+103 −0
Original line number Diff line number Diff line
/******************************************************************************
 * Copyright 2022-2023, Barcelona Supercomputing Center (BSC), Spain
 *
 * This software was partially supported by the EuroHPC-funded project ADMIRE
 *   (Project ID: 956748, https://www.admire-eurohpc.eu).
 *
 * This file is part of Cargo.
 *
 * Cargo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Cargo 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 Cargo.  If not, see <https://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 *****************************************************************************/

#include <fmt/format.h>
#include <cargo.hpp>
#include <filesystem>
#include <CLI/CLI.hpp>
#include <net/client.hpp>
#include <net/endpoint.hpp>

struct ping_config {
    std::string progname;
    std::string server_address;
};

ping_config
parse_command_line(int argc, char* argv[]) {

    ping_config cfg;

    cfg.progname = std::filesystem::path{argv[0]}.filename().string();

    CLI::App app{"Cargo ping client", cfg.progname};

    app.add_option("-s,--server", cfg.server_address, "Server address")
            ->option_text("ADDRESS")
            ->required();

    try {
        app.parse(argc, argv);
        return cfg;
    } catch(const CLI::ParseError& ex) {
        std::exit(app.exit(ex));
    }
}

auto
parse_address(const std::string& address) {
    const auto pos = address.find("://");
    if(pos == std::string::npos) {
        throw std::runtime_error(fmt::format("Invalid address: {}", address));
    }

    const auto protocol = address.substr(0, pos);
    return std::make_pair(protocol, address);
}


int
main(int argc, char* argv[]) {

    ping_config cfg = parse_command_line(argc, argv);

    try {
        const auto [protocol, address] = parse_address(cfg.server_address);
        network::client rpc_client{protocol};

        if(const auto result = rpc_client.lookup(address); result.has_value()) {
            const auto& endpoint = result.value();
            const auto retval = endpoint.call("ping");

            if(retval.has_value()) {

                auto error_code = int{retval.value()};

                fmt::print("ping RPC was successful!\n");
                fmt::print("  (server replied with: {})\n", error_code);
                return EXIT_SUCCESS;
            }

            fmt::print(stderr, "ping RPC failed\n");
            return EXIT_FAILURE;

        } else {
            fmt::print(stderr, "Failed to lookup address: {}\n", address);
            return EXIT_FAILURE;
        }
    } catch(const std::exception& ex) {
        fmt::print(stderr, "Error: {}\n", ex.what());
        return EXIT_FAILURE;
    }
}
Loading