From: Jan Provaznik<jprovazn(a)redhat.com>
https://www.aeolusproject.org/redmine/issues/2438
---
src/app/controllers/providers_controller.rb | 8 +++++++
src/app/models/instance.rb | 1 +
src/app/models/provider.rb | 24 +++++++++++++++++++++++
src/features/provider.feature | 9 ++++++++
src/features/step_definitions/provider_steps.rb | 7 ++++++
src/spec/models/provider_spec.rb | 10 +++++++++
6 files changed, 59 insertions(+), 0 deletions(-)
diff --git a/src/app/controllers/providers_controller.rb
b/src/app/controllers/providers_controller.rb
index 9f8e466..74cc794 100644
--- a/src/app/controllers/providers_controller.rb
+++ b/src/app/controllers/providers_controller.rb
@@ -111,7 +111,15 @@ class ProvidersController< ApplicationController
def update
@provider = Provider.find_by_id(params[:id])
require_privilege(Privilege::MODIFY, @provider)
+ old_enabled = @provider.enabled
@provider.update_attributes(params[:provider])
+ # stop running instances when a provider is disabled
+ # it would be better to have this in provider's observer
+ # but we need to display error message when an error occurs
+ if old_enabled and not @provider.enabled
+ errs = @provider.stop_instances(current_user)
+ flash[:error] = errs unless errs.empty?
+ end
if !(a)provider.connect
flash.now[:warning] = "Failed to connect to Provider"
load_provider_tabs
diff --git a/src/app/models/instance.rb b/src/app/models/instance.rb
index e6bb17a..5f0d49a 100644
--- a/src/app/models/instance.rb
+++ b/src/app/models/instance.rb
@@ -107,6 +107,7 @@ class Instance< ActiveRecord::Base
scope :pending, :conditions => { :state => [STATE_NEW, STATE_PENDING] }
# FIXME: "failed" is misleading too...
scope :failed, :conditions => { :state => [STATE_CREATE_FAILED,
STATE_ERROR] }
+ scope :stopable, :conditions => { :state => [STATE_NEW, STATE_PENDING,
STATE_RUNNING] }
SEARCHABLE_COLUMNS = %w(name state)
diff --git a/src/app/models/provider.rb b/src/app/models/provider.rb
index bfb838c..30cbee2 100644
--- a/src/app/models/provider.rb
+++ b/src/app/models/provider.rb
@@ -114,6 +114,30 @@ class Provider< ActiveRecord::Base
(frontend_realms + realms.map {|r| r.frontend_realms}.flatten).uniq
end
+ def stop_instances(user)
+ errs = []
+ provider_accounts.each do |pa|
+ pa.instances.stopable.each do |instance|
+ begin
+ unless instance.valid_action?('stop')
+ raise "stop is an invalid action."
+ end
+
+ unless @task = instance.queue_action(user, 'stop')
+ raise "stop cannot be performed on this instance."
+ end
+ Taskomatic.stop_instance(@task)
+ rescue Exception => e
+ err = "Error while stopping an instance #{instance.name}:
#{e.message}"
+ errs<< err
+ logger.error err
+ logger.error e.backtrace.join("\n ")
+ end
+ end
+ end
+ errs
+ end
+
protected
def validate_provider
if !nil_or_empty(url)
diff --git a/src/features/provider.feature b/src/features/provider.feature
index 5b43e6c..03f835a 100644
--- a/src/features/provider.feature
+++ b/src/features/provider.feature
@@ -83,6 +83,15 @@ Feature: Manage Providers
And there should not be a provider account
And there should not be a realm
+ Scenario: Disable a provider
+ Given there is a provider named "provider1"
+ And this provider has a provider account with 2 running instances
+ When I go to the provider1's edit provider page
+ And I press "provider_submit"
+ Then I should be on the provider1's edit provider page
+ And I should see "Provider is disabled."
+ And I should not see "Error while stopping an instance"
+
# Scenario: Search for hardware profiles
# Given there are these providers:
# | name | url |
diff --git a/src/features/step_definitions/provider_steps.rb
b/src/features/step_definitions/provider_steps.rb
index f035997..377e0d4 100644
--- a/src/features/step_definitions/provider_steps.rb
+++ b/src/features/step_definitions/provider_steps.rb
@@ -91,3 +91,10 @@ Then /^there should be these provider:$/ do |table|
p[:provider_type].should == hash[:provider_type]
end
end
+
+Given /^this provider has a provider account with (\d+) running instances$/ do |arg1|
+ pa = FactoryGirl.create(:mock_provider_account, :provider => @provider)
+ arg1.to_i.times do |i|
+ FactoryGirl.create(:instance, :provider_account => pa, :state =>
'running')
+ end
+end
diff --git a/src/spec/models/provider_spec.rb b/src/spec/models/provider_spec.rb
index 30e385c..8c593c7 100644
--- a/src/spec/models/provider_spec.rb
+++ b/src/spec/models/provider_spec.rb
@@ -116,6 +116,16 @@ describe Provider do
provider1.frontend_realms.reload
provider1.all_associated_frontend_realms.count.should == 1
end
+
+ it "should stop all associated instances" do
+ provider1 = Factory.create(:mock_provider)
+ pa = FactoryGirl.create(:mock_provider_account, :provider => provider1)
+ inst1 = FactoryGirl.create(:instance, :provider_account => pa)
+ inst2 = FactoryGirl.create(:instance, :provider_account => pa)
+ errs = provider1.stop_instances(nil)
+ errs.should be_empty
+ end
+
end
context "(using original connect method)" do
ACK
--
No trees were killed to send this message, but a large number of
electrons were terribly inconvenienced.