Class: Bosh::Agent::Message::Drain

Inherits:
Object
  • Object
show all
Defined in:
lib/bosh_agent/message/drain.rb

Constant Summary collapse

HM_NOTIFY_TIMEOUT =
5

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ Drain

Returns a new instance of Drain.



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/bosh_agent/message/drain.rb', line 20

def initialize(args)
  @logger     = Bosh::Agent::Config.logger
  @nats       = Bosh::Agent::Config.nats
  @agent_id   = Bosh::Agent::Config.agent_id
  @old_spec   = Bosh::Agent::Config.state.to_hash
  @args       = args

  @drain_type = args[0]
  @spec       = args[1]
  @drain_script = DrainScript.new
end

Class Method Details

.long_running?Boolean

Returns:

  • (Boolean)


16
17
18
# File 'lib/bosh_agent/message/drain.rb', line 16

def self.long_running?
  true
end

.process(args) ⇒ Object



12
13
14
# File 'lib/bosh_agent/message/drain.rb', line 12

def self.process(args)
  self.new(args).drain
end

Instance Method Details

#drainObject



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/bosh_agent/message/drain.rb', line 52

def drain
  @logger.info("Draining: #{@args.inspect}")

  if Bosh::Agent::Config.configure
    Bosh::Agent::Monit.unmonitor_services
  end

  case @drain_type
  when "shutdown"
    drain_for_shutdown
  when "update"
    drain_for_update
  when "status"
    drain_check_status
  else
    raise Bosh::Agent::MessageHandlerError, "Unknown drain type #{@drain_type}"
  end
end

#drain_check_statusObject



112
113
114
# File 'lib/bosh_agent/message/drain.rb', line 112

def drain_check_status
  run_drain_script("job_check_status", "hash_unchanged", [])
end

#drain_for_shutdownObject



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/bosh_agent/message/drain.rb', line 84

def drain_for_shutdown
  lock = Monitor.new
  delivery_cond = lock.new_cond
  delivered = false

  if @nats
    # HM notification should be in sync with VM shutdown
    Thread.new do
      @nats.publish("hm.agent.shutdown.#{@agent_id}") do
        lock.synchronize do
          delivered = true
          delivery_cond.signal
        end
      end
    end
  end

  lock.synchronize do
    delivery_cond.wait(HM_NOTIFY_TIMEOUT) unless delivered
  end

  if @old_spec.key?('job') && drain_script_exists?
    run_drain_script("job_shutdown", "hash_unchanged", [])
  else
    0
  end
end

#drain_for_updateObject



71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/bosh_agent/message/drain.rb', line 71

def drain_for_update
  if @spec.nil?
    raise Bosh::Agent::MessageHandlerError, "Drain update called without apply spec"
  end

  if @old_spec.key?('job') && drain_script_exists?
    # HACK: We go through the motions below to be able to support drain scripts written as shell scripts
    run_drain_script(job_change, hash_change, updated_packages.flatten)
  else
    0
  end
end

#drain_script_exists?Boolean

Returns:

  • (Boolean)


144
145
146
# File 'lib/bosh_agent/message/drain.rb', line 144

def drain_script_exists?
  @drain_script.exists?
end

#hash_changeObject



42
43
44
45
46
47
48
49
50
# File 'lib/bosh_agent/message/drain.rb', line 42

def hash_change
  if !@old_spec.key?('configuration_hash')
    "hash_new"
  elsif @old_spec['configuration_hash'] == @spec['configuration_hash']
    "hash_unchanged"
  else
    "hash_changed"
  end
end

#job_changeObject



32
33
34
35
36
37
38
39
40
# File 'lib/bosh_agent/message/drain.rb', line 32

def job_change
  if !@old_spec.key?('job')
    "job_new"
  elsif @old_spec['job']['sha1'] == @spec['job']['sha1']
    "job_unchanged"
  else
    "job_changed"
  end
end

#run_drain_script(job_updated, hash_updated, updated_packages) ⇒ Object



116
117
118
# File 'lib/bosh_agent/message/drain.rb', line 116

def run_drain_script(job_updated, hash_updated, updated_packages)
  @drain_script.run(job_updated, hash_updated, updated_packages)
end

#updated_packagesObject



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/bosh_agent/message/drain.rb', line 120

def updated_packages
  updated_packages = []

  return updated_packages unless @old_spec.key?('packages')

  # Check old packages
  updated_packages << @old_spec['packages'].find_all do |pkg_name, pkg|
    if @spec['packages'].key?(pkg_name)
      pkg['sha1'] != @spec['packages'][pkg_name]['sha1']
    else
      false
    end
  end.collect { |package_name, pkg| package_name }

  # New packages counts as new
  updated_packages << @spec['packages'].find_all do |pkg_name, pkg|
    unless @old_spec['packages'].key?(pkg_name)
      true
    else
      false
    end
  end.collect { |package_name, pkg| package_name }
end