Class: Vagrant::Action::Builtin::GracefulHalt

Inherits:
Object
  • Object
show all
Defined in:
lib/vagrant/action/builtin/graceful_halt.rb

Overview

This middleware class will attempt to perform a graceful shutdown of the machine using the guest implementation. This middleware is compatible with the Call middleware so you can branch based on the result, which is true if the halt succeeded and false otherwise.

Instance Method Summary collapse

Constructor Details

#initialize(app, env, target_state, source_state = nil) ⇒ GracefulHalt

Note: Any of the arguments can be arrays as well.

Parameters:

  • target_state (Symbol)

    The target state ID that means that the machine was properly shut down.

  • source_state (Symbol) (defaults to: nil)

    The source state ID that the machine must be in to be shut down.



17
18
19
20
21
22
# File 'lib/vagrant/action/builtin/graceful_halt.rb', line 17

def initialize(app, env, target_state, source_state=nil)
  @app          = app
  @logger       = Log4r::Logger.new("vagrant::action::builtin::graceful_halt")
  @source_state = source_state
  @target_state = target_state
end

Instance Method Details

#call(env) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/vagrant/action/builtin/graceful_halt.rb', line 24

def call(env)
  graceful = true
  graceful = !env[:force_halt] if env.has_key?(:force_halt)

  # By default, we didn't succeed.
  env[:result] = false

  if graceful && @source_state
    @logger.info("Verifying source state of machine: #{@source_state.inspect}")

    # If we're not in the proper source state, then we don't
    # attempt to halt the machine
    current_state = env[:machine].state.id
    if current_state != @source_state
      @logger.info("Invalid source state, not halting: #{current_state}")
      graceful = false
    end
  end

  # Only attempt to perform graceful shutdown under certain cases
  # checked above.
  if graceful
    env[:ui].info I18n.t("vagrant.actions.vm.halt.graceful")
    env[:machine].guest.halt

    @logger.debug("Waiting for target graceful halt state: #{@target_state}")
    count = 0
    while env[:machine].state.id != @target_state
      count += 1
      return if count >= env[:machine].config.vm.graceful_halt_retry_count
      sleep env[:machine].config.vm.graceful_halt_retry_interval
    end

    # The result of this matters on whether we reached our
    # proper target state or not.
    env[:result] = env[:machine].state.id == @target_state

    if env[:result]
      @logger.info("Gracefully halted.")
    else
      @logger.info("Graceful halt failed.")
    end
  end

  @app.call(env)
end