You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltacloud.apache.org by lu...@redhat.com on 2012/03/02 01:02:41 UTC

[PATCH 2/2] Instance states: settle on fixed set of possible states/actions

From: David Lutterkort <lu...@redhat.com>

We now enforce that each driver only uses instance states and actions that
come from the approved list of such entities. This helps guard against
simple mistakes in writing drivers.
---
 server/lib/deltacloud/base_driver/base_driver.rb   |    7 ++++++-
 .../lib/deltacloud/drivers/condor/condor_driver.rb |    2 +-
 server/lib/deltacloud/drivers/ec2/ec2_driver.rb    |    3 ++-
 .../drivers/opennebula/opennebula_driver.rb        |    4 ++--
 .../drivers/openstack/openstack_driver.rb          |    4 ++--
 .../drivers/rackspace/rackspace_driver.rb          |    4 ++--
 .../drivers/rimuhosting/rimuhosting_driver.rb      |    4 ++--
 .../drivers/terremark/terremark_driver.rb          |    4 ++--
 .../deltacloud/drivers/vsphere/vsphere_driver.rb   |    4 ++--
 server/lib/deltacloud/state_machine.rb             |   18 +++++++++++++++++-
 site/content/api.mdown                             |    6 +++---
 site/content/developers.mdown                      |    6 +++---
 12 files changed, 44 insertions(+), 22 deletions(-)

diff --git a/server/lib/deltacloud/base_driver/base_driver.rb b/server/lib/deltacloud/base_driver/base_driver.rb
index dcc3b9a..01dd5e7 100644
--- a/server/lib/deltacloud/base_driver/base_driver.rb
+++ b/server/lib/deltacloud/base_driver/base_driver.rb
@@ -22,6 +22,11 @@ module Deltacloud
 
     include ExceptionHandler
 
+    STATE_MACHINE_OPTS = {
+      :all_states => [:start, :pending, :running, :stopping, :stopped, :finish],
+      :all_actions => [:create, :reboot, :stop, :start, :destroy]
+    }
+
     def name
       self.class.name.split('::').last.gsub('Driver', '').downcase
     end
@@ -90,7 +95,7 @@ module Deltacloud
     end
 
     def self.define_instance_states(&block)
-      machine = ::Deltacloud::StateMachine.new(&block)
+      machine = ::Deltacloud::StateMachine.new(STATE_MACHINE_OPTS, &block)
       @instance_state_machine = machine
     end
 
diff --git a/server/lib/deltacloud/drivers/condor/condor_driver.rb b/server/lib/deltacloud/drivers/condor/condor_driver.rb
index f48c9d3..f5cb741 100644
--- a/server/lib/deltacloud/drivers/condor/condor_driver.rb
+++ b/server/lib/deltacloud/drivers/condor/condor_driver.rb
@@ -175,7 +175,7 @@ module Deltacloud
           pending.to( :running )        .automatically
           pending.to( :finish )         .on(:destroy)
           running.to( :running )        .on( :reboot )
-          running.to( :shutting_down )  .on( :destroy )
+          running.to( :stopping )       .on( :destroy )
           pending.to( :finish )         .automatically
         end
 
diff --git a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
index 74e110f..5f55ecf 100644
--- a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
+++ b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
@@ -118,7 +118,8 @@ module Deltacloud
           stopped.to( :running )        .on( :start )
           running.to( :running )        .on( :reboot )
           running.to( :stopping )       .on( :stop )
-          shutting_down.to( :stopped )  .automatically
+          stopping.to(:stopped)         .automatically
+          stopping.to(:finish)          .automatically
           stopped.to( :finish )         .automatically
         end
 
diff --git a/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb b/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb
index 3b00eca..baae2a2 100644
--- a/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb
+++ b/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb
@@ -152,8 +152,8 @@ class OpennebulaDriver < Deltacloud::BaseDriver
     running.to(:running)        .on( :reboot )
     running.to(:stopping)       .on( :stop )
     stopping.to(:stopped)       .automatically
-    running.to(:shutting_down)  .on( :destroy )
-    shutting_down.to(:finish)   .automatically
+    running.to(:stopping)       .on( :destroy )
+    stopping.to(:finish)        .automatically
   end
 
   def instances(credentials, opts=nil)
diff --git a/server/lib/deltacloud/drivers/openstack/openstack_driver.rb b/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
index 845ddee..161e8b1 100644
--- a/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
+++ b/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
@@ -34,8 +34,8 @@ module Deltacloud
           start.to( :pending )          .on( :create )
           pending.to( :running )        .automatically
           running.to( :running )        .on( :reboot )
-          running.to( :shutting_down )  .on( :stop )
-          shutting_down.to( :stopped )  .automatically
+          running.to( :stopping )       .on( :stop )
+          stopping.to( :stopped )       .automatically
           stopped.to( :finish )         .automatically
         end
 
diff --git a/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb b/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb
index 3779c41..32ba78a 100644
--- a/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb
+++ b/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb
@@ -193,8 +193,8 @@ class RackspaceDriver < Deltacloud::BaseDriver
     start.to( :pending )          .on( :create )
     pending.to( :running )        .automatically
     running.to( :running )        .on( :reboot )
-    running.to( :shutting_down )  .on( :stop )
-    shutting_down.to( :stopped )  .automatically
+    running.to( :stopping )       .on( :stop )
+    stopping.to( :stopped )       .automatically
     stopped.to( :finish )         .automatically
   end
 
diff --git a/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb b/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb
index 6b61b8c..67c415c 100644
--- a/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb
+++ b/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb
@@ -142,9 +142,9 @@ class RimuHostingDriver < Deltacloud::BaseDriver
     pending.to( :running )        .automatically
 
     running.to( :running )        .on(:reboot)
-    running.to( :shutting_down )  .on(:stop)
+    running.to( :stopping )       .on(:stop)
 
-    shutting_down.to( :stopped )  .automatically
+    stopping.to( :stopped )       .automatically
 
     stopped.to( :finish )         .automatically
   end
diff --git a/server/lib/deltacloud/drivers/terremark/terremark_driver.rb b/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
index c93bfb3..0bdfdac 100644
--- a/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
+++ b/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
@@ -118,8 +118,8 @@ VAPP_STATE_MAP = { "0" =>  "PENDING", "1" =>  "PENDING", "2" =>  "STOPPED", "4"
     pending.to(:stopped)          .automatically
     stopped.to(:running)          .on( :start )
     running.to(:running)          .on( :reboot )
-    running.to(:shutting_down)    .on( :stop )
-    shutting_down.to(:stopped)    .automatically
+    running.to(:stopping)         .on( :stop )
+    stopping.to(:stopped)         .automatically
     stopped.to(:finish)           .on( :destroy )
    end
 
diff --git a/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb b/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
index e2e7654..4fbbb4b 100644
--- a/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
+++ b/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
@@ -69,8 +69,8 @@ module Deltacloud::Drivers::VSphere
       pending.to(:stopped)        .automatically
       stopped.to(:running)        .on( :start )
       running.to(:running)        .on( :reboot )
-      running.to(:shutting_down)  .on( :stop )
-      shutting_down.to(:stopped)  .automatically
+      running.to(:stopping)       .on( :stop )
+      stopping.to(:stopped)       .automatically
       stopped.to(:finish)         .on( :destroy )
     end
 
diff --git a/server/lib/deltacloud/state_machine.rb b/server/lib/deltacloud/state_machine.rb
index 19fb9f2..facd4ba 100644
--- a/server/lib/deltacloud/state_machine.rb
+++ b/server/lib/deltacloud/state_machine.rb
@@ -18,7 +18,9 @@ module Deltacloud
   class StateMachine
 
     attr_reader :states
-    def initialize(&block)
+    def initialize(opts = {}, &block)
+      @all_states = opts[:all_states]
+      @all_actions = opts[:all_actions]
       @states  = []
       instance_eval &block if block
     end
@@ -32,6 +34,9 @@ module Deltacloud
     end
 
     def state(name)
+      unless valid_state_name?(name)
+        raise "State '#{name}' not in list of allowed states"
+      end
       state = @states.find{|e| e.name == name.to_sym}
       if ( state.nil? )
         state = State.new( self, name.to_sym )
@@ -40,6 +45,14 @@ module Deltacloud
       state
     end
 
+    def valid_state_name?(name)
+      @all_states.nil? || @all_states.include?(name.to_sym)
+    end
+
+    def valid_action_name?(name)
+      @all_actions.nil? || @all_actions.include?(name.to_sym)
+    end
+
     def method_missing(sym,*args)
       return state( sym ) if ( args.empty? )
       super( sym, *args )
@@ -90,6 +103,9 @@ module Deltacloud
       end
 
       def on(action)
+        unless @machine.valid_action_name?(action)
+          raise "Action '#{action}' not in list of allowed actions"
+        end
         @action = action
       end
 
diff --git a/site/content/api.mdown b/site/content/api.mdown
index eb0114e..8ce2db3 100644
--- a/site/content/api.mdown
+++ b/site/content/api.mdown
@@ -59,7 +59,7 @@ Each Image defines the root partition and initial storage for the Instance opera
 ##### Instance States
 
 These represent the Instance lifecycle; at any time an Instance will be in one of
- *start, pending, running, stopped, shutting_down, finished*.
+ *start, pending, running, stopped, stopping, finished*.
 
 ##### Keys
 
@@ -929,9 +929,9 @@ machine for ***instances*** from the given cloud.
       </state>
       <state name='running'>
         <transition action='reboot' to='running'></transition>
-        <transition action='stop' to='shutting_down'></transition>
+        <transition action='stop' to='stopping'></transition>
       </state>
-      <state name='shutting_down'>
+      <state name='stopping'>
         <transition auto='true' to='stopped'></transition>
       </state>
       <state name='stopped'>
diff --git a/site/content/developers.mdown b/site/content/developers.mdown
index d5ea697..946ea47 100644
--- a/site/content/developers.mdown
+++ b/site/content/developers.mdown
@@ -419,8 +419,8 @@ look like is:
       start.to( :pending )          .on( :create )
       pending.to( :running )        .automatically
       running.to( :running )        .on( :reboot )
-      running.to( :shutting_down )  .on( :stop )
-      shutting_down.to( :stopped )  .automatically
+      running.to( :stopping )  .on( :stop )
+      stopping.to( :stopped )  .automatically
       stopped.to( :finish )         .automatically
     end
 
@@ -432,7 +432,7 @@ Valid states are
 - **`:begin`**
 - **`:pending`**
 - **`:running`**
-- **`:shutting_down`**
+- **`:stopping`**
 - **`:stopped`**
 - **`:end`**
 
-- 
1.7.7.6


Re: [PATCH 2/2] Instance states: settle on fixed set of possible states/actions

Posted by "marios@redhat.com" <ma...@redhat.com>.
On 02/03/12 02:02, lutter@redhat.com wrote:
> From: David Lutterkort <lu...@redhat.com>

---8<------------

> diff --git a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
> index 74e110f..5f55ecf 100644
> --- a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
> +++ b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
> @@ -118,7 +118,8 @@ module Deltacloud
>            stopped.to( :running )        .on( :start )
>            running.to( :running )        .on( :reboot )
>            running.to( :stopping )       .on( :stop )
> -          shutting_down.to( :stopped )  .automatically
> +          stopping.to(:stopped)         .automatically
> +          stopping.to(:finish)          .automatically
>            stopped.to( :finish )         .automatically
>          end
>  

is the stopping.to(:finish) there necessary? I mean:
stopping.to(:stopped) and then stopped.to(:finish) is enough no?

OR, is it a start in reconciling ebs vs instance_store instances... i
mean ebs go stopping.to(stopped) and instance_store go
stopping.to(finish)... but then the "stopped.to(:finish) :automatically"
kinda ruins the party so not sure?


marios

> diff --git a/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb b/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb
> index 3b00eca..baae2a2 100644
> --- a/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb
> +++ b/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb
> @@ -152,8 +152,8 @@ class OpennebulaDriver < Deltacloud::BaseDriver
>      running.to(:running)        .on( :reboot )
>      running.to(:stopping)       .on( :stop )
>      stopping.to(:stopped)       .automatically
> -    running.to(:shutting_down)  .on( :destroy )
> -    shutting_down.to(:finish)   .automatically
> +    running.to(:stopping)       .on( :destroy )
> +    stopping.to(:finish)        .automatically
>    end
>  
>    def instances(credentials, opts=nil)
> diff --git a/server/lib/deltacloud/drivers/openstack/openstack_driver.rb b/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
> index 845ddee..161e8b1 100644
> --- a/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
> +++ b/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
> @@ -34,8 +34,8 @@ module Deltacloud
>            start.to( :pending )          .on( :create )
>            pending.to( :running )        .automatically
>            running.to( :running )        .on( :reboot )
> -          running.to( :shutting_down )  .on( :stop )
> -          shutting_down.to( :stopped )  .automatically
> +          running.to( :stopping )       .on( :stop )
> +          stopping.to( :stopped )       .automatically
>            stopped.to( :finish )         .automatically
>          end
>  
> diff --git a/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb b/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb
> index 3779c41..32ba78a 100644
> --- a/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb
> +++ b/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb
> @@ -193,8 +193,8 @@ class RackspaceDriver < Deltacloud::BaseDriver
>      start.to( :pending )          .on( :create )
>      pending.to( :running )        .automatically
>      running.to( :running )        .on( :reboot )
> -    running.to( :shutting_down )  .on( :stop )
> -    shutting_down.to( :stopped )  .automatically
> +    running.to( :stopping )       .on( :stop )
> +    stopping.to( :stopped )       .automatically
>      stopped.to( :finish )         .automatically
>    end
>  
> diff --git a/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb b/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb
> index 6b61b8c..67c415c 100644
> --- a/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb
> +++ b/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb
> @@ -142,9 +142,9 @@ class RimuHostingDriver < Deltacloud::BaseDriver
>      pending.to( :running )        .automatically
>  
>      running.to( :running )        .on(:reboot)
> -    running.to( :shutting_down )  .on(:stop)
> +    running.to( :stopping )       .on(:stop)
>  
> -    shutting_down.to( :stopped )  .automatically
> +    stopping.to( :stopped )       .automatically
>  
>      stopped.to( :finish )         .automatically
>    end
> diff --git a/server/lib/deltacloud/drivers/terremark/terremark_driver.rb b/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
> index c93bfb3..0bdfdac 100644
> --- a/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
> +++ b/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
> @@ -118,8 +118,8 @@ VAPP_STATE_MAP = { "0" =>  "PENDING", "1" =>  "PENDING", "2" =>  "STOPPED", "4"
>      pending.to(:stopped)          .automatically
>      stopped.to(:running)          .on( :start )
>      running.to(:running)          .on( :reboot )
> -    running.to(:shutting_down)    .on( :stop )
> -    shutting_down.to(:stopped)    .automatically
> +    running.to(:stopping)         .on( :stop )
> +    stopping.to(:stopped)         .automatically
>      stopped.to(:finish)           .on( :destroy )
>     end
>  
> diff --git a/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb b/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
> index e2e7654..4fbbb4b 100644
> --- a/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
> +++ b/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
> @@ -69,8 +69,8 @@ module Deltacloud::Drivers::VSphere
>        pending.to(:stopped)        .automatically
>        stopped.to(:running)        .on( :start )
>        running.to(:running)        .on( :reboot )
> -      running.to(:shutting_down)  .on( :stop )
> -      shutting_down.to(:stopped)  .automatically
> +      running.to(:stopping)       .on( :stop )
> +      stopping.to(:stopped)       .automatically
>        stopped.to(:finish)         .on( :destroy )
>      end
>  
> diff --git a/server/lib/deltacloud/state_machine.rb b/server/lib/deltacloud/state_machine.rb
> index 19fb9f2..facd4ba 100644
> --- a/server/lib/deltacloud/state_machine.rb
> +++ b/server/lib/deltacloud/state_machine.rb
> @@ -18,7 +18,9 @@ module Deltacloud
>    class StateMachine
>  
>      attr_reader :states
> -    def initialize(&block)
> +    def initialize(opts = {}, &block)
> +      @all_states = opts[:all_states]
> +      @all_actions = opts[:all_actions]
>        @states  = []
>        instance_eval &block if block
>      end
> @@ -32,6 +34,9 @@ module Deltacloud
>      end
>  
>      def state(name)
> +      unless valid_state_name?(name)
> +        raise "State '#{name}' not in list of allowed states"
> +      end
>        state = @states.find{|e| e.name == name.to_sym}
>        if ( state.nil? )
>          state = State.new( self, name.to_sym )
> @@ -40,6 +45,14 @@ module Deltacloud
>        state
>      end
>  
> +    def valid_state_name?(name)
> +      @all_states.nil? || @all_states.include?(name.to_sym)
> +    end
> +
> +    def valid_action_name?(name)
> +      @all_actions.nil? || @all_actions.include?(name.to_sym)
> +    end
> +
>      def method_missing(sym,*args)
>        return state( sym ) if ( args.empty? )
>        super( sym, *args )
> @@ -90,6 +103,9 @@ module Deltacloud
>        end
>  
>        def on(action)
> +        unless @machine.valid_action_name?(action)
> +          raise "Action '#{action}' not in list of allowed actions"
> +        end
>          @action = action
>        end
>  
> diff --git a/site/content/api.mdown b/site/content/api.mdown
> index eb0114e..8ce2db3 100644
> --- a/site/content/api.mdown
> +++ b/site/content/api.mdown
> @@ -59,7 +59,7 @@ Each Image defines the root partition and initial storage for the Instance opera
>  ##### Instance States
>  
>  These represent the Instance lifecycle; at any time an Instance will be in one of
> - *start, pending, running, stopped, shutting_down, finished*.
> + *start, pending, running, stopped, stopping, finished*.
>  
>  ##### Keys
>  
> @@ -929,9 +929,9 @@ machine for ***instances*** from the given cloud.
>        </state>
>        <state name='running'>
>          <transition action='reboot' to='running'></transition>
> -        <transition action='stop' to='shutting_down'></transition>
> +        <transition action='stop' to='stopping'></transition>
>        </state>
> -      <state name='shutting_down'>
> +      <state name='stopping'>
>          <transition auto='true' to='stopped'></transition>
>        </state>
>        <state name='stopped'>
> diff --git a/site/content/developers.mdown b/site/content/developers.mdown
> index d5ea697..946ea47 100644
> --- a/site/content/developers.mdown
> +++ b/site/content/developers.mdown
> @@ -419,8 +419,8 @@ look like is:
>        start.to( :pending )          .on( :create )
>        pending.to( :running )        .automatically
>        running.to( :running )        .on( :reboot )
> -      running.to( :shutting_down )  .on( :stop )
> -      shutting_down.to( :stopped )  .automatically
> +      running.to( :stopping )  .on( :stop )
> +      stopping.to( :stopped )  .automatically
>        stopped.to( :finish )         .automatically
>      end
>  
> @@ -432,7 +432,7 @@ Valid states are
>  - **`:begin`**
>  - **`:pending`**
>  - **`:running`**
> -- **`:shutting_down`**
> +- **`:stopping`**
>  - **`:stopped`**
>  - **`:end`**
>  


Re: [PATCH 2/2] Instance states: settle on fixed set of possible states/actions

Posted by "marios@redhat.com" <ma...@redhat.com>.
bump (can't find the commit in git log - thanks to Dies Kopper)

On 02/03/12 02:02, lutter@redhat.com wrote:
> From: David Lutterkort <lu...@redhat.com>
> 
> We now enforce that each driver only uses instance states and actions that
> come from the approved list of such entities. This helps guard against
> simple mistakes in writing drivers.
> ---
>  server/lib/deltacloud/base_driver/base_driver.rb   |    7 ++++++-
>  .../lib/deltacloud/drivers/condor/condor_driver.rb |    2 +-
>  server/lib/deltacloud/drivers/ec2/ec2_driver.rb    |    3 ++-
>  .../drivers/opennebula/opennebula_driver.rb        |    4 ++--
>  .../drivers/openstack/openstack_driver.rb          |    4 ++--
>  .../drivers/rackspace/rackspace_driver.rb          |    4 ++--
>  .../drivers/rimuhosting/rimuhosting_driver.rb      |    4 ++--
>  .../drivers/terremark/terremark_driver.rb          |    4 ++--
>  .../deltacloud/drivers/vsphere/vsphere_driver.rb   |    4 ++--
>  server/lib/deltacloud/state_machine.rb             |   18 +++++++++++++++++-
>  site/content/api.mdown                             |    6 +++---
>  site/content/developers.mdown                      |    6 +++---
>  12 files changed, 44 insertions(+), 22 deletions(-)
> 
> diff --git a/server/lib/deltacloud/base_driver/base_driver.rb b/server/lib/deltacloud/base_driver/base_driver.rb
> index dcc3b9a..01dd5e7 100644
> --- a/server/lib/deltacloud/base_driver/base_driver.rb
> +++ b/server/lib/deltacloud/base_driver/base_driver.rb
> @@ -22,6 +22,11 @@ module Deltacloud
>  
>      include ExceptionHandler
>  
> +    STATE_MACHINE_OPTS = {
> +      :all_states => [:start, :pending, :running, :stopping, :stopped, :finish],
> +      :all_actions => [:create, :reboot, :stop, :start, :destroy]
> +    }
> +
>      def name
>        self.class.name.split('::').last.gsub('Driver', '').downcase
>      end
> @@ -90,7 +95,7 @@ module Deltacloud
>      end
>  
>      def self.define_instance_states(&block)
> -      machine = ::Deltacloud::StateMachine.new(&block)
> +      machine = ::Deltacloud::StateMachine.new(STATE_MACHINE_OPTS, &block)
>        @instance_state_machine = machine
>      end
>  
> diff --git a/server/lib/deltacloud/drivers/condor/condor_driver.rb b/server/lib/deltacloud/drivers/condor/condor_driver.rb
> index f48c9d3..f5cb741 100644
> --- a/server/lib/deltacloud/drivers/condor/condor_driver.rb
> +++ b/server/lib/deltacloud/drivers/condor/condor_driver.rb
> @@ -175,7 +175,7 @@ module Deltacloud
>            pending.to( :running )        .automatically
>            pending.to( :finish )         .on(:destroy)
>            running.to( :running )        .on( :reboot )
> -          running.to( :shutting_down )  .on( :destroy )
> +          running.to( :stopping )       .on( :destroy )
>            pending.to( :finish )         .automatically
>          end
>  
> diff --git a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
> index 74e110f..5f55ecf 100644
> --- a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
> +++ b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
> @@ -118,7 +118,8 @@ module Deltacloud
>            stopped.to( :running )        .on( :start )
>            running.to( :running )        .on( :reboot )
>            running.to( :stopping )       .on( :stop )
> -          shutting_down.to( :stopped )  .automatically
> +          stopping.to(:stopped)         .automatically
> +          stopping.to(:finish)          .automatically
>            stopped.to( :finish )         .automatically
>          end
>  
> diff --git a/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb b/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb
> index 3b00eca..baae2a2 100644
> --- a/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb
> +++ b/server/lib/deltacloud/drivers/opennebula/opennebula_driver.rb
> @@ -152,8 +152,8 @@ class OpennebulaDriver < Deltacloud::BaseDriver
>      running.to(:running)        .on( :reboot )
>      running.to(:stopping)       .on( :stop )
>      stopping.to(:stopped)       .automatically
> -    running.to(:shutting_down)  .on( :destroy )
> -    shutting_down.to(:finish)   .automatically
> +    running.to(:stopping)       .on( :destroy )
> +    stopping.to(:finish)        .automatically
>    end
>  
>    def instances(credentials, opts=nil)
> diff --git a/server/lib/deltacloud/drivers/openstack/openstack_driver.rb b/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
> index 845ddee..161e8b1 100644
> --- a/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
> +++ b/server/lib/deltacloud/drivers/openstack/openstack_driver.rb
> @@ -34,8 +34,8 @@ module Deltacloud
>            start.to( :pending )          .on( :create )
>            pending.to( :running )        .automatically
>            running.to( :running )        .on( :reboot )
> -          running.to( :shutting_down )  .on( :stop )
> -          shutting_down.to( :stopped )  .automatically
> +          running.to( :stopping )       .on( :stop )
> +          stopping.to( :stopped )       .automatically
>            stopped.to( :finish )         .automatically
>          end
>  
> diff --git a/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb b/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb
> index 3779c41..32ba78a 100644
> --- a/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb
> +++ b/server/lib/deltacloud/drivers/rackspace/rackspace_driver.rb
> @@ -193,8 +193,8 @@ class RackspaceDriver < Deltacloud::BaseDriver
>      start.to( :pending )          .on( :create )
>      pending.to( :running )        .automatically
>      running.to( :running )        .on( :reboot )
> -    running.to( :shutting_down )  .on( :stop )
> -    shutting_down.to( :stopped )  .automatically
> +    running.to( :stopping )       .on( :stop )
> +    stopping.to( :stopped )       .automatically
>      stopped.to( :finish )         .automatically
>    end
>  
> diff --git a/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb b/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb
> index 6b61b8c..67c415c 100644
> --- a/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb
> +++ b/server/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb
> @@ -142,9 +142,9 @@ class RimuHostingDriver < Deltacloud::BaseDriver
>      pending.to( :running )        .automatically
>  
>      running.to( :running )        .on(:reboot)
> -    running.to( :shutting_down )  .on(:stop)
> +    running.to( :stopping )       .on(:stop)
>  
> -    shutting_down.to( :stopped )  .automatically
> +    stopping.to( :stopped )       .automatically
>  
>      stopped.to( :finish )         .automatically
>    end
> diff --git a/server/lib/deltacloud/drivers/terremark/terremark_driver.rb b/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
> index c93bfb3..0bdfdac 100644
> --- a/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
> +++ b/server/lib/deltacloud/drivers/terremark/terremark_driver.rb
> @@ -118,8 +118,8 @@ VAPP_STATE_MAP = { "0" =>  "PENDING", "1" =>  "PENDING", "2" =>  "STOPPED", "4"
>      pending.to(:stopped)          .automatically
>      stopped.to(:running)          .on( :start )
>      running.to(:running)          .on( :reboot )
> -    running.to(:shutting_down)    .on( :stop )
> -    shutting_down.to(:stopped)    .automatically
> +    running.to(:stopping)         .on( :stop )
> +    stopping.to(:stopped)         .automatically
>      stopped.to(:finish)           .on( :destroy )
>     end
>  
> diff --git a/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb b/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
> index e2e7654..4fbbb4b 100644
> --- a/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
> +++ b/server/lib/deltacloud/drivers/vsphere/vsphere_driver.rb
> @@ -69,8 +69,8 @@ module Deltacloud::Drivers::VSphere
>        pending.to(:stopped)        .automatically
>        stopped.to(:running)        .on( :start )
>        running.to(:running)        .on( :reboot )
> -      running.to(:shutting_down)  .on( :stop )
> -      shutting_down.to(:stopped)  .automatically
> +      running.to(:stopping)       .on( :stop )
> +      stopping.to(:stopped)       .automatically
>        stopped.to(:finish)         .on( :destroy )
>      end
>  
> diff --git a/server/lib/deltacloud/state_machine.rb b/server/lib/deltacloud/state_machine.rb
> index 19fb9f2..facd4ba 100644
> --- a/server/lib/deltacloud/state_machine.rb
> +++ b/server/lib/deltacloud/state_machine.rb
> @@ -18,7 +18,9 @@ module Deltacloud
>    class StateMachine
>  
>      attr_reader :states
> -    def initialize(&block)
> +    def initialize(opts = {}, &block)
> +      @all_states = opts[:all_states]
> +      @all_actions = opts[:all_actions]
>        @states  = []
>        instance_eval &block if block
>      end
> @@ -32,6 +34,9 @@ module Deltacloud
>      end
>  
>      def state(name)
> +      unless valid_state_name?(name)
> +        raise "State '#{name}' not in list of allowed states"
> +      end
>        state = @states.find{|e| e.name == name.to_sym}
>        if ( state.nil? )
>          state = State.new( self, name.to_sym )
> @@ -40,6 +45,14 @@ module Deltacloud
>        state
>      end
>  
> +    def valid_state_name?(name)
> +      @all_states.nil? || @all_states.include?(name.to_sym)
> +    end
> +
> +    def valid_action_name?(name)
> +      @all_actions.nil? || @all_actions.include?(name.to_sym)
> +    end
> +
>      def method_missing(sym,*args)
>        return state( sym ) if ( args.empty? )
>        super( sym, *args )
> @@ -90,6 +103,9 @@ module Deltacloud
>        end
>  
>        def on(action)
> +        unless @machine.valid_action_name?(action)
> +          raise "Action '#{action}' not in list of allowed actions"
> +        end
>          @action = action
>        end
>  
> diff --git a/site/content/api.mdown b/site/content/api.mdown
> index eb0114e..8ce2db3 100644
> --- a/site/content/api.mdown
> +++ b/site/content/api.mdown
> @@ -59,7 +59,7 @@ Each Image defines the root partition and initial storage for the Instance opera
>  ##### Instance States
>  
>  These represent the Instance lifecycle; at any time an Instance will be in one of
> - *start, pending, running, stopped, shutting_down, finished*.
> + *start, pending, running, stopped, stopping, finished*.
>  
>  ##### Keys
>  
> @@ -929,9 +929,9 @@ machine for ***instances*** from the given cloud.
>        </state>
>        <state name='running'>
>          <transition action='reboot' to='running'></transition>
> -        <transition action='stop' to='shutting_down'></transition>
> +        <transition action='stop' to='stopping'></transition>
>        </state>
> -      <state name='shutting_down'>
> +      <state name='stopping'>
>          <transition auto='true' to='stopped'></transition>
>        </state>
>        <state name='stopped'>
> diff --git a/site/content/developers.mdown b/site/content/developers.mdown
> index d5ea697..946ea47 100644
> --- a/site/content/developers.mdown
> +++ b/site/content/developers.mdown
> @@ -419,8 +419,8 @@ look like is:
>        start.to( :pending )          .on( :create )
>        pending.to( :running )        .automatically
>        running.to( :running )        .on( :reboot )
> -      running.to( :shutting_down )  .on( :stop )
> -      shutting_down.to( :stopped )  .automatically
> +      running.to( :stopping )  .on( :stop )
> +      stopping.to( :stopped )  .automatically
>        stopped.to( :finish )         .automatically
>      end
>  
> @@ -432,7 +432,7 @@ Valid states are
>  - **`:begin`**
>  - **`:pending`**
>  - **`:running`**
> -- **`:shutting_down`**
> +- **`:stopping`**
>  - **`:stopped`**
>  - **`:end`**
>