* refactoring (rename 'fast_provision' to 'provision', 'provision' to 'watch_provision_progress' and more)
* fix bug with ignoring node status for provision operation (+ test); * small test refactoring.
This commit is contained in:
parent
8b54068de0
commit
ba1c303b72
13
bin/astute
13
bin/astute
@ -97,14 +97,11 @@ if [:deploy, :provision, :provision_and_deploy].include? opts[:command]
|
||||
end
|
||||
|
||||
def console_provision(orchestrator, reporter, environment)
|
||||
res = orchestrator.fast_provision(reporter, environment['engine'], environment['nodes'])
|
||||
if res == Astute::SUCCESS
|
||||
puts "restarting nodes..."
|
||||
sleep 5
|
||||
puts "start watching progress"
|
||||
res = orchestrator.provision(reporter, environment['task_uuid'], environment['nodes'])
|
||||
end
|
||||
res
|
||||
orchestrator.provision(reporter, environment['engine'], environment['nodes'])
|
||||
puts "restarting nodes..."
|
||||
sleep 5
|
||||
puts "start watching progress"
|
||||
orchestrator.watch_provision_progress(reporter, environment['task_uuid'], environment['nodes'])
|
||||
end
|
||||
|
||||
result = Astute::SUCCESS
|
||||
|
@ -43,15 +43,17 @@ module Astute
|
||||
context.status
|
||||
end
|
||||
|
||||
def fast_provision(reporter, engine_attrs, nodes)
|
||||
raise "Nodes to provision are not provided!" if nodes.empty?
|
||||
def provision(reporter, engine_attrs, nodes_for_provision)
|
||||
raise "Nodes to provision are not provided!" if nodes_for_provision.empty?
|
||||
|
||||
# We need only those which are not ready/provisioned yet
|
||||
nodes = nodes_for_provision.select { |n| !['provisioned', 'ready'].include?(n['status']) }
|
||||
|
||||
engine = create_engine(engine_attrs, reporter)
|
||||
|
||||
begin
|
||||
add_nodes_to_cobbler(engine, nodes)
|
||||
reboot_events = reboot_nodes(engine, nodes)
|
||||
failed_nodes = check_reboot_nodes(engine, reboot_events)
|
||||
|
||||
rescue RuntimeError => e
|
||||
Astute.logger.error("Error occured while provisioning: #{e.inspect}")
|
||||
reporter.report({
|
||||
@ -59,14 +61,13 @@ module Astute
|
||||
'error' => 'Cobbler error',
|
||||
'progress' => 100
|
||||
})
|
||||
raise StopIteration
|
||||
raise e
|
||||
ensure
|
||||
engine.sync
|
||||
end
|
||||
|
||||
if failed_nodes.empty?
|
||||
report_result({}, reporter)
|
||||
return SUCCESS
|
||||
else
|
||||
Astute.logger.error("Nodes failed to reboot: #{failed_nodes.inspect}")
|
||||
reporter.report({
|
||||
@ -74,18 +75,12 @@ module Astute
|
||||
'error' => "Nodes failed to reboot: #{failed_nodes.inspect}",
|
||||
'progress' => 100
|
||||
})
|
||||
raise StopIteration
|
||||
raise e
|
||||
end
|
||||
end
|
||||
|
||||
def provision(reporter, task_id, nodes_up)
|
||||
raise "Nodes to provision are not provided!" if nodes_up.empty?
|
||||
|
||||
# We need only those which are not ready/provisioned yet
|
||||
nodes = []
|
||||
nodes_up.each do |n|
|
||||
nodes << n unless ['provisioned', 'ready'].include?(n['status'])
|
||||
end
|
||||
def watch_provision_progress(reporter, task_id, nodes)
|
||||
raise "Nodes to provision are not provided!" if nodes.empty?
|
||||
|
||||
nodes_uids = nodes.map { |n| n['uid'] }
|
||||
|
||||
@ -198,10 +193,10 @@ module Astute
|
||||
Astute::RedhatChecker.new(ctx, credentials).check_redhat_credentials
|
||||
rescue Astute::RedhatCheckingError => e
|
||||
Astute.logger.error("Error #{e.message}")
|
||||
raise StopIteration
|
||||
raise e
|
||||
rescue Exception => e
|
||||
Astute.logger.error("Unexpected error #{e.message} traceback #{e.format_backtrace}")
|
||||
raise StopIteration
|
||||
raise e
|
||||
end
|
||||
end
|
||||
|
||||
@ -211,10 +206,10 @@ module Astute
|
||||
Astute::RedhatChecker.new(ctx, credentials).check_redhat_licenses(nodes)
|
||||
rescue Astute::RedhatCheckingError => e
|
||||
Astute.logger.error("Error #{e.message}")
|
||||
raise StopIteration
|
||||
raise e
|
||||
rescue Exception => e
|
||||
Astute.logger.error("Unexpected error #{e.message} traceback #{e.format_backtrace}")
|
||||
raise StopIteration
|
||||
raise e
|
||||
end
|
||||
end
|
||||
|
||||
@ -236,23 +231,23 @@ module Astute
|
||||
end
|
||||
|
||||
def create_engine(engine_attrs, reporter)
|
||||
raise "Settings for Cobbler must be set" if engine_attrs.blank?
|
||||
|
||||
begin
|
||||
Astute.logger.info("Trying to instantiate cobbler engine: #{engine_attrs.inspect}")
|
||||
Astute::Provision::Cobbler.new(engine_attrs)
|
||||
rescue
|
||||
rescue => e
|
||||
Astute.logger.error("Error occured during cobbler initializing")
|
||||
|
||||
reporter.report({
|
||||
'status' => 'error',
|
||||
'error' => 'Cobbler can not be initialized',
|
||||
'progress' => 100
|
||||
})
|
||||
raise StopIteration
|
||||
raise e
|
||||
end
|
||||
end
|
||||
|
||||
def reboot_nodes(engine, nodes)
|
||||
reboot_events = {}
|
||||
def add_nodes_to_cobbler(engine, nodes)
|
||||
nodes.each do |node|
|
||||
begin
|
||||
Astute.logger.info("Adding #{node['name']} into cobbler")
|
||||
@ -262,6 +257,12 @@ module Astute
|
||||
Astute.logger.error("Error occured while adding system #{node['name']} to cobbler")
|
||||
raise e
|
||||
end
|
||||
end # end iteration
|
||||
end
|
||||
|
||||
def reboot_nodes(engine, nodes)
|
||||
reboot_events = {}
|
||||
nodes.each do |node|
|
||||
Astute.logger.debug("Trying to reboot node: #{node['name']}")
|
||||
reboot_events[node['name']] = engine.power_reboot(node['name'])
|
||||
end
|
||||
|
@ -45,12 +45,11 @@ describe Cobbler do
|
||||
end
|
||||
|
||||
it "should be able to be initialized with 'host', 'port', 'path'" do
|
||||
host = "host.domain.tld"
|
||||
port = "1234"
|
||||
path = "/api"
|
||||
username = 'user'
|
||||
password = 'pass'
|
||||
|
||||
host = "host.domain.tld"
|
||||
path = "/api"
|
||||
port = "1234"
|
||||
remote = mock() do
|
||||
expects(:call).with('login', username, password)
|
||||
end
|
||||
@ -78,8 +77,10 @@ describe Cobbler do
|
||||
XMLRPC::Client = mock() do
|
||||
stubs(:new).returns(remote)
|
||||
end
|
||||
|
||||
@data = {
|
||||
end
|
||||
|
||||
let(:data) do
|
||||
{
|
||||
'profile' => 'centos-x86_64',
|
||||
'power_type' => 'ssh',
|
||||
'power_user' => 'root',
|
||||
@ -146,7 +147,7 @@ describe Cobbler do
|
||||
end
|
||||
|
||||
it "item_from_hash should modify item with cobblerized data" do
|
||||
cobblerized_data = Astute::Provision::Cobsh.new(@data.merge({'what' => 'system', 'name' => 'name'})).cobblerized
|
||||
cobblerized_data = Astute::Provision::Cobsh.new(data.merge({'what' => 'system', 'name' => 'name'})).cobblerized
|
||||
cobbler = Astute::Provision::Cobbler.new
|
||||
cobbler.stubs(:get_item_id).with('system', 'name').returns('itemid')
|
||||
cobblerized_data.each do |opt, value|
|
||||
@ -160,11 +161,11 @@ describe Cobbler do
|
||||
'remotetoken'
|
||||
)
|
||||
end
|
||||
cobbler.item_from_hash('system', 'name', @data, :item_preremove => true)
|
||||
cobbler.item_from_hash('system', 'name', data, :item_preremove => true)
|
||||
end
|
||||
|
||||
it "item_from_hash should modify 'system' interfaces with cobblerized['interfaces']" do
|
||||
cobblerized_data = Astute::Provision::Cobsh.new(@data.merge({'what' => 'system', 'name' => 'name'})).cobblerized
|
||||
cobblerized_data = Astute::Provision::Cobsh.new(data.merge({'what' => 'system', 'name' => 'name'})).cobblerized
|
||||
cobbler = Astute::Provision::Cobbler.new
|
||||
cobbler.stubs(:get_item_id).with('system', 'name').returns('itemid')
|
||||
cobbler.remote.expects(:call).with(
|
||||
@ -173,7 +174,7 @@ describe Cobbler do
|
||||
'modify_interface',
|
||||
cobblerized_data['interfaces'],
|
||||
'remotetoken')
|
||||
cobbler.item_from_hash('system', 'name', @data, :item_preremove => true)
|
||||
cobbler.item_from_hash('system', 'name', data, :item_preremove => true)
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -215,10 +215,10 @@ describe Astute::Orchestrator do
|
||||
res.should eql({'nodes' => [{'uid' => '1'}, {'uid' => '2'}]})
|
||||
end
|
||||
|
||||
it "remove_nodes do not fail if any of nodes failed"
|
||||
xit "remove_nodes do not fail if any of nodes failed"
|
||||
|
||||
before(:all) do
|
||||
@data = {
|
||||
let(:data) do
|
||||
{
|
||||
"engine"=>{
|
||||
"url"=>"http://localhost/cobbler_api",
|
||||
"username"=>"cobbler",
|
||||
@ -266,33 +266,31 @@ describe Astute::Orchestrator do
|
||||
}
|
||||
}
|
||||
]
|
||||
}.freeze
|
||||
}
|
||||
end
|
||||
|
||||
describe '#fast_provision' do
|
||||
|
||||
|
||||
describe '#provision' do
|
||||
|
||||
context 'cobler cases' do
|
||||
it "raise error if cobler settings empty" do
|
||||
expect {@orchestrator.fast_provision(@reporter, {}, @data['nodes'])}.
|
||||
to raise_error(StopIteration)
|
||||
expect {@orchestrator.provision(@reporter, {}, data['nodes'])}.
|
||||
to raise_error(/Settings for Cobbler must be set/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'node state cases' do
|
||||
before(:each) do
|
||||
|
||||
remote = mock() do
|
||||
stubs(:call)
|
||||
stubs(:call).with('login', 'cobbler', 'cobbler').returns('remotetoken')
|
||||
end
|
||||
@tmp = XMLRPC::Client
|
||||
XMLRPC::Client = mock() do
|
||||
stubs(:new).returns(remote)
|
||||
end
|
||||
end
|
||||
|
||||
it "raises error if nodes list is empty" do
|
||||
expect {@orchestrator.fast_provision(@reporter, @data['engine'], {})}.
|
||||
expect {@orchestrator.provision(@reporter, data['engine'], {})}.
|
||||
to raise_error(/Nodes to provision are not provided!/)
|
||||
end
|
||||
|
||||
@ -301,13 +299,28 @@ describe Astute::Orchestrator do
|
||||
expects(:power_reboot).with('controller-1')
|
||||
end
|
||||
@orchestrator.stubs(:check_reboot_nodes).returns([])
|
||||
@orchestrator.fast_provision(@reporter, @data['engine'], @data['nodes'])
|
||||
@orchestrator.provision(@reporter, data['engine'], data['nodes'])
|
||||
end
|
||||
|
||||
it "should not provision nodes that ready for deploy" do
|
||||
nodes = deep_copy data['nodes']
|
||||
nodes << {'uid' => '2', 'status' => 'ready'}
|
||||
nodes << {'uid' => '3', 'status' => 'provisioned'}
|
||||
|
||||
engine = mock
|
||||
engine.stubs(:sync)
|
||||
@orchestrator.stubs(:create_engine).returns(engine)
|
||||
@orchestrator.stubs(:reboot_nodes).returns([])
|
||||
@orchestrator.stubs(:check_reboot_nodes).returns([])
|
||||
|
||||
@orchestrator.expects(:add_nodes_to_cobbler).with(engine, data['nodes'])
|
||||
|
||||
@orchestrator.provision(@reporter, data['engine'], nodes)
|
||||
end
|
||||
|
||||
before(:each) { Astute::Provision::Cobbler.any_instance.stubs(:power_reboot).returns(333) }
|
||||
|
||||
context 'node reboot success' do
|
||||
|
||||
before(:each) { Astute::Provision::Cobbler.any_instance.stubs(:event_status).
|
||||
returns([Time.now.to_f, 'controller-1', 'complete'])}
|
||||
|
||||
@ -315,47 +328,44 @@ describe Astute::Orchestrator do
|
||||
Astute::Provision::Cobbler.any_instance.stubs(:event_status).
|
||||
returns([Time.now.to_f, 'controller-1', 'complete'])
|
||||
|
||||
@orchestrator.fast_provision(@reporter, @data['engine'], @data['nodes'])
|
||||
@orchestrator.provision(@reporter, data['engine'], data['nodes'])
|
||||
end
|
||||
|
||||
it "report about success" do
|
||||
@reporter.expects(:report).with({'status' => 'ready', 'progress' => 100}).returns(true)
|
||||
@orchestrator.fast_provision(@reporter, @data['engine'], @data['nodes'])
|
||||
@orchestrator.provision(@reporter, data['engine'], data['nodes'])
|
||||
end
|
||||
|
||||
it "sync engine state" do
|
||||
Astute::Provision::Cobbler.any_instance do
|
||||
expects(:sync).once
|
||||
end
|
||||
@orchestrator.fast_provision(@reporter, @data['engine'], @data['nodes'])
|
||||
@orchestrator.provision(@reporter, data['engine'], data['nodes'])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'node reboot fail' do
|
||||
before(:each) { Astute::Provision::Cobbler.any_instance.stubs(:event_status).
|
||||
returns([Time.now.to_f, 'controller-1', 'failed'])}
|
||||
|
||||
it "should sync engine state" do
|
||||
Astute::Provision::Cobbler.any_instance do
|
||||
expects(:sync).once
|
||||
end
|
||||
begin
|
||||
@orchestrator.fast_provision(@reporter, @data['engine'], @data['nodes'])
|
||||
@orchestrator.provision(@reporter, data['engine'], data['nodes'])
|
||||
rescue
|
||||
end
|
||||
end
|
||||
|
||||
it "raise error if failed node find" do
|
||||
expect {@orchestrator.fast_provision(@reporter, @data['engine'], @data['nodes'])}.to raise_error(StopIteration)
|
||||
expect {@orchestrator.provision(@reporter, data['engine'], data['nodes'])}.to raise_error(TypeError)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
describe '#provision' do
|
||||
describe '#watch_provision_progress' do
|
||||
|
||||
before(:each) do
|
||||
# Disable sleeping in test env (doubles the test speed)
|
||||
@ -365,36 +375,36 @@ describe Astute::Orchestrator do
|
||||
end
|
||||
|
||||
it "raises error if nodes list is empty" do
|
||||
expect {@orchestrator.provision(@reporter, @data['task_uuid'], {})}.
|
||||
expect {@orchestrator.watch_provision_progress(@reporter, data['task_uuid'], {})}.
|
||||
to raise_error(/Nodes to provision are not provided!/)
|
||||
end
|
||||
|
||||
it "prepare provision log for parsing" do
|
||||
Astute::LogParser::ParseProvisionLogs.any_instance do
|
||||
expects(:prepare).with(@data['nodes']).once
|
||||
expects(:prepare).with(data['nodes']).once
|
||||
end
|
||||
@orchestrator.stubs(:report_about_progress).returns()
|
||||
@orchestrator.stubs(:node_type).returns([{'uid' => '1', 'node_type' => 'target' }])
|
||||
|
||||
@orchestrator.provision(@reporter, @data['task_uuid'], @data['nodes'])
|
||||
@orchestrator.watch_provision_progress(@reporter, data['task_uuid'], data['nodes'])
|
||||
end
|
||||
|
||||
it "ignore problem with parsing provision log" do
|
||||
Astute::LogParser::ParseProvisionLogs.any_instance do
|
||||
stubs(:prepare).with(@data['nodes']).raises
|
||||
stubs(:prepare).with(data['nodes']).raises
|
||||
end
|
||||
|
||||
@orchestrator.stubs(:report_about_progress).returns()
|
||||
@orchestrator.stubs(:node_type).returns([{'uid' => '1', 'node_type' => 'target' }])
|
||||
|
||||
@orchestrator.provision(@reporter, @data['task_uuid'], @data['nodes'])
|
||||
@orchestrator.watch_provision_progress(@reporter, data['task_uuid'], data['nodes'])
|
||||
end
|
||||
|
||||
it 'provision nodes using mclient' do
|
||||
@orchestrator.stubs(:report_about_progress).returns()
|
||||
@orchestrator.expects(:node_type).returns([{'uid' => '1', 'node_type' => 'target' }])
|
||||
|
||||
@orchestrator.provision(@reporter, @data['task_uuid'], @data['nodes'])
|
||||
@orchestrator.watch_provision_progress(@reporter, data['task_uuid'], data['nodes'])
|
||||
end
|
||||
|
||||
it "fail if timeout of provisioning is exceeded" do
|
||||
@ -412,7 +422,7 @@ describe Astute::Orchestrator do
|
||||
'error_type' => 'provision'}]}
|
||||
|
||||
@reporter.expects(:report).with(error_mgs).once
|
||||
@orchestrator.provision(@reporter, @data['task_uuid'], @data['nodes'])
|
||||
@orchestrator.watch_provision_progress(@reporter, data['task_uuid'], data['nodes'])
|
||||
end
|
||||
|
||||
end
|
||||
@ -439,32 +449,32 @@ describe Astute::Orchestrator do
|
||||
|
||||
describe '#check_redhat_credentials' do
|
||||
|
||||
it 'Should raise StopIteration in case of errors ' do
|
||||
it 'should raise StopIteration in case of errors ' do
|
||||
stub_rpc("Before\nInvalid username or password\nAfter")
|
||||
|
||||
expect do
|
||||
@orchestrator.check_redhat_credentials(@reporter, @data['task_uuid'], credentials)
|
||||
end.to raise_error(StopIteration)
|
||||
@orchestrator.check_redhat_credentials(@reporter, data['task_uuid'], credentials)
|
||||
end.to raise_error(/Invalid username or password/)
|
||||
end
|
||||
|
||||
it 'Should not raise errors ' do
|
||||
it 'should not raise errors' do
|
||||
stub_rpc
|
||||
@orchestrator.check_redhat_credentials(@reporter, @data['task_uuid'], credentials)
|
||||
@orchestrator.check_redhat_credentials(@reporter, data['task_uuid'], credentials)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#check_redhat_licenses' do
|
||||
it 'Should raise StopIteration in case of errors ' do
|
||||
it 'should raise StopIteration in case of errors ' do
|
||||
stub_rpc('{"openstack_licenses_physical_hosts_count":0}')
|
||||
|
||||
expect do
|
||||
@orchestrator.check_redhat_licenses(@reporter, @data['task_uuid'], credentials)
|
||||
end.to raise_error(StopIteration)
|
||||
@orchestrator.check_redhat_licenses(@reporter, data['task_uuid'], credentials)
|
||||
end.to raise_error(/Could not find any valid Red Hat OpenStack subscriptions/)
|
||||
end
|
||||
|
||||
it 'Should not raise errors ' do
|
||||
it 'should not raise errors ' do
|
||||
stub_rpc('{"openstack_licenses_physical_hosts_count":1}')
|
||||
@orchestrator.check_redhat_licenses(@reporter, @data['task_uuid'], credentials)
|
||||
@orchestrator.check_redhat_licenses(@reporter, data['task_uuid'], credentials)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user