Skip to content

Commit

Permalink
Make timeouts configuratble
Browse files Browse the repository at this point in the history
  • Loading branch information
ggiamarchi committed Jan 9, 2015
1 parent 60b8b85 commit c3e0c20
Show file tree
Hide file tree
Showing 13 changed files with 102 additions and 28 deletions.
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -110,6 +110,10 @@ This provider exposes quite a few provider-specific configuration options:
* `user_data` - String of User data to be sent to the newly created OpenStack instance. Use this e.g. to inject a script at boot time.
* `metadata` - A Hash of metadata that will be sent to the instance for configuration e.g. `os.metadata = { 'key' => 'value' }`
* `scheduler_hints` - Pass hints to the OpenStack scheduler, e.g. { "cell": "some cell name" }
* `server_create_timeout` - Time to wait in seconds for the server to be created when `vagrant up`. Default is `200`
* `server_active_timeout` - Time to wait in seconds for the server to become active when `vagrant up` or `vagrant resume`. Default is `200`
* `server_stop_timeout` - Time to wait in seconds for the server to stop when `vagrant halt`. Default is `200`
* `server_delete_timeout` - Time to wait in seconds for the server to be deleted when `vagrant destroy`. Default is `200`

#### Floating IPs

Expand Down
5 changes: 3 additions & 2 deletions source/lib/vagrant-openstack-provider/action/create_server.rb
Expand Up @@ -127,10 +127,11 @@ def create_server(env, options)
nova.create_server(env, create_opts)
end

def waiting_for_server_to_be_built(env, server_id, retry_interval = 3, timeout = 200)
def waiting_for_server_to_be_built(env, server_id, retry_interval = 3)
@logger.info "Waiting for the server with id #{server_id} to be built..."
env[:ui].info(I18n.t('vagrant_openstack.waiting_for_build'))
timeout(timeout, Errors::Timeout) do
config = env[:machine].provider_config
timeout(config.server_create_timeout, Errors::Timeout) do
server_status = 'WAITING'
until server_status == 'ACTIVE'
@logger.debug('Waiting for server to be ACTIVE')
Expand Down
5 changes: 3 additions & 2 deletions source/lib/vagrant-openstack-provider/action/create_stack.rb
Expand Up @@ -48,10 +48,11 @@ def execute(env)

private

def waiting_for_stack_to_be_created(env, stack_name, stack_id, retry_interval = 3, timeout = 200)
def waiting_for_stack_to_be_created(env, stack_name, stack_id, retry_interval = 3)
@logger.info "Waiting for the stack with id #{stack_id} to be built..."
env[:ui].info(I18n.t('vagrant_openstack.waiting_for_stack'))
timeout(timeout, Errors::Timeout) do
config = env[:machine].provider_config
timeout(config.stack_create_timeout, Errors::Timeout) do
stack_status = 'CREATE_IN_PROGRESS'
until stack_status == 'CREATE_COMPLETE'
@logger.debug('Waiting for stack to be CREATED')
Expand Down
5 changes: 3 additions & 2 deletions source/lib/vagrant-openstack-provider/action/delete_server.rb
Expand Up @@ -28,10 +28,11 @@ def execute(env)

private

def waiting_for_instance_to_be_deleted(env, instance_id, retry_interval = 3, timeout = 200)
def waiting_for_instance_to_be_deleted(env, instance_id, retry_interval = 3)
@logger.info "Waiting for the instance with id #{instance_id} to be deleted..."
env[:ui].info(I18n.t('vagrant_openstack.waiting_deleted'))
timeout(timeout, Errors::Timeout) do
config = env[:machine].provider_config
timeout(config.server_delete_timeout, Errors::Timeout) do
delete_ok = false
until delete_ok
begin
Expand Down
5 changes: 3 additions & 2 deletions source/lib/vagrant-openstack-provider/action/delete_stack.rb
Expand Up @@ -53,10 +53,11 @@ def list_stack_files(env)
stack_files
end

def waiting_for_stack_to_be_deleted(env, stack_name, stack_id, retry_interval = 3, timeout = 200)
def waiting_for_stack_to_be_deleted(env, stack_name, stack_id, retry_interval = 3)
@logger.info "Waiting for the stack with id #{stack_id} to be deleted..."
env[:ui].info(I18n.t('vagrant_openstack.waiting_for_stack_deleted'))
timeout(timeout, Errors::Timeout) do
config = env[:machine].provider_config
timeout(config.stack_delete_timeout, Errors::Timeout) do
stack_status = 'DELETE_IN_PROGRESS'
until stack_status == 'DELETE_COMPLETE'
@logger.debug('Waiting for stack to be DELETED')
Expand Down
6 changes: 3 additions & 3 deletions source/lib/vagrant-openstack-provider/action/wait_active.rb
Expand Up @@ -7,18 +7,18 @@ module VagrantPlugins
module Openstack
module Action
class WaitForServerToBeActive < AbstractAction
def initialize(app, _env, retry_interval = 3, timeout = 200)
def initialize(app, _env, retry_interval = 3)
@app = app
@logger = Log4r::Logger.new('vagrant_openstack::action::start_server')
@retry_interval = retry_interval
@timeout = timeout
end

def execute(env)
if env[:machine].id
env[:ui].info(I18n.t('vagrant_openstack.waiting_start'))
client = env[:openstack_client].nova
timeout(@timeout, Errors::Timeout) do
config = env[:machine].provider_config
timeout(config.server_active_timeout, Errors::Timeout) do
while client.get_server_details(env, env[:machine].id)['status'] != 'ACTIVE'
sleep @retry_interval
@logger.info('Waiting for server to be active')
Expand Down
6 changes: 3 additions & 3 deletions source/lib/vagrant-openstack-provider/action/wait_stop.rb
Expand Up @@ -7,18 +7,18 @@ module VagrantPlugins
module Openstack
module Action
class WaitForServerToStop < AbstractAction
def initialize(app, _env, retry_interval = 3, timeout = 200)
def initialize(app, _env, retry_interval = 3)
@app = app
@logger = Log4r::Logger.new('vagrant_openstack::action::stop_server')
@retry_interval = retry_interval
@timeout = timeout
end

def execute(env)
if env[:machine].id
env[:ui].info(I18n.t('vagrant_openstack.waiting_stop'))
client = env[:openstack_client].nova
timeout(@timeout, Errors::Timeout) do
config = env[:machine].provider_config
timeout(config.server_stop_timeout, Errors::Timeout) do
while client.get_server_details(env, env[:machine].id)['status'] != 'SHUTOFF'
sleep @retry_interval
@logger.info('Waiting for server to stop')
Expand Down
36 changes: 36 additions & 0 deletions source/lib/vagrant-openstack-provider/config.rb
Expand Up @@ -165,6 +165,30 @@ class Config < Vagrant.plugin('2', :config)
# @return [String]
attr_accessor :endpoint_type

#
# @return [Integer]
attr_accessor :server_create_timeout

#
# @return [Integer]
attr_accessor :server_active_timeout

#
# @return [Integer]
attr_accessor :server_stop_timeout

#
# @return [Integer]
attr_accessor :server_delete_timeout

#
# @return [Integer]
attr_accessor :stack_create_timeout

#
# @return [Integer]
attr_accessor :stack_delete_timeout

def initialize
@password = UNSET_VALUE
@openstack_compute_url = UNSET_VALUE
Expand Down Expand Up @@ -200,6 +224,12 @@ def initialize
@user_data = UNSET_VALUE
@metadata = UNSET_VALUE
@ssh_disabled = UNSET_VALUE
@server_create_timeout = UNSET_VALUE
@server_active_timeout = UNSET_VALUE
@server_stop_timeout = UNSET_VALUE
@server_delete_timeout = UNSET_VALUE
@stack_create_timeout = UNSET_VALUE
@stack_delete_timeout = UNSET_VALUE
end

def merge(other)
Expand Down Expand Up @@ -271,6 +301,12 @@ def finalize!
# `config.ssh` values are used.
@ssh_username = nil if @ssh_username == UNSET_VALUE
@ssh_timeout = 180 if @ssh_timeout == UNSET_VALUE
@server_create_timeout = 200 if @server_create_timeout == UNSET_VALUE
@server_active_timeout = 200 if @server_active_timeout == UNSET_VALUE
@server_stop_timeout = 200 if @server_stop_timeout == UNSET_VALUE
@server_delete_timeout = 200 if @server_delete_timeout == UNSET_VALUE
@stack_create_timeout = 200 if @stack_create_timeout == UNSET_VALUE
@stack_delete_timeout = 200 if @stack_delete_timeout == UNSET_VALUE
@networks = nil if @networks.empty?
@volumes = nil if @volumes.empty?
@stacks = nil if @stacks.empty?
Expand Down
Expand Up @@ -195,17 +195,20 @@
it 'become active after one retry' do
nova.stub(:get_server_details).and_return({ 'status' => 'BUILD' }, { 'status' => 'ACTIVE' })
nova.should_receive(:get_server_details).with(env, 'server-01').exactly(2).times
@action.waiting_for_server_to_be_built(env, 'server-01', 1, 5)
config.stub(:server_create_timeout) { 5 }
@action.waiting_for_server_to_be_built(env, 'server-01', 1)
end
it 'timeout before the server become active' do
nova.stub(:get_server_details).and_return({ 'status' => 'BUILD' }, { 'status' => 'BUILD' })
nova.should_receive(:get_server_details).with(env, 'server-01').at_least(2).times
expect { @action.waiting_for_server_to_be_built(env, 'server-01', 1, 3) }.to raise_error Errors::Timeout
config.stub(:server_create_timeout) { 3 }
expect { @action.waiting_for_server_to_be_built(env, 'server-01', 1) }.to raise_error Errors::Timeout
end
it 'raise an error after one retry' do
nova.stub(:get_server_details).and_return({ 'status' => 'BUILD' }, { 'status' => 'ERROR' })
nova.should_receive(:get_server_details).with(env, 'server-01').exactly(2).times
expect { @action.waiting_for_server_to_be_built(env, 'server-01', 1, 3) }.to raise_error Errors::ServerStatusError
config.stub(:server_create_timeout) { 3 }
expect { @action.waiting_for_server_to_be_built(env, 'server-01', 1) }.to raise_error Errors::ServerStatusError
end
end
end
Expand Down
Expand Up @@ -22,6 +22,7 @@
}
]
end
config.stub(:stack_create_timeout) { 200 }
end
end

Expand Down Expand Up @@ -80,17 +81,20 @@
it 'become active after one retry' do
heat.stub(:get_stack_details).and_return({ 'stack_status' => 'CREATE_IN_PROGRESS' }, { 'stack_status' => 'CREATE_COMPLETE' })
heat.should_receive(:get_stack_details).with(env, 'stack1', 'id-01').exactly(2).times
@action.waiting_for_stack_to_be_created(env, 'stack1', 'id-01', 1, 5)
config.stub(:stack_create_timeout) { 5 }
@action.waiting_for_stack_to_be_created(env, 'stack1', 'id-01', 1)
end
it 'timeout before the server become active' do
heat.stub(:get_stack_details).and_return({ 'stack_status' => 'CREATE_IN_PROGRESS' }, { 'stack_status' => 'CREATE_IN_PROGRESS' })
heat.should_receive(:get_stack_details).with(env, 'stack1', 'id-01').at_least(2).times
expect { @action.waiting_for_stack_to_be_created(env, 'stack1', 'id-01', 1, 3) }.to raise_error Errors::Timeout
config.stub(:stack_create_timeout) { 3 }
expect { @action.waiting_for_stack_to_be_created(env, 'stack1', 'id-01', 1) }.to raise_error Errors::Timeout
end
it 'raise an error after one retry' do
heat.stub(:get_stack_details).and_return({ 'stack_status' => 'CREATE_IN_PROGRESS' }, { 'stack_status' => 'CREATE_FAILED' })
heat.should_receive(:get_stack_details).with(env, 'stack1', 'id-01').exactly(2).times
expect { @action.waiting_for_stack_to_be_created(env, 'stack1', 'id-01', 1, 3) }.to raise_error Errors::StackStatusError
config.stub(:stack_create_timeout) { 3 }
expect { @action.waiting_for_stack_to_be_created(env, 'stack1', 'id-01', 1) }.to raise_error Errors::StackStatusError
end
end
end
Expand Down
Expand Up @@ -15,13 +15,18 @@
end
end

let(:config) do
double('config')
end

let(:env) do
Hash.new.tap do |env|
env[:ui] = double('ui')
env[:ui].stub(:info).with(anything)
env[:ui].stub(:error).with(anything)
env[:openstack_client] = openstack_client
env[:machine] = OpenStruct.new.tap do |m|
m.provider_config = config
m.id = 'server_id'
end
end
Expand Down Expand Up @@ -59,22 +64,26 @@
nova.stub(:get_server_details).once.and_return('status' => 'ACTIVE')
nova.stub(:get_server_details).once.and_raise(Errors::InstanceNotFound)
nova.should_receive(:get_server_details).with(env, 'server-01').exactly(1).times
@action.waiting_for_instance_to_be_deleted(env, 'server-01', 1, 5)
config.stub(:server_delete_timeout) { 5 }
@action.waiting_for_instance_to_be_deleted(env, 'server-01', 1)
end
it 'become deleted after one retry' do
nova.stub(:get_server_details).and_return({ 'status' => 'ACTIVE' }, { 'status' => 'DELETED' })
nova.should_receive(:get_server_details).with(env, 'server-01').exactly(2).times
@action.waiting_for_instance_to_be_deleted(env, 'server-01', 1, 5)
config.stub(:server_delete_timeout) { 5 }
@action.waiting_for_instance_to_be_deleted(env, 'server-01', 1)
end
it 'timeout before the server become active' do
nova.stub(:get_server_details).and_return({ 'status' => 'ACTIVE' }, { 'status' => 'ACTIVE' })
nova.should_receive(:get_server_details).with(env, 'server-01').at_least(2).times
expect { @action.waiting_for_instance_to_be_deleted(env, 'server-01', 1, 3) }.to raise_error Errors::Timeout
config.stub(:server_delete_timeout) { 3 }
expect { @action.waiting_for_instance_to_be_deleted(env, 'server-01', 1) }.to raise_error Errors::Timeout
end
it 'raise an error after one retry' do
nova.stub(:get_server_details).and_return({ 'status' => 'ACTIVE' }, { 'status' => 'ERROR' })
nova.should_receive(:get_server_details).with(env, 'server-01').exactly(2).times
expect { @action.waiting_for_instance_to_be_deleted(env, 'server-01', 1, 3) }.to raise_error Errors::ServerStatusError
config.stub(:server_delete_timeout) { 3 }
expect { @action.waiting_for_instance_to_be_deleted(env, 'server-01', 1) }.to raise_error Errors::ServerStatusError
end
end
end
Expand Down
Expand Up @@ -6,6 +6,10 @@
double('nova')
end

let(:config) do
double('config')
end

let(:env) do
Hash.new.tap do |env|
env[:ui] = double('ui').tap do |ui|
Expand All @@ -16,6 +20,7 @@
os.stub(:nova) { nova }
end
env[:machine] = OpenStruct.new.tap do |m|
m.provider_config = config
m.id = 'server_id'
end
end
Expand All @@ -33,13 +38,15 @@
nova.stub(:get_server_details).and_return({ 'status' => 'BUILD' }, { 'status' => 'ACTIVE' })
expect(nova).to receive(:get_server_details).with(env, 'server_id').exactly(2).times
expect(app).to receive(:call)
@action = WaitForServerToBeActive.new(app, nil, 1, 5)
config.stub(:server_active_timeout) { 5 }
@action = WaitForServerToBeActive.new(app, nil, 1)
@action.call(env)
end
it 'timeout after one retry' do
nova.stub(:get_server_details).and_return({ 'status' => 'BUILD' }, { 'status' => 'BUILD' })
expect(nova).to receive(:get_server_details).with(env, 'server_id').at_least(2).times
@action = WaitForServerToBeActive.new(app, nil, 1, 2)
config.stub(:server_active_timeout) { 2 }
@action = WaitForServerToBeActive.new(app, nil, 1)
expect { @action.call(env) }.to raise_error Errors::Timeout
end
end
Expand Down
11 changes: 9 additions & 2 deletions source/spec/vagrant-openstack-provider/action/wait_stop_spec.rb
Expand Up @@ -6,6 +6,10 @@
double('nova')
end

let(:config) do
double('config')
end

let(:env) do
Hash.new.tap do |env|
env[:ui] = double('ui').tap do |ui|
Expand All @@ -16,6 +20,7 @@
os.stub(:nova) { nova }
end
env[:machine] = OpenStruct.new.tap do |m|
m.provider_config = config
m.id = 'server_id'
end
end
Expand All @@ -33,13 +38,15 @@
nova.stub(:get_server_details).and_return({ 'status' => 'ACTIVE' }, { 'status' => 'SHUTOFF' })
expect(nova).to receive(:get_server_details).with(env, 'server_id').exactly(2).times
expect(app).to receive(:call)
@action = WaitForServerToStop.new(app, nil, 1, 5)
config.stub(:server_stop_timeout) { 5 }
@action = WaitForServerToStop.new(app, nil, 1)
@action.call(env)
end
it 'timeout after one retry' do
nova.stub(:get_server_details).and_return({ 'status' => 'ACTIVE' }, { 'status' => 'ACTIVE' })
expect(nova).to receive(:get_server_details).with(env, 'server_id').at_least(2).times
@action = WaitForServerToStop.new(app, nil, 1, 2)
config.stub(:server_stop_timeout) { 2 }
@action = WaitForServerToStop.new(app, nil, 1)
expect { @action.call(env) }.to raise_error Errors::Timeout
end
end
Expand Down

0 comments on commit c3e0c20

Please sign in to comment.