diff --git a/include/RaftManager.h b/include/RaftManager.h
index 594e23257a..71d54c074f 100644
--- a/include/RaftManager.h
+++ b/include/RaftManager.h
@@ -99,6 +99,12 @@ public:
// -------------------------------------------------------------------------
// Raft state query functions
// -------------------------------------------------------------------------
+ /**
+ * Return the Raft status in XML format
+ * @return xml document with the raft state
+ */
+ std::string& to_xml(std::string& state_xml);
+
/**
* Makes this server follower. Stop associated replication facilities
*/
diff --git a/include/RequestManagerZone.h b/include/RequestManagerZone.h
index bbc7933dbe..d2a27bfed4 100644
--- a/include/RequestManagerZone.h
+++ b/include/RequestManagerZone.h
@@ -112,4 +112,20 @@ public:
RequestAttributes& att);
};
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+
+class ZoneRaftStatus : public RequestManagerZone
+{
+public:
+ ZoneRaftStatus():
+ RequestManagerZone("ZoneRaftInformation", "Returns Raft status",
+ "A:s"){};
+
+ ~ZoneRaftStatus(){};
+
+ void request_execute(xmlrpc_c::paramList const& _paramList,
+ RequestAttributes& att);
+};
+
#endif
diff --git a/src/cli/one_helper/onezone_helper.rb b/src/cli/one_helper/onezone_helper.rb
index 23a1996c5b..f0967f9ca1 100644
--- a/src/cli/one_helper/onezone_helper.rb
+++ b/src/cli/one_helper/onezone_helper.rb
@@ -117,6 +117,42 @@ class OneZoneHelper < OpenNebulaHelper::OneHelper
zone_hash=zone.to_hash
if zone.has_elements?("/ZONE/SERVER_POOL/SERVER")
+ servers = zone_hash["ZONE"]["SERVER_POOL"]["SERVER"]
+
+ servers.each { |s|
+ endpoint = s["ENDPOINT"]
+
+ next if endpoint.nil?
+
+ client = OpenNebula::Client.new(nil, endpoint)
+
+ xml_doc = client.call("zone.raftstatus")
+
+ if OpenNebula::is_error?(xml_doc)
+ s["STATE"] = "error"
+ s["TERM"] = "-"
+ s["VOTEDFOR"] = "-"
+ s["COMMIT" ] = "-"
+ s["LOG_INDEX"] = "-"
+
+ next
+ end
+
+ xml_doc = Nokogiri::XML(xml_doc)
+
+ s["STATE"] = case xml_doc.root.at_xpath("STATE").text
+ when "0" then "solo"
+ when "1" then "candidate"
+ when "2" then "follower"
+ when "3" then "leader"
+ else "-"
+ end
+ s["TERM"] = xml_doc.root.at_xpath("TERM").text
+ s["VOTEDFOR"] = xml_doc.root.at_xpath("VOTEDFOR").text
+ s["COMMIT"] = xml_doc.root.at_xpath("COMMIT").text
+ s["LOG_INDEX"] = xml_doc.root.at_xpath("LOG_INDEX").text
+ }
+
puts
CLIHelper.print_header(str_h1 % "SERVERS",false)
@@ -130,10 +166,29 @@ class OneZoneHelper < OpenNebulaHelper::OneHelper
d["NAME"] if !d.nil?
end
- column :"ENDPOINT", "", :left, :size=>30 do |d|
- d["ENDPOINT"] if !d.nil?
+ column :"STATE", "", :left, :size=>10 do |d|
+ d["STATE"] if !d.nil?
end
+ column :"TERM", "", :left, :size=>10 do |d|
+ d["TERM"] if !d.nil?
+ end
+
+ column :"INDEX", "", :left, :size=>10 do |d|
+ d["LOG_INDEX"] if !d.nil?
+ end
+
+ column :"COMMIT", "", :left, :size=>10 do |d|
+ d["COMMIT"] if !d.nil?
+ end
+
+ column :"VOTE", "", :left, :size=>5 do |d|
+ d["VOTEDFOR"] if !d.nil?
+ end
+
+ column :"ENDPOINT", "", :left, :size=>18 do |d|
+ d["ENDPOINT"] if !d.nil?
+ end
end.show([zone_hash['ZONE']['SERVER_POOL']['SERVER']].flatten, {})
end
diff --git a/src/raft/RaftManager.cc b/src/raft/RaftManager.cc
index 605e4d1a7c..2d4589f513 100644
--- a/src/raft/RaftManager.cc
+++ b/src/raft/RaftManager.cc
@@ -1112,3 +1112,37 @@ int RaftManager::xmlrpc_request_vote(int follower_id, unsigned int lindex,
return xml_rc;
}
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+
+std::string& RaftManager::to_xml(std::string& raft_xml)
+{
+ Nebula& nd = Nebula::instance();
+ LogDB * logdb = nd.get_logdb();
+
+ unsigned int lindex, lterm;
+
+ std::ostringstream oss;
+
+ logdb->get_last_record_index(lindex, lterm);
+
+ pthread_mutex_lock(&mutex);
+
+ oss << ""
+ << "" << server_id << ""
+ << "" << state << ""
+ << "" << term << ""
+ << "" << votedfor << ""
+ << "" << commit << ""
+ << "" << lindex << ""
+ << "" << lterm << ""
+ << "";
+
+ pthread_mutex_unlock(&mutex);
+
+ raft_xml = oss.str();
+
+ return raft_xml;
+}
+
+
diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc
index a1a11fb5ab..7ad01a8897 100644
--- a/src/rm/RequestManager.cc
+++ b/src/rm/RequestManager.cc
@@ -789,6 +789,7 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr zone_delserver(zone_delserver_pt);
xmlrpc_c::methodPtr zone_replicatelog(new ZoneReplicateLog());
xmlrpc_c::methodPtr zone_voterequest(new ZoneVoteRequest());
+ xmlrpc_c::methodPtr zone_raftstatus(new ZoneRaftStatus());
xmlrpc_c::methodPtr zone_info(new ZoneInfo());
xmlrpc_c::methodPtr zonepool_info(new ZonePoolInfo());
@@ -800,6 +801,7 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.zone.rename", zone_rename);
RequestManagerRegistry.addMethod("one.zone.replicate",zone_replicatelog);
RequestManagerRegistry.addMethod("one.zone.voterequest",zone_voterequest);
+ RequestManagerRegistry.addMethod("one.zone.raftstatus", zone_raftstatus);
RequestManagerRegistry.addMethod("one.zone.addserver", zone_addserver);
RequestManagerRegistry.addMethod("one.zone.delserver", zone_delserver);
diff --git a/src/rm/RequestManagerZone.cc b/src/rm/RequestManagerZone.cc
index dd6c4420a2..244a6d18d0 100644
--- a/src/rm/RequestManagerZone.cc
+++ b/src/rm/RequestManagerZone.cc
@@ -303,4 +303,25 @@ void ZoneVoteRequest::request_execute(xmlrpc_c::paramList const& paramList,
success_response(static_cast(current_term), att);
}
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+
+void ZoneRaftStatus::request_execute(xmlrpc_c::paramList const& paramList,
+ RequestAttributes& att)
+{
+ Nebula& nd = Nebula::instance();
+
+ RaftManager * raftm = nd.get_raftm();
+
+ std::string raft_xml;
+
+ if ( basic_authorization(nd.get_zone_id(), att) == false )
+ {
+ return;
+ }
+
+ raftm->to_xml(raft_xml);
+
+ success_response(raft_xml, att);
+}