Exception handling in case of unconfigured or not-installed ceph mons
Change-Id: I5371cc9085f0d501d23f8f91b352ed0e08598880 Closes-Bug: #1453975
This commit is contained in:
parent
d9d488c4c6
commit
6be8322593
@ -32,7 +32,7 @@ module Astute
|
||||
end
|
||||
|
||||
if result[:data][:exit_code] != 0
|
||||
Astute.logger.debug "Ceph has been not found or has not been configured propertly." \
|
||||
Astute.logger.debug "Ceph has not been found or has not been configured properly" \
|
||||
" Safely removing nodes..."
|
||||
return answer
|
||||
end
|
||||
@ -85,8 +85,21 @@ module Astute
|
||||
return answer if ceph_mon_nodes.empty?
|
||||
|
||||
#Get the list of mon nodes
|
||||
shell = MClient.new(ctx, "execute_shell_command", [ceph_mon_nodes[0]["id"]], timeout=120, retries=1)
|
||||
result = shell.execute(:cmd => "ceph -f json mon dump").first.results
|
||||
result = {}
|
||||
shell = nil
|
||||
|
||||
ceph_mon_nodes.each do |ceph_mon_node|
|
||||
shell = MClient.new(ctx, "execute_shell_command", [ceph_mon_node["id"]], timeout=120, retries=1)
|
||||
result = shell.execute(:cmd => "ceph -f json mon dump").first.results
|
||||
break if result[:data][:exit_code] == 0
|
||||
end
|
||||
|
||||
if result[:data][:exit_code] != 0
|
||||
Astute.logger.debug "Ceph mon has not been found or has not been configured properly" \
|
||||
" Safely removing nodes..."
|
||||
return answer
|
||||
end
|
||||
|
||||
mon_dump = JSON.parse(result[:data][:stdout])
|
||||
left_mons = mon_dump['mons'].select { | n | n if ! ceph_mons.include? n['name'] }
|
||||
left_mon_names = left_mons.collect { |n| n['name'] }
|
||||
@ -94,14 +107,14 @@ module Astute
|
||||
|
||||
#Remove nodes from ceph cluster
|
||||
Astute.logger.info("Removing ceph mons #{ceph_mons} from cluster")
|
||||
ceph_mon_nodes.each do | node |
|
||||
ceph_mon_nodes.each do |node|
|
||||
shell = MClient.new(ctx, "execute_shell_command", [node["id"]], timeout=120, retries=1)
|
||||
#remove node from ceph mon list
|
||||
shell.execute(:cmd => "ceph mon remove #{node["slave_name"]}").first.results
|
||||
end
|
||||
|
||||
#Fix the ceph.conf on the left mon nodes
|
||||
left_mon_names.each do | node |
|
||||
left_mon_names.each do |node|
|
||||
mon_initial_members_cmd = "sed -i \"s/mon_initial_members.*/mon_initial_members\ = #{left_mon_names.join(" ")}/g\" /etc/ceph/ceph.conf"
|
||||
mon_host_cmd = "sed -i \"s/mon_host.*/mon_host\ = #{left_mon_ips.join(" ")}/g\" /etc/ceph/ceph.conf"
|
||||
shell = MClient.new(ctx, "execute_shell_command", [node.split('-')[1]], timeout=120, retries=1)
|
||||
|
@ -15,9 +15,8 @@
|
||||
|
||||
require File.join(File.dirname(__FILE__), '../spec_helper')
|
||||
|
||||
describe '#check_ceph_osds' do
|
||||
describe Astute::PreDelete do
|
||||
include SpecHelpers
|
||||
|
||||
let(:ctx) { mock_ctx }
|
||||
let(:success_result) { {"status"=>"ready"} }
|
||||
|
||||
@ -38,89 +37,164 @@ describe '#check_ceph_osds' do
|
||||
[mock_result]
|
||||
end
|
||||
|
||||
context "no ceph-osd nodes" do
|
||||
describe '#check_ceph_osds' do
|
||||
|
||||
context "no ceph-osd nodes" do
|
||||
let(:nodes) { [
|
||||
{"id" => "1", "roles" => ["controller"]},
|
||||
{"id" => "2", "roles" => ["compute"]}
|
||||
]
|
||||
}
|
||||
|
||||
it "should do nothing if no nodes have ceph-osd role" do
|
||||
expect(Astute::PreDelete.check_ceph_osds(ctx, nodes)).to eq(success_result)
|
||||
end
|
||||
end
|
||||
|
||||
context "nodes with ceph-osd role" do
|
||||
let(:nodes) { [
|
||||
{"id" => "1", "roles" => ["primary-controller"]},
|
||||
{"id" => "2", "roles" => ["compute", "ceph-osd"],
|
||||
"slave_name" => "node-2"}
|
||||
]
|
||||
}
|
||||
let(:pg_cmd) {
|
||||
cmd = "ceph pg dump 2>/dev/null | " \
|
||||
"awk '//{print $14, $16}' | " \
|
||||
"egrep -o '\\<(1|2)\\>' | " \
|
||||
"sort -un"
|
||||
}
|
||||
let(:osd_cmd) { "ceph -f json osd tree" }
|
||||
let(:json_resp) { '{"nodes": [{"name": "node-2", "children": [1,2]}]}'}
|
||||
let(:error_result) do
|
||||
msg = "Ceph data still exists on: node-2. You must manually " \
|
||||
"remove the OSDs from the cluster and allow Ceph to " \
|
||||
"rebalance before deleting these nodes."
|
||||
{"status" => "error", "error" => msg}
|
||||
end
|
||||
|
||||
it "should raise error if OSDs contain data" do
|
||||
mclient.expects(:execute).with({:cmd => osd_cmd})
|
||||
.returns(build_mcresult(stdout=json_resp))
|
||||
|
||||
mclient.expects(:execute).with({:cmd => pg_cmd})
|
||||
.returns(build_mcresult(stdout="1\n2"))
|
||||
|
||||
expect(Astute::PreDelete.check_ceph_osds(ctx, nodes)).to eq(error_result)
|
||||
end
|
||||
|
||||
it 'should ignore nodes with unconfigured or failed ceph' do
|
||||
mclient.expects(:execute).with({:cmd => osd_cmd}).twice
|
||||
.returns(build_mcresult(stdout="", "2", 42))
|
||||
.then.returns(build_mcresult(stdout=json_resp, "3", 1))
|
||||
|
||||
mclient.expects(:execute).with({:cmd => pg_cmd}).never
|
||||
all_nodes = nodes + [{
|
||||
"id" => "3",
|
||||
"roles" => ["compute", "ceph-osd"],
|
||||
"slave_name" => "node-3"}
|
||||
]
|
||||
expect(Astute::PreDelete.check_ceph_osds(ctx, all_nodes)).to eq(success_result)
|
||||
end
|
||||
|
||||
it 'should find live ceph installation' do
|
||||
mclient.expects(:execute).with({:cmd => osd_cmd}).twice
|
||||
.returns(build_mcresult(stdout="", "2", 42))
|
||||
.then.returns(build_mcresult(stdout=json_resp, "3", 0))
|
||||
|
||||
mclient.expects(:execute).with({:cmd => pg_cmd})
|
||||
.returns(build_mcresult(stdout="1\n2"))
|
||||
|
||||
all_nodes = nodes + [{
|
||||
"id" => "3",
|
||||
"roles" => ["compute", "ceph-osd"],
|
||||
"slave_name" => "node-3"}
|
||||
]
|
||||
expect(Astute::PreDelete.check_ceph_osds(ctx, all_nodes)).to eq(error_result)
|
||||
end
|
||||
|
||||
it "should succeed with no pgs placed on node" do
|
||||
mclient.expects(:execute).with({:cmd => osd_cmd})
|
||||
.returns(build_mcresult(stdout=json_resp))
|
||||
|
||||
mclient.expects(:execute).with({:cmd => pg_cmd})
|
||||
.returns(build_mcresult(stdout="3\n4"))
|
||||
|
||||
expect(Astute::PreDelete.check_ceph_osds(ctx, nodes)).to eq(success_result)
|
||||
end
|
||||
end
|
||||
|
||||
end # check_ceph_osds
|
||||
|
||||
describe '#remove_ceph_mons' do
|
||||
|
||||
let(:mon_cmd) { "ceph -f json mon dump" }
|
||||
let(:json_resp) do
|
||||
'{
|
||||
"epoch": 5,
|
||||
"mons": [
|
||||
{"name":"node-1", "addr":"192.168.0.11:6789\/0"},
|
||||
{"name":"node-2", "addr":"192.168.0.12:6789\/0"},
|
||||
{"name":"node-3", "addr":"192.168.0.13:6789\/0"}
|
||||
]
|
||||
}'
|
||||
end
|
||||
|
||||
def mon_rm_cmd(slave_name)
|
||||
"ceph mon remove #{slave_name}"
|
||||
end
|
||||
|
||||
let(:nodes) { [
|
||||
{"id" => "1", "roles" => ["controller"]},
|
||||
{"id" => "2", "roles" => ["compute"]}
|
||||
{"id" => "1", "roles" => ["controller"], "slave_name" => "node-1"},
|
||||
{"id" => "2", "roles" => ["controller"], "slave_name" => "node-2"}
|
||||
]
|
||||
}
|
||||
|
||||
it "should do nothing if no nodes have ceph-osd role" do
|
||||
expect(Astute::PreDelete.check_ceph_osds(ctx, nodes)).to eq(success_result)
|
||||
end
|
||||
end
|
||||
context "no ceph-mon nodes" do
|
||||
let(:nodes) { [
|
||||
{"id" => "3", "roles" => ["cinder"]},
|
||||
{"id" => "4", "roles" => ["compute"]}
|
||||
]
|
||||
}
|
||||
|
||||
context "nodes with ceph-osd role" do
|
||||
let(:nodes) { [
|
||||
{"id" => "1", "roles" => ["primary-controller"]},
|
||||
{"id" => "2", "roles" => ["compute", "ceph-osd"],
|
||||
"slave_name" => "node-2"}
|
||||
]
|
||||
}
|
||||
let(:pg_cmd) {
|
||||
cmd = "ceph pg dump 2>/dev/null | " \
|
||||
"awk '//{print $14, $16}' | " \
|
||||
"egrep -o '\\<(1|2)\\>' | " \
|
||||
"sort -un"
|
||||
}
|
||||
let(:osd_cmd) { "ceph -f json osd tree" }
|
||||
let(:json_resp) { '{"nodes": [{"name": "node-2", "children": [1,2]}]}'}
|
||||
let(:error_result) do
|
||||
msg = "Ceph data still exists on: node-2. You must manually " \
|
||||
"remove the OSDs from the cluster and allow Ceph to " \
|
||||
"rebalance before deleting these nodes."
|
||||
{"status" => "error", "error" => msg}
|
||||
it "should do nothing if no nodes have ceph-osd role" do
|
||||
expect(Astute::PreDelete.remove_ceph_mons(ctx, nodes)).to eq(success_result)
|
||||
end
|
||||
end
|
||||
|
||||
it "should raise error if OSDs contain data" do
|
||||
mclient.expects(:execute).with({:cmd => osd_cmd})
|
||||
.returns(build_mcresult(stdout=json_resp))
|
||||
it 'should ignore nodes with unconfigured or failed ceph mons' do
|
||||
mclient.expects(:execute).with({:cmd => mon_cmd}).twice
|
||||
.returns(build_mcresult(stdout="", "1", 42))
|
||||
.then.returns(build_mcresult(stdout=json_resp, "2", 1))
|
||||
|
||||
mclient.expects(:execute).with({:cmd => pg_cmd})
|
||||
.returns(build_mcresult(stdout="1\n2"))
|
||||
nodes.each do |node|
|
||||
mclient.expects(:execute).with({:cmd => mon_rm_cmd(node['slave_name'])}).never
|
||||
end
|
||||
|
||||
expect(Astute::PreDelete.check_ceph_osds(ctx, nodes)).to eq(error_result)
|
||||
expect(Astute::PreDelete.remove_ceph_mons(ctx, nodes)).to eq(success_result)
|
||||
end
|
||||
|
||||
it 'should ignore nodes with unconfigured or failed ceph' do
|
||||
mclient.expects(:execute).with({:cmd => osd_cmd}).twice
|
||||
.returns(build_mcresult(stdout="","2", 42))
|
||||
.then.returns(build_mcresult(stdout=json_resp,"3", 1))
|
||||
it 'should find and delete live ceph mon installation' do
|
||||
mclient.expects(:execute).with({:cmd => mon_cmd}).twice
|
||||
.returns(build_mcresult(stdout="", "1", 42))
|
||||
.then.returns(build_mcresult(stdout=json_resp, "2", 0))
|
||||
|
||||
mclient.expects(:execute).with({:cmd => pg_cmd}).never
|
||||
all_nodes = nodes + [{
|
||||
"id" => "3",
|
||||
"roles" => ["compute", "ceph-osd"],
|
||||
"slave_name" => "node-3"}
|
||||
]
|
||||
expect(Astute::PreDelete.check_ceph_osds(ctx, all_nodes)).to eq(success_result)
|
||||
nodes.each do |node|
|
||||
mclient.expects(:execute).with({:cmd => mon_rm_cmd(node['slave_name'])}).once
|
||||
.returns(build_mcresult(stdout="", node['id'], 0))
|
||||
end
|
||||
|
||||
mclient.expects(:execute).with({:cmd =>
|
||||
"sed -i \"s/mon_initial_members.*/mon_initial_members = node-3/g\" /etc/ceph/ceph.conf"})
|
||||
.returns(build_mcresult(stdout="", "3", 0))
|
||||
|
||||
mclient.expects(:execute).with({:cmd =>
|
||||
"sed -i \"s/mon_host.*/mon_host = 192.168.0.13/g\" /etc/ceph/ceph.conf"})
|
||||
.returns(build_mcresult(stdout="", "3", 0))
|
||||
|
||||
expect(Astute::PreDelete.remove_ceph_mons(ctx, nodes)).to eq(success_result)
|
||||
end
|
||||
|
||||
it 'should find live ceph installation' do
|
||||
mclient.expects(:execute).with({:cmd => osd_cmd}).twice
|
||||
.returns(build_mcresult(stdout="","2", 42))
|
||||
.then.returns(build_mcresult(stdout=json_resp,"3", 0))
|
||||
end # remove_ceph_mons
|
||||
|
||||
mclient.expects(:execute).with({:cmd => pg_cmd})
|
||||
.returns(build_mcresult(stdout="1\n2"))
|
||||
|
||||
all_nodes = nodes + [{
|
||||
"id" => "3",
|
||||
"roles" => ["compute", "ceph-osd"],
|
||||
"slave_name" => "node-3"}
|
||||
]
|
||||
expect(Astute::PreDelete.check_ceph_osds(ctx, all_nodes)).to eq(error_result)
|
||||
end
|
||||
|
||||
it "should succeed with no pgs placed on node" do
|
||||
mclient.expects(:execute).with({:cmd => osd_cmd})
|
||||
.returns(build_mcresult(stdout=json_resp))
|
||||
|
||||
mclient.expects(:execute).with({:cmd => pg_cmd})
|
||||
.returns(build_mcresult(stdout="3\n4"))
|
||||
|
||||
expect(Astute::PreDelete.check_ceph_osds(ctx, nodes)).to eq(success_result)
|
||||
end
|
||||
end
|
||||
|
||||
end # describe
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user