[FUEL-813] Add provision to CI, tests and small refactoring

This commit is contained in:
Vladmir Sharhsov(warpc) 2013-07-09 15:57:12 +04:00
parent 1a000f42f2
commit 45ddbfa8bc
5 changed files with 245 additions and 18 deletions

View File

@ -11,7 +11,7 @@ Gem::Specification.new do |s|
s.email = ['mscherbakov@mirantis.com']
s.add_dependency 'activesupport', '3.0.10'
s.add_dependency 'mcollective-client', '2.3.1'
s.add_dependency 'mcollective-client', '~> 2.2.4'
s.add_dependency 'symboltable', '1.0.2'
s.add_development_dependency 'rspec', '2.13.0'

View File

@ -42,6 +42,11 @@ optparse = OptionParser.new do |o|
end
o.on("-h") { puts o; exit }
o.on("-c", "--command [COMMAND]", [:deploy, :provision], "Select operation (deploy, provision)") do |c|
opts[:command] = c || :deploy
end
end
optparse.parse!(ARGV)
@ -65,5 +70,11 @@ case environment['attributes']['deployment_engine']
deploy_engine = nil # Orchestrator will use it's default
end
orchestrator = Astute::Orchestrator.new(deploy_engine, log_parsing=false)
orchestrator.deploy(reporter, environment['task_uuid'], environment['nodes'], environment['attributes'])
case opts[:command]
when :deploy
orchestrator = Astute::Orchestrator.new(deploy_engine, log_parsing=false)
orchestrator.deploy(reporter, environment['task_uuid'], environment['nodes'], environment['attributes'])
when :provision
orchestrator = Astute::Orchestrator.new(deploy_engine, log_parsing=false)
orchestrator.provision(reporter, environment['engine'], environment['nodes'])
end

View File

@ -0,0 +1,74 @@
---
task_uuid: deployment_task
attributes:
deployment_engine: simplepuppet
engine:
url: http://localhost/cobbler_api
username: cobbler
password: cobbler
nodes:
- profile: centos-x86_64
name_servers_search: domain.tld
ks_meta:
mco_enable: 1
mco_vhost: mcollective
mco_pskey: unset
ks_spaces: '"[{\"type\": \"disk\", \"id\": \"disk/by-path/pci-0000:00:0d.0-scsi-0:0:0:0\",
\"volumes\": [{\"mount\": \"/boot\", \"type\": \"partition\", \"size\": 209715200},
{\"type\": \"mbr\"}, {\"size\": 16959668224, \"type\": \"pv\", \"vg\": \"os\"}],
\"size\": 17179869184}, {\"type\": \"disk\", \"id\": \"disk/by-path/pci-0000:00:0d.0-scsi-1:0:0:0\",
\"volumes\": [{\"size\": 536860426240, \"type\": \"pv\", \"vg\": \"os\"}], \"size\":
536870912000}, {\"type\": \"disk\", \"id\": \"disk/by-path/pci-0000:00:0d.0-scsi-2:0:0:0\",
\"volumes\": [{\"size\": 2411714314240, \"type\": \"pv\", \"vg\": \"os\"}],
\"size\": 2411724800000}, {\"type\": \"vg\", \"id\": \"os\", \"volumes\": [{\"mount\":
\"/\", \"type\": \"lv\", \"name\": \"root\", \"size\": 2963243016192}, {\"mount\":
\"swap\", \"type\": \"lv\", \"name\": \"swap\", \"size\": 2090065920}]}]"'
mco_user: mcollective
puppet_enable: 0
install_log_2_syslog: 1
mco_password: marionette
puppet_auto_setup: 1
puppet_master: fuelweb.domain.tld
mco_auto_setup: 1
auth_key: '""'
puppet_version: 2.7.19
mco_connector: rabbitmq
mco_host: 10.20.0.2
interfaces:
eth2:
ip_address: 10.20.0.129
netmask: 255.255.255.0
static: 0
mac_address: 08:00:27:4E:1D:DD
eth1:
ip_address: 10.20.0.130
netmask: 255.255.255.0
static: 0
mac_address: 08:00:27:86:97:99
eth0:
ip_address: 10.20.0.131
netmask: 255.255.255.0
dns_name: controller-1.domain.tld
static: 0
mac_address: 08:00:27:0B:2E:DD
interfaces_extra:
eth2:
onboot: no
peerdns: no
eth1:
onboot: no
peerdns: no
eth0:
onboot: yes
peerdns: no
power_type: ssh
power_user: root
power_address: 10.20.0.78
name_servers: 10.20.0.2
name: controller-1
hostname: controller-1.domain.tld
power_pass: /root/.ssh/bootstrap.rsa
netboot_enabled: 1

View File

@ -55,19 +55,8 @@ module Astute
end
def provision(reporter, engine_attrs, nodes)
begin
Astute.logger.info("Trying to instantiate cobbler engine: #{engine_attrs.inspect}")
engine = Astute::Provision::Cobbler.new(engine_attrs)
rescue
Astute.logger.error("Error occured during cobbler initializing")
reporter.report({
'status' => 'error',
'error' => 'Cobbler can not be initialized',
'progress' => 100
})
raise StopIteration
end
raise "Nodes to provision are not provided!" if nodes.empty?
engine = create_engine(engine_attrs, reporter)
begin
reboot_events = reboot_nodes(engine, nodes)
@ -119,7 +108,7 @@ module Astute
Timeout::timeout(Astute.config.PROVISIONING_TIMEOUT) do # Timeout for booting target OS
while true
time = Time::now.to_f
types = self.node_type(reporter, task_id, nodes, 2)
types = node_type(reporter, task_id, nodes, 2)
types.each do |t|
Astute.logger.debug("Got node types: uid=#{t['uid']} type=#{t['node_type']}")
end
@ -169,7 +158,7 @@ module Astute
reporter.report({'nodes' => nodes_progress})
begin
result = self.deploy(reporter, task_id, nodes, attrs)
result = deploy(reporter, task_id, nodes, attrs)
rescue Timeout::Error
msg = "Timeout of deployment is exceeded."
Astute.logger.error msg
@ -199,6 +188,22 @@ module Astute
reporter.report(status)
end
def create_engine(engine_attrs, reporter)
begin
Astute.logger.info("Trying to instantiate cobbler engine: #{engine_attrs.inspect}")
engine = Astute::Provision::Cobbler.new(engine_attrs)
rescue
Astute.logger.error("Error occured during cobbler initializing")
reporter.report({
'status' => 'error',
'error' => 'Cobbler can not be initialized',
'progress' => 100
})
raise StopIteration
end
end
def reboot_nodes(engine, nodes)
reboot_events = {}
nodes.each do |node|

View File

@ -217,5 +217,142 @@ describe Astute::Orchestrator do
end
it "remove_nodes do not fail if any of nodes failed"
describe '#provision' do
before(:all) do
@data = {
"engine"=>{
"url"=>"http://localhost/cobbler_api",
"username"=>"cobbler",
"password"=>"cobbler"
},
"task_uuid"=>"a5c44b9a-285a-4a0c-ae65-2ed6b3d250f4",
"nodes" => [
{
'profile' => 'centos-x86_64',
"name"=>"controller-1",
'power_type' => 'ssh',
'power_user' => 'root',
'power_pass' => '/root/.ssh/bootstrap.rsa',
'power-address' => '1.2.3.5',
'hostname' => 'name.domain.tld',
'name_servers' => '1.2.3.4 1.2.3.100',
'name_servers_search' => 'some.domain.tld domain.tld',
'netboot_enabled' => '1',
'ks_meta' => 'some_param=1 another_param=2',
'interfaces' => {
'eth0' => {
'mac_address' => '00:00:00:00:00:00',
'static' => '1',
'netmask' => '255.255.255.0',
'ip_address' => '1.2.3.5',
'dns_name' => 'node.mirantis.net',
},
'eth1' => {
'mac_address' => '00:00:00:00:00:01',
'static' => '0',
'netmask' => '255.255.255.0',
'ip_address' => '1.2.3.6',
}
},
'interfaces_extra' => {
'eth0' => {
'peerdns' => 'no',
'onboot' => 'yes',
},
'eth1' => {
'peerdns' => 'no',
'onboot' => 'yes',
}
}
}
]
}.freeze
end
context 'cobler cases' do
it "raise error if cobler settings empty" do
expect {@orchestrator.provision(@reporter, {}, @data['nodes'])}.
to raise_error(StopIteration)
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.provision(@reporter, @data['engine'], {})}.
to raise_error(/Nodes to provision are not provided!/)
end
it "try to reboot nodes from list" do
Astute::Provision::Cobbler.any_instance do
expects(:power_reboot).with('controller-1')
end
@orchestrator.stubs(:check_reboot_nodes).returns([])
@orchestrator.provision(@reporter, @data['engine'], @data['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'])}
it "does not find failed nodes" do
Astute::Provision::Cobbler.any_instance.stubs(:event_status).
returns([Time.now.to_f, 'controller-1', 'complete'])
@orchestrator.provision(@reporter, @data['engine'], @data['nodes'])
end
it "report about success" do
@reporter.expects(:report).with({'status' => 'ready', 'progress' => 100}).returns(true)
@orchestrator.provision(@reporter, @data['engine'], @data['nodes'])
end
it "sync engine state" do
Astute::Provision::Cobbler.any_instance do
expects(:sync).once
end
@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.provision(@reporter, @data['engine'], @data['nodes'])
rescue
end
end
it "raise error if failed node find" do
expect {@orchestrator.provision(@reporter, @data['engine'], @data['nodes'])}.to raise_error(StopIteration)
end
end
end
end
end