From: Jan Provaznik <jprovazn(a)redhat.com>
This option allows a user to launch a deployment even if some instance fails to start.
https://www.aeolusproject.org/redmine/issues/3321
---
src/app/models/deployment.rb | 10 +++-
src/app/models/instance.rb | 4 +
src/app/views/deployments/_overview.html.haml | 5 ++
src/config/locales/en.yml | 1 +
...20515141411_add_partial_launch_to_deployment.rb | 12 ++++
src/spec/models/deployment_spec.rb | 60 ++++++++++++++------
6 files changed, 74 insertions(+), 18 deletions(-)
create mode 100644 src/db/migrate/20120515141411_add_partial_launch_to_deployment.rb
diff --git a/src/app/models/deployment.rb b/src/app/models/deployment.rb
index c410957..f77b16d 100644
--- a/src/app/models/deployment.rb
+++ b/src/app/models/deployment.rb
@@ -269,6 +269,11 @@ class Deployment < ActiveRecord::Base
"#{instance.name}:
#{$!.message.to_s.split("\n").first}")
logger.error $!.message
logger.error $!.backtrace.join("\n ")
+
+ # be default launching of instances is terminated if an error occurs,
+ # user can set "partial_launch" attribute - launch request is then
+ # sent for all deployment's instances
+ break unless partial_launch
end
end
true
@@ -607,7 +612,9 @@ class Deployment < ActiveRecord::Base
def state_transition_from_pending(instance)
if instances.all? {|i| i.state == Instance::STATE_RUNNING}
self.state = STATE_RUNNING
- elsif Instance::FAILED_STATES.include?(instance.state)
+ elsif partial_launch and instances.all? {|i| i.failed_or_running?}
+ self.state = STATE_RUNNING
+ elsif !partial_launch and Instance::FAILED_STATES.include?(instance.state)
deployment_rollback
end
end
@@ -668,6 +675,7 @@ class Deployment < ActiveRecord::Base
end
if error_occured
self.state = STATE_ROLLBACK_FAILED
+ save!
end
end
end
diff --git a/src/app/models/instance.rb b/src/app/models/instance.rb
index ea901fa..ea8ada6 100644
--- a/src/app/models/instance.rb
+++ b/src/app/models/instance.rb
@@ -337,6 +337,10 @@ class Instance < ActiveRecord::Base
(FAILED_STATES + [STATE_STOPPED]).include?(state)
end
+ def failed_or_running?
+ (FAILED_STATES + [STATE_RUNNING]).include?(state)
+ end
+
def requires_config_server?
not instance_config_xml.nil? or assembly_xml.requires_config_server?
end
diff --git a/src/app/views/deployments/_overview.html.haml
b/src/app/views/deployments/_overview.html.haml
index 62190f0..d4a90fd 100644
--- a/src/app/views/deployments/_overview.html.haml
+++ b/src/app/views/deployments/_overview.html.haml
@@ -42,6 +42,11 @@
%div#realm-description
.field
+ = label_tag :launch_with_errors , t('.launch_with_errors')
+ .input
+ = check_box :deployment, :partial_launch
+
+ .field
= label_tag :image_ids, t('.image_ids')
.input
%span.text_instead_input
diff --git a/src/config/locales/en.yml b/src/config/locales/en.yml
index 64e7012..471c154 100644
--- a/src/config/locales/en.yml
+++ b/src/config/locales/en.yml
@@ -245,6 +245,7 @@ en:
description: Description
image_ids: Image IDs
launch: Launch
+ launch_with_errors: Launch with errors
launch_from_catalog:
profile: Profile
hint: Choose a deployable to launch in the "%{pool}" pool
diff --git a/src/db/migrate/20120515141411_add_partial_launch_to_deployment.rb
b/src/db/migrate/20120515141411_add_partial_launch_to_deployment.rb
new file mode 100644
index 0000000..9ec9b5f
--- /dev/null
+++ b/src/db/migrate/20120515141411_add_partial_launch_to_deployment.rb
@@ -0,0 +1,12 @@
+class AddPartialLaunchToDeployment < ActiveRecord::Migration
+ def self.up
+ add_column :deployments, :partial_launch, :boolean, :default => false
+ Deployment.unscoped.all.each do |d|
+ d.update_attribute(:partial_launch, true)
+ end
+ end
+
+ def self.down
+ remove_column :deployments, :partial_launch
+ end
+end
diff --git a/src/spec/models/deployment_spec.rb b/src/spec/models/deployment_spec.rb
index eee587e..cb4b756 100644
--- a/src/spec/models/deployment_spec.rb
+++ b/src/spec/models/deployment_spec.rb
@@ -313,13 +313,19 @@ describe Deployment do
lambda { Deployment.find((a)deployment.id) }.should
raise_error(ActiveRecord::RecordNotFound)
end
- it "should set create_failed status for instances if instance's launch
raises an exception" do
- @deployment.instances.should be_empty
- Taskomatic.stub!(:create_dcloud_instance).and_raise("an exception")
- @deployment.create_and_launch(@user_for_launch)
- @deployment.reload
- @deployment.instances.should_not be_empty
- @deployment.instances.each {|i| i.state.should == Instance::STATE_CREATE_FAILED}
+ context "partial_launch is enabled" do
+ before :each do
+ @deployment.update_attribute(:partial_launch, true)
+ end
+
+ it "should set create_failed status for instances if instance's launch
raises an exception" do
+ @deployment.instances.should be_empty
+ Taskomatic.stub!(:create_dcloud_instance).and_raise("an exception")
+ @deployment.create_and_launch(@user_for_launch)
+ @deployment.reload
+ @deployment.instances.should_not be_empty
+ @deployment.instances.each {|i| i.state.should == Instance::STATE_CREATE_FAILED}
+ end
end
end
@@ -402,18 +408,38 @@ describe Deployment do
@deployment.state.should == Deployment::STATE_RUNNING
end
- it "should be rollback_in_progress if an instance fails" do
- @inst2.state = Instance::STATE_ERROR
- @inst2.save!
- @deployment.reload
- @deployment.state.should == Deployment::STATE_ROLLBACK_IN_PROGRESS
+ context "partial_launch disabled" do
+ before :each do
+ @deployment.update_attribute(:partial_launch, false)
+ end
+
+ it "should be rollback_in_progress if an instance fails" do
+ Instance.any_instance.stub(:stop).and_return(true)
+ @inst2.state = Instance::STATE_ERROR
+ @inst2.save!
+ @deployment.reload
+ @deployment.state.should == Deployment::STATE_ROLLBACK_IN_PROGRESS
+ end
+
+ it "should stop all running instances if an instance fails" do
+ Instance.any_instance.stub(:stop).and_return(true)
+ Instance.any_instance.should_receive(:stop)
+ @inst2.state = Instance::STATE_ERROR
+ @inst2.save!
+ end
end
- it "should stop all running instances" do
- Instance.any_instance.stub(:stop).and_return(true)
- Instance.any_instance.should_receive(:stop)
- @inst2.state = Instance::STATE_ERROR
- @inst2.save!
+ context "partial_launch enabled" do
+ before :each do
+ @deployment.update_attribute(:partial_launch, true)
+ end
+
+ it "should not change deployment's state if an instance fails" do
+ @inst2.state = Instance::STATE_ERROR
+ @inst2.save!
+ @deployment.reload
+ @deployment.state.should == Deployment::STATE_PENDING
+ end
end
end
--
1.7.7.6