Skip to content
Snippets Groups Projects
util.cpp 3.49 KiB
Newer Older
  Copyright 2018-2020, Barcelona Supercomputing Center (BSC), Spain
  Copyright 2015-2020, Johannes Gutenberg Universitaet Mainz, Germany

  This software was partially supported by the
  EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu).

  This software was partially supported by the
  ADA-FS project under the SPPEXA project funded by the DFG.

  SPDX-License-Identifier: MIT
*/
#include <daemon/util.hpp>
#include <daemon/daemon.hpp>
#include <global/rpc/rpc_util.hpp>

#include <fstream>
#include <iostream>

#include <regex>

Marc Vef's avatar
Marc Vef committed
namespace gkfs::util {
void
populate_hosts_file() {
    const auto& hosts_file = GKFS_DATA->hosts_file();
    GKFS_DATA->spdlogger()->debug("{}() Populating hosts file: '{}'", __func__,
                                  hosts_file);
    ofstream lfstream(hosts_file, ios::out | ios::app);
    if(!lfstream) {
        throw runtime_error(fmt::format("Failed to open hosts file '{}': {}",
                                        hosts_file, strerror(errno)));
    lfstream << fmt::format("{} {}", gkfs::rpc::get_my_hostname(true),
                            RPC_DATA->self_addr_str())
             << std::endl;
    if(!lfstream) {
                fmt::format("Failed to write on hosts file '{}': {}",
                            hosts_file, strerror(errno)));
void
destroy_hosts_file() {
    std::remove(GKFS_DATA->hosts_file().c_str());
}

// hosts file functions copied from daemon - need Modifications for LOG and hostsfile path source
// TODO clean that up, probably best into global utilities - TBD How do we do logging there?
/**
 * Reads the daemon generator hosts file by a given path, returning hosts and URI addresses
 * @param path to hosts file
 * @return vector<pair<hosts, URI>>
 * @throws std::runtime_error
 */
vector<pair<string, string>> load_hostfile(const std::string& path) {

    //LOG(DEBUG, "Loading hosts file: \"{}\"", path);

    ifstream lf(path);
    if (!lf) {
        throw runtime_error(fmt::format("Failed to open hosts file '{}': {}",
                                        path, strerror(errno)));
    }
    vector<pair<string, string>> hosts;
    const regex line_re("^(\\S+)\\s+(\\S+)$",
                        regex::ECMAScript | regex::optimize);
    string line;
    string host;
    string uri;
    std::smatch match;
    while (getline(lf, line)) {
        if (!regex_match(line, match, line_re)) {

            //LOG(ERROR, "Unrecognized line format: [path: '{}', line: '{}']",
            //    path, line);

            throw runtime_error(
                    fmt::format("unrecognized line format: '{}'", line));
        }
        host = match[1];
        uri = match[2];
        hosts.emplace_back(host, uri);
    }
    if (hosts.empty()) {
        throw runtime_error("Hosts file found but no suitable addresses could be extracted");
    }
    // ??? extract_protocol(hosts[0].second);
    return hosts;
}

vector<pair<string, string>> read_hosts_file() {
    string hostfile = GKFS_DATA->hosts_file();

    vector<pair<string, string>> hosts;
    try {
        hosts = load_hostfile(hostfile);
    } catch (const exception& e) {
        auto emsg = fmt::format("Failed to load hosts file: {}", e.what());
        throw runtime_error(emsg);
    }

    if (hosts.empty()) {
        throw runtime_error(fmt::format("Hostfile empty: '{}'", hostfile));
    }

    GKFS_DATA->spdlogger()->info("Hosts pool size: {}", hosts.size());

    return hosts;
}
Marc Vef's avatar
Marc Vef committed
} // namespace gkfs::util