[PATCH conductor 1/2] 838726 (1) - mark 'new' instances as create_failed if deployment launch fails

jprovazn at redhat.com jprovazn at redhat.com
Thu Jul 12 18:45:09 UTC 2012


From: Jan Provaznik <jprovazn at redhat.com>

After whole launch process fails (= deployment ends in failed or
rollback_failed state) then all instances which remained in 'new'
state are marked as 'create_failed'.
---
 src/app/models/deployment.rb       |   11 ++++++-
 src/app/models/instance.rb         |    1 +
 src/spec/models/deployment_spec.rb |   62 ++++++++++++++++++++++++------------
 3 files changed, 52 insertions(+), 22 deletions(-)

diff --git a/src/app/models/deployment.rb b/src/app/models/deployment.rb
index 202f960..3b4e9c1 100644
--- a/src/app/models/deployment.rb
+++ b/src/app/models/deployment.rb
@@ -671,9 +671,10 @@ class Deployment < ActiveRecord::Base
     if Instance::ACTIVE_FAILED_STATES.include?(instance.state)
       # if this instance stop failed, whole deployment rollback failed
       self.state = STATE_ROLLBACK_FAILED
+      cleanup_failed_launch
     elsif instance.state == Instance::STATE_RUNNING
       deployment_rollback
-    elsif instances.all? {|i| i.inactive?}
+    elsif instances.all? {|i| i.inactive? or i.state == Instance::STATE_NEW}
       # some other instances might be failed (because their
       # launch failed), but it shouldn't be a problem if all
       # running instances stopped correctly
@@ -715,6 +716,7 @@ class Deployment < ActiveRecord::Base
       end
     end
     if error_occured
+      cleanup_failed_launch
       self.state = STATE_ROLLBACK_FAILED
       save!
     end
@@ -747,9 +749,16 @@ class Deployment < ActiveRecord::Base
           :summary => "Failed to launch deployment: #{$!.message}"
         )
         update_attribute(:state, STATE_FAILED)
+        cleanup_failed_launch
         logger.error $!.message
         logger.error $!.backtrace.join("\n    ")
       end
     end
   end
+
+  def cleanup_failed_launch
+    instances.in_new_state.each do |instance|
+      instance.update_attribute(:state, Instance::STATE_CREATE_FAILED)
+    end
+  end
 end
diff --git a/src/app/models/instance.rb b/src/app/models/instance.rb
index 07ec7cf..8b8021e 100644
--- a/src/app/models/instance.rb
+++ b/src/app/models/instance.rb
@@ -130,6 +130,7 @@ class Instance < ActiveRecord::Base
   # FIXME: "pending" is misleading as it doesn't just cover STATE_PENDING
   scope :pending,   :conditions => { :state => [STATE_NEW, STATE_PENDING] }
   scope :running,   :conditions => { :state => [STATE_RUNNING] }
+  scope :in_new_state, :conditions => { :state => [STATE_NEW] }
   scope :pending_or_deployed,   :conditions => { :state => [STATE_NEW, STATE_PENDING, STATE_RUNNING, STATE_SHUTTING_DOWN] }
   # FIXME: "failed" is misleading too...
   scope :failed,    :conditions => { :state => FAILED_STATES }
diff --git a/src/spec/models/deployment_spec.rb b/src/spec/models/deployment_spec.rb
index da893d2..9b2a37e 100644
--- a/src/spec/models/deployment_spec.rb
+++ b/src/spec/models/deployment_spec.rb
@@ -472,29 +472,49 @@ describe Deployment do
         @inst2.update_attribute(:state, Instance::STATE_STOPPED)
       end
 
-      describe "on relaunch" do
-        before :each do
-          account = Factory.create(:mock_provider_account)
-          match1 = FactoryGirl.build(:instance_match,
-                                     :provider_account => account,
-                                     :instance_id => @inst1.id)
-          match2 = FactoryGirl.build(:instance_match,
-                                     :provider_account => account,
-                                     :instance_id => @inst2.id)
-          Instance.any_instance.stub(:launch!).and_return(true)
-          Deployment.any_instance.stub(:find_match_with_common_account).
-            and_return([[match1, match2], account, []])
-          @inst2.update_attribute(:state, Instance::STATE_STOPPED)
-        end
-
-        it "should set pending state for the deployment" do
-          @deployment.reload
-          @deployment.state.should == Deployment::STATE_PENDING
+      describe "handle_completed_rollback" do
+        context "next match is found" do
+          before :each do
+            account = Factory.create(:mock_provider_account)
+            match1 = FactoryGirl.build(:instance_match,
+                                       :provider_account => account,
+                                       :instance_id => @inst1.id)
+            match2 = FactoryGirl.build(:instance_match,
+                                       :provider_account => account,
+                                       :instance_id => @inst2.id)
+            Instance.any_instance.stub(:launch!).and_return(true)
+            Deployment.any_instance.stub(:find_match_with_common_account).
+              and_return([[match1, match2], account, []])
+            @inst2.update_attribute(:state, Instance::STATE_STOPPED)
+          end
+
+          it "should set pending state for the deployment" do
+            @deployment.reload
+            @deployment.state.should == Deployment::STATE_PENDING
+          end
+
+          it "should save instance match for each instance" do
+            @inst1.instance_matches.count.should > 0
+            @inst2.instance_matches.count.should > 0
+          end
         end
 
-        it "should save instance match for each instance" do
-          @inst1.instance_matches.count.should > 0
-          @inst2.instance_matches.count.should > 0
+        context "no other match is found" do
+          before :each do
+            Deployment.any_instance.stub(:find_match_with_common_account).
+                and_return([nil, nil, []])
+              @inst1.update_attribute(:state, Instance::STATE_NEW)
+              @inst2.update_attribute(:state, Instance::STATE_STOPPED)
+              @deployment.reload
+          end
+
+          it "deployment should be in failed state" do
+            @deployment.state.should == Deployment::STATE_FAILED
+          end
+
+          it "there should not be instances in new state" do
+            @deployment.instances.in_new_state.count.should == 0
+          end
         end
       end
     end
-- 
1.7.10.4




More information about the aeolus-devel mailing list