daemon/rpc: updates command and RPC

subcommands "check", "download", and "update".
update is not yet implemented.
This commit is contained in:
moneromooo-monero 2017-02-24 23:16:13 +00:00
parent beee286c7b
commit ea873ceb2c
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
8 changed files with 199 additions and 0 deletions

View file

@ -552,4 +552,15 @@ bool t_command_parser_executor::print_blockchain_dynamic_stats(const std::vector
return m_executor.print_blockchain_dynamic_stats(nblocks); return m_executor.print_blockchain_dynamic_stats(nblocks);
} }
bool t_command_parser_executor::update(const std::vector<std::string>& args)
{
if(args.size() != 1)
{
std::cout << "Exactly one parameter is needed: check, download, or update" << std::endl;
return false;
}
return m_executor.update(args.front());
}
} // namespace daemonize } // namespace daemonize

View file

@ -130,6 +130,8 @@ public:
bool alt_chain_info(const std::vector<std::string>& args); bool alt_chain_info(const std::vector<std::string>& args);
bool print_blockchain_dynamic_stats(const std::vector<std::string>& args); bool print_blockchain_dynamic_stats(const std::vector<std::string>& args);
bool update(const std::vector<std::string>& args);
}; };
} // namespace daemonize } // namespace daemonize

View file

@ -243,6 +243,11 @@ t_command_server::t_command_server(
, std::bind(&t_command_parser_executor::print_blockchain_dynamic_stats, &m_parser, p::_1) , std::bind(&t_command_parser_executor::print_blockchain_dynamic_stats, &m_parser, p::_1)
, "Print information about current blockchain dynamic state" , "Print information about current blockchain dynamic state"
); );
m_command_lookup.set_handler(
"update"
, std::bind(&t_command_parser_executor::update, &m_parser, p::_1)
, "subcommands: check (check if an update is available), download (download it is there is), update (not implemented)"
);
} }
bool t_command_server::process_command_str(const std::string& cmd) bool t_command_server::process_command_str(const std::string& cmd)

View file

@ -1580,4 +1580,51 @@ bool t_rpc_command_executor::print_blockchain_dynamic_stats(uint64_t nblocks)
return true; return true;
} }
bool t_rpc_command_executor::update(const std::string &command)
{
cryptonote::COMMAND_RPC_UPDATE::request req;
cryptonote::COMMAND_RPC_UPDATE::response res;
epee::json_rpc::error error_resp;
std::string fail_message = "Problem fetching info";
req.command = command;
if (m_is_rpc)
{
if (!m_rpc_client->rpc_request(req, res, "/update", fail_message.c_str()))
{
return true;
}
}
else
{
if (!m_rpc_server->on_update(req, res) || res.status != CORE_RPC_STATUS_OK)
{
tools::fail_msg_writer() << fail_message.c_str();
return true;
}
}
if (!res.update)
{
tools::msg_writer() << "No update available";
return true;
}
tools::msg_writer() << "Update available: v" << res.version << ": " << res.user_uri << ", hash " << res.hash;
if (command == "check")
return true;
if (!res.path.empty())
tools::msg_writer() << "Update downloaded to: " << res.path;
else
tools::msg_writer() << "Update download failed: " << res.status;
if (command == "download")
return true;
tools::msg_writer() << "'update' not implemented yet";
return true;
}
}// namespace daemonize }// namespace daemonize

View file

@ -151,6 +151,8 @@ public:
bool alt_chain_info(); bool alt_chain_info();
bool print_blockchain_dynamic_stats(uint64_t nblocks); bool print_blockchain_dynamic_stats(uint64_t nblocks);
bool update(const std::string &command);
}; };
} // namespace daemonize } // namespace daemonize

View file

@ -33,6 +33,9 @@ using namespace epee;
#include "core_rpc_server.h" #include "core_rpc_server.h"
#include "common/command_line.h" #include "common/command_line.h"
#include "common/updates.h"
#include "common/download.h"
#include "common/util.h"
#include "cryptonote_basic/cryptonote_format_utils.h" #include "cryptonote_basic/cryptonote_format_utils.h"
#include "cryptonote_basic/account.h" #include "cryptonote_basic/account.h"
#include "cryptonote_basic/cryptonote_basic_impl.h" #include "cryptonote_basic/cryptonote_basic_impl.h"
@ -1455,6 +1458,98 @@ namespace cryptonote
return true; return true;
} }
//------------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_update(const COMMAND_RPC_UPDATE::request& req, COMMAND_RPC_UPDATE::response& res)
{
static const char software[] = "monero";
#ifdef BUILDTAG
static const char buildtag[] = BOOST_PP_STRINGIZE(BUILDTAG);
#else
static const char buildtag[] = "source";
#endif
if (req.command != "check" && req.command != "download" && req.command != "update")
{
res.status = std::string("unknown command: '") + req.command + "'";
return true;
}
std::string version, hash;
if (!tools::check_updates(software, buildtag, version, hash))
{
res.status = "Error checking for updates";
return true;
}
if (tools::vercmp(version.c_str(), MONERO_VERSION) <= 0)
{
res.update = false;
res.status = CORE_RPC_STATUS_OK;
return true;
}
res.update = true;
res.version = version;
res.user_uri = tools::get_update_url(software, "cli", buildtag, version, true);
res.auto_uri = tools::get_update_url(software, "cli", buildtag, version, false);
res.hash = hash;
if (req.command == "check")
{
res.status = CORE_RPC_STATUS_OK;
return true;
}
boost::filesystem::path path;
if (req.path.empty())
{
std::string filename;
const char *slash = strrchr(res.auto_uri.c_str(), '/');
if (slash)
filename = slash + 1;
else
filename = std::string(software) + "-update-" + version;
path = epee::string_tools::get_current_module_folder();
path /= filename;
}
else
{
path = req.path;
}
crypto::hash file_hash;
if (!tools::sha256sum(path.string(), file_hash) || (hash != epee::string_tools::pod_to_hex(file_hash)))
{
MDEBUG("We don't have that file already, downloading");
if (!tools::download(path.string(), res.auto_uri))
{
MERROR("Failed to download " << res.auto_uri);
return false;
}
if (!tools::sha256sum(path.string(), file_hash))
{
MERROR("Failed to hash " << path);
return false;
}
if (hash != epee::string_tools::pod_to_hex(file_hash))
{
MERROR("Download from " << res.auto_uri << " does not match the expected hash");
return false;
}
MINFO("New version downloaded to " << path);
}
else
{
MDEBUG("We already have " << path << " with expected hash");
}
res.path = path.string();
if (req.command == "download")
{
res.status = CORE_RPC_STATUS_OK;
return true;
}
res.status = "'update' not implemented yet";
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
const command_line::arg_descriptor<std::string> core_rpc_server::arg_rpc_bind_port = { const command_line::arg_descriptor<std::string> core_rpc_server::arg_rpc_bind_port = {
"rpc-bind-port" "rpc-bind-port"

View file

@ -98,6 +98,7 @@ namespace cryptonote
MAP_URI_AUTO_JON2_IF("/start_save_graph", on_start_save_graph, COMMAND_RPC_START_SAVE_GRAPH, !m_restricted) MAP_URI_AUTO_JON2_IF("/start_save_graph", on_start_save_graph, COMMAND_RPC_START_SAVE_GRAPH, !m_restricted)
MAP_URI_AUTO_JON2_IF("/stop_save_graph", on_stop_save_graph, COMMAND_RPC_STOP_SAVE_GRAPH, !m_restricted) MAP_URI_AUTO_JON2_IF("/stop_save_graph", on_stop_save_graph, COMMAND_RPC_STOP_SAVE_GRAPH, !m_restricted)
MAP_URI_AUTO_JON2("/get_outs", on_get_outs, COMMAND_RPC_GET_OUTPUTS) MAP_URI_AUTO_JON2("/get_outs", on_get_outs, COMMAND_RPC_GET_OUTPUTS)
MAP_URI_AUTO_JON2_IF("/update", on_update, COMMAND_RPC_UPDATE, !m_restricted)
BEGIN_JSON_RPC_MAP("/json_rpc") BEGIN_JSON_RPC_MAP("/json_rpc")
MAP_JON_RPC("getblockcount", on_getblockcount, COMMAND_RPC_GETBLOCKCOUNT) MAP_JON_RPC("getblockcount", on_getblockcount, COMMAND_RPC_GETBLOCKCOUNT)
MAP_JON_RPC_WE("on_getblockhash", on_getblockhash, COMMAND_RPC_GETBLOCKHASH) MAP_JON_RPC_WE("on_getblockhash", on_getblockhash, COMMAND_RPC_GETBLOCKHASH)
@ -148,6 +149,7 @@ namespace cryptonote
bool on_out_peers(const COMMAND_RPC_OUT_PEERS::request& req, COMMAND_RPC_OUT_PEERS::response& res); bool on_out_peers(const COMMAND_RPC_OUT_PEERS::request& req, COMMAND_RPC_OUT_PEERS::response& res);
bool on_start_save_graph(const COMMAND_RPC_START_SAVE_GRAPH::request& req, COMMAND_RPC_START_SAVE_GRAPH::response& res); bool on_start_save_graph(const COMMAND_RPC_START_SAVE_GRAPH::request& req, COMMAND_RPC_START_SAVE_GRAPH::response& res);
bool on_stop_save_graph(const COMMAND_RPC_STOP_SAVE_GRAPH::request& req, COMMAND_RPC_STOP_SAVE_GRAPH::response& res); bool on_stop_save_graph(const COMMAND_RPC_STOP_SAVE_GRAPH::request& req, COMMAND_RPC_STOP_SAVE_GRAPH::response& res);
bool on_update(const COMMAND_RPC_UPDATE::request& req, COMMAND_RPC_UPDATE::response& res);
//json_rpc //json_rpc
bool on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res); bool on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res);

View file

@ -1438,4 +1438,39 @@ namespace cryptonote
END_KV_SERIALIZE_MAP() END_KV_SERIALIZE_MAP()
}; };
}; };
struct COMMAND_RPC_UPDATE
{
struct request
{
std::string command;
std::string path;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(command);
KV_SERIALIZE(path);
END_KV_SERIALIZE_MAP()
};
struct response
{
std::string status;
bool update;
std::string version;
std::string user_uri;
std::string auto_uri;
std::string hash;
std::string path;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(status)
KV_SERIALIZE(update)
KV_SERIALIZE(version)
KV_SERIALIZE(user_uri)
KV_SERIALIZE(auto_uri)
KV_SERIALIZE(hash)
KV_SERIALIZE(path)
END_KV_SERIALIZE_MAP()
};
};
} }