bosh-director 1.2619.0 → 1.2624.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/bosh/director/deployment_plan.rb +1 -1
- data/lib/bosh/director/deployment_plan/assembler.rb +44 -51
- data/lib/bosh/director/deployment_plan/deployment_spec_parser.rb +1 -1
- data/lib/bosh/director/deployment_plan/instance.rb +112 -50
- data/lib/bosh/director/deployment_plan/instance_vm_binder.rb +5 -27
- data/lib/bosh/director/deployment_plan/job.rb +6 -7
- data/lib/bosh/director/deployment_plan/job_spec_parser.rb +3 -2
- data/lib/bosh/director/deployment_plan/resource_pool.rb +35 -31
- data/lib/bosh/director/deployment_plan/{idle_vm.rb → vm.rb} +7 -6
- data/lib/bosh/director/errand/job_manager.rb +1 -1
- data/lib/bosh/director/instance_updater/vm_updater.rb +2 -38
- data/lib/bosh/director/resource_pool_updater.rb +48 -52
- data/lib/bosh/director/version.rb +1 -1
- metadata +25 -25
@@ -4,7 +4,7 @@ module Bosh::Director
|
|
4
4
|
end
|
5
5
|
|
6
6
|
require 'bosh/director/deployment_plan/compilation_config'
|
7
|
-
require 'bosh/director/deployment_plan/
|
7
|
+
require 'bosh/director/deployment_plan/vm'
|
8
8
|
require 'bosh/director/deployment_plan/instance'
|
9
9
|
require 'bosh/director/deployment_plan/job'
|
10
10
|
require 'bosh/director/deployment_plan/network'
|
@@ -35,10 +35,10 @@ module Bosh::Director
|
|
35
35
|
def bind_existing_deployment
|
36
36
|
lock = Mutex.new
|
37
37
|
ThreadPool.new(:max_threads => Config.max_threads).wrap do |pool|
|
38
|
-
@deployment_plan.vms.each do |
|
38
|
+
@deployment_plan.vms.each do |vm_model|
|
39
39
|
pool.process do
|
40
|
-
with_thread_name("bind_existing_deployment(#{
|
41
|
-
bind_existing_vm(
|
40
|
+
with_thread_name("bind_existing_deployment(#{vm_model.agent_id})") do
|
41
|
+
bind_existing_vm(vm_model, lock)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
@@ -46,15 +46,15 @@ module Bosh::Director
|
|
46
46
|
end
|
47
47
|
|
48
48
|
# Queries agent for VM state and updates deployment plan accordingly
|
49
|
-
# @param [Models::Vm]
|
49
|
+
# @param [Models::Vm] vm_model VM database model
|
50
50
|
# @param [Mutex] lock Lock to hold on to while updating deployment plan
|
51
|
-
def bind_existing_vm(
|
52
|
-
state = get_state(
|
51
|
+
def bind_existing_vm(vm_model, lock)
|
52
|
+
state = get_state(vm_model)
|
53
53
|
lock.synchronize do
|
54
54
|
@logger.debug('Processing VM network reservations')
|
55
55
|
reservations = get_network_reservations(state)
|
56
56
|
|
57
|
-
instance =
|
57
|
+
instance = vm_model.instance
|
58
58
|
if instance
|
59
59
|
bind_instance(instance, state, reservations)
|
60
60
|
else
|
@@ -62,10 +62,10 @@ module Bosh::Director
|
|
62
62
|
resource_pool = @deployment_plan.resource_pool(resource_pool_name)
|
63
63
|
if resource_pool
|
64
64
|
@logger.debug("Binding VM to resource pool '#{resource_pool_name}'")
|
65
|
-
bind_idle_vm(
|
65
|
+
bind_idle_vm(vm_model, resource_pool, state, reservations)
|
66
66
|
else
|
67
67
|
@logger.debug("Resource pool '#{resource_pool_name}' does not exist, marking VM for deletion")
|
68
|
-
@deployment_plan.delete_vm(
|
68
|
+
@deployment_plan.delete_vm(vm_model)
|
69
69
|
end
|
70
70
|
end
|
71
71
|
@logger.debug('Finished processing VM network reservations')
|
@@ -73,36 +73,36 @@ module Bosh::Director
|
|
73
73
|
end
|
74
74
|
|
75
75
|
# Binds idle VM to a resource pool with a proper network reservation
|
76
|
-
# @param [Models::Vm]
|
76
|
+
# @param [Models::Vm] vm_model VM DB model
|
77
77
|
# @param [DeploymentPlan::ResourcePool] resource_pool Resource pool
|
78
78
|
# @param [Hash] state VM state according to its agent
|
79
79
|
# @param [Hash] reservations Network reservations
|
80
|
-
def bind_idle_vm(
|
80
|
+
def bind_idle_vm(vm_model, resource_pool, state, reservations)
|
81
81
|
if reservations.any? { |network_name, reservation| reservation.static? }
|
82
|
-
@logger.debug("Releasing all network reservations for VM `#{
|
82
|
+
@logger.debug("Releasing all network reservations for VM `#{vm_model.cid}'")
|
83
83
|
reservations.each do |network_name, reservation|
|
84
|
-
@logger.debug("Releasing #{reservation.type} network reservation `#{network_name}' for VM `#{
|
84
|
+
@logger.debug("Releasing #{reservation.type} network reservation `#{network_name}' for VM `#{vm_model.cid}'")
|
85
85
|
resource_pool.network.release(reservation)
|
86
86
|
end
|
87
87
|
|
88
|
-
@logger.debug("Deleting VM `#{
|
89
|
-
@deployment_plan.delete_vm(
|
88
|
+
@logger.debug("Deleting VM `#{vm_model.cid}' with static network reservation")
|
89
|
+
@deployment_plan.delete_vm(vm_model)
|
90
90
|
return
|
91
91
|
end
|
92
92
|
|
93
|
-
@logger.debug("Adding VM `#{
|
93
|
+
@logger.debug("Adding VM `#{vm_model.cid}' to resource pool `#{resource_pool.name}'")
|
94
94
|
idle_vm = resource_pool.add_idle_vm
|
95
|
-
idle_vm.
|
95
|
+
idle_vm.model = vm_model
|
96
96
|
idle_vm.current_state = state
|
97
97
|
|
98
98
|
network_name = resource_pool.network.name
|
99
99
|
reservation = reservations[network_name]
|
100
100
|
if reservation
|
101
101
|
@logger.debug("Using existing `#{reservation.type}' " +
|
102
|
-
"network reservation of `#{reservation.ip}' for VM `#{
|
102
|
+
"network reservation of `#{reservation.ip}' for VM `#{vm_model.cid}'")
|
103
103
|
idle_vm.use_reservation(reservation)
|
104
104
|
else
|
105
|
-
@logger.debug("No network reservation for VM `#{
|
105
|
+
@logger.debug("No network reservation for VM `#{vm_model.cid}'")
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
@@ -139,15 +139,8 @@ module Bosh::Director
|
|
139
139
|
return
|
140
140
|
end
|
141
141
|
|
142
|
-
@logger.debug("Found job instance `#{instance_name}'")
|
143
|
-
instance.
|
144
|
-
instance.current_state = state
|
145
|
-
|
146
|
-
@logger.debug("Copying job instance `#{instance_name}' network reservations")
|
147
|
-
instance.take_network_reservations(reservations)
|
148
|
-
|
149
|
-
@logger.debug("Copying job instance `#{instance_name}' resource pool reservation")
|
150
|
-
job.resource_pool.mark_active_vm
|
142
|
+
@logger.debug("Found existing job instance `#{instance_name}'")
|
143
|
+
instance.bind_existing_instance(instance_model, state, reservations)
|
151
144
|
end
|
152
145
|
|
153
146
|
def get_network_reservations(state)
|
@@ -163,16 +156,16 @@ module Bosh::Director
|
|
163
156
|
reservations
|
164
157
|
end
|
165
158
|
|
166
|
-
def get_state(
|
167
|
-
@logger.debug("Requesting current VM state for: #{
|
168
|
-
agent = AgentClient.with_defaults(
|
159
|
+
def get_state(vm_model)
|
160
|
+
@logger.debug("Requesting current VM state for: #{vm_model.agent_id}")
|
161
|
+
agent = AgentClient.with_defaults(vm_model.agent_id)
|
169
162
|
state = agent.get_state
|
170
163
|
|
171
164
|
@logger.debug("Received VM state: #{state.pretty_inspect}")
|
172
|
-
verify_state(
|
165
|
+
verify_state(vm_model, state)
|
173
166
|
@logger.debug('Verified VM state')
|
174
167
|
|
175
|
-
migrate_legacy_state(
|
168
|
+
migrate_legacy_state(vm_model, state)
|
176
169
|
state.delete('release')
|
177
170
|
if state.include?('job')
|
178
171
|
state['job'].delete('release')
|
@@ -180,21 +173,21 @@ module Bosh::Director
|
|
180
173
|
state
|
181
174
|
end
|
182
175
|
|
183
|
-
def verify_state(
|
184
|
-
instance =
|
176
|
+
def verify_state(vm_model, state)
|
177
|
+
instance = vm_model.instance
|
185
178
|
|
186
|
-
if instance && instance.deployment_id !=
|
179
|
+
if instance && instance.deployment_id != vm_model.deployment_id
|
187
180
|
# Both VM and instance should reference same deployment
|
188
181
|
raise VmInstanceOutOfSync,
|
189
|
-
"VM `#{
|
182
|
+
"VM `#{vm_model.cid}' and instance " +
|
190
183
|
"`#{instance.job}/#{instance.index}' " +
|
191
184
|
"don't belong to the same deployment"
|
192
185
|
end
|
193
186
|
|
194
187
|
unless state.kind_of?(Hash)
|
195
|
-
@logger.error("Invalid state for `#{
|
188
|
+
@logger.error("Invalid state for `#{vm_model.cid}': #{state.pretty_inspect}")
|
196
189
|
raise AgentInvalidStateFormat,
|
197
|
-
"VM `#{
|
190
|
+
"VM `#{vm_model.cid}' returns invalid state: " +
|
198
191
|
"expected Hash, got #{state.class}"
|
199
192
|
end
|
200
193
|
|
@@ -203,7 +196,7 @@ module Bosh::Director
|
|
203
196
|
|
204
197
|
if actual_deployment_name != expected_deployment_name
|
205
198
|
raise AgentWrongDeployment,
|
206
|
-
"VM `#{
|
199
|
+
"VM `#{vm_model.cid}' is out of sync: " +
|
207
200
|
'expected to be a part of deployment ' +
|
208
201
|
"`#{expected_deployment_name}' " +
|
209
202
|
'but is actually a part of deployment ' +
|
@@ -215,7 +208,7 @@ module Bosh::Director
|
|
215
208
|
|
216
209
|
if instance.nil? && !actual_job.nil?
|
217
210
|
raise AgentUnexpectedJob,
|
218
|
-
"VM `#{
|
211
|
+
"VM `#{vm_model.cid}' is out of sync: " +
|
219
212
|
"it reports itself as `#{actual_job}/#{actual_index}' but " +
|
220
213
|
'there is no instance reference in DB'
|
221
214
|
end
|
@@ -237,22 +230,22 @@ module Bosh::Director
|
|
237
230
|
end
|
238
231
|
else
|
239
232
|
raise AgentJobMismatch,
|
240
|
-
"VM `#{
|
233
|
+
"VM `#{vm_model.cid}' is out of sync: " +
|
241
234
|
"it reports itself as `#{actual_job}/#{actual_index}' but " +
|
242
235
|
"according to DB it is `#{instance.job}/#{instance.index}'"
|
243
236
|
end
|
244
237
|
end
|
245
238
|
end
|
246
239
|
|
247
|
-
def migrate_legacy_state(
|
240
|
+
def migrate_legacy_state(vm_model, state)
|
248
241
|
# Persisting apply spec for VMs that were introduced before we started
|
249
242
|
# persisting it on apply itself (this is for cloudcheck purposes only)
|
250
|
-
if
|
243
|
+
if vm_model.apply_spec.nil?
|
251
244
|
# The assumption is that apply_spec <=> VM state
|
252
|
-
|
245
|
+
vm_model.update(:apply_spec => state)
|
253
246
|
end
|
254
247
|
|
255
|
-
instance =
|
248
|
+
instance = vm_model.instance
|
256
249
|
if instance
|
257
250
|
disk_size = state['persistent_disk'].to_i
|
258
251
|
persistent_disk = instance.persistent_disk
|
@@ -354,12 +347,12 @@ module Bosh::Director
|
|
354
347
|
|
355
348
|
@event_log.begin_stage('Deleting unneeded VMs', unneeded_vms.size)
|
356
349
|
ThreadPool.new(:max_threads => Config.max_threads).wrap do |pool|
|
357
|
-
unneeded_vms.each do |
|
350
|
+
unneeded_vms.each do |vm_model|
|
358
351
|
pool.process do
|
359
|
-
@event_log.track(
|
360
|
-
@logger.info("Delete unneeded VM #{
|
361
|
-
@cloud.delete_vm(
|
362
|
-
|
352
|
+
@event_log.track(vm_model.cid) do
|
353
|
+
@logger.info("Delete unneeded VM #{vm_model.cid}")
|
354
|
+
@cloud.delete_vm(vm_model.cid)
|
355
|
+
vm_model.destroy
|
363
356
|
end
|
364
357
|
end
|
365
358
|
end
|
@@ -118,7 +118,7 @@ module Bosh::Director
|
|
118
118
|
job_spec.recursive_merge!(state_overrides)
|
119
119
|
end
|
120
120
|
|
121
|
-
@deployment.add_job(Job.parse(@deployment, job_spec, @event_log))
|
121
|
+
@deployment.add_job(Job.parse(@deployment, job_spec, @event_log, @logger))
|
122
122
|
end
|
123
123
|
end
|
124
124
|
end
|
@@ -29,10 +29,10 @@ module Bosh::Director
|
|
29
29
|
attr_accessor :state
|
30
30
|
|
31
31
|
# @return [Hash] current state as provided by the BOSH Agent
|
32
|
-
|
32
|
+
attr_reader :current_state
|
33
33
|
|
34
|
-
# @return [DeploymentPlan::
|
35
|
-
attr_reader :
|
34
|
+
# @return [DeploymentPlan::Vm] Associated resource pool VM
|
35
|
+
attr_reader :vm
|
36
36
|
|
37
37
|
# @return [Boolean] true if this instance needs to be recreated
|
38
38
|
attr_accessor :recreate
|
@@ -40,18 +40,18 @@ module Bosh::Director
|
|
40
40
|
# @return [Boolean] true if this instance needs to be restarted
|
41
41
|
attr_accessor :restart
|
42
42
|
|
43
|
-
##
|
44
43
|
# Creates a new instance specification based on the job and index.
|
45
|
-
#
|
46
44
|
# @param [DeploymentPlan::Job] job associated job
|
47
45
|
# @param [Integer] index index for this instance
|
48
|
-
def initialize(job, index)
|
46
|
+
def initialize(job, index, logger)
|
49
47
|
@job = job
|
50
48
|
@index = index
|
49
|
+
@logger = logger
|
50
|
+
|
51
51
|
@model = nil
|
52
52
|
@configuration_hash = nil
|
53
53
|
@template_hashes = nil
|
54
|
-
@
|
54
|
+
@vm = nil
|
55
55
|
@current_state = nil
|
56
56
|
|
57
57
|
@network_reservations = {}
|
@@ -72,33 +72,84 @@ module Bosh::Director
|
|
72
72
|
"#{@job.name}/#{@index}"
|
73
73
|
end
|
74
74
|
|
75
|
-
#
|
76
|
-
# @return [void]
|
77
|
-
def use_model(model)
|
78
|
-
if @model
|
79
|
-
raise DirectorError, 'Instance model is already bound'
|
80
|
-
end
|
81
|
-
@model = model
|
82
|
-
end
|
83
|
-
|
84
|
-
# Looks up a DB model for this instance, creates one if doesn't exist
|
85
|
-
# yet.
|
75
|
+
# Looks up a DB model for this instance, creates one if doesn't exist yet.
|
86
76
|
# @return [void]
|
87
77
|
def bind_model
|
88
78
|
@model ||= find_or_create_model
|
89
79
|
end
|
90
80
|
|
91
81
|
# Looks up instance model in DB and binds it to this instance spec.
|
92
|
-
# Instance model is created if it's not found in DB. New
|
82
|
+
# Instance model is created if it's not found in DB. New VM is
|
93
83
|
# allocated if instance DB record doesn't reference one.
|
94
84
|
# @return [void]
|
95
85
|
def bind_unallocated_vm
|
96
86
|
bind_model
|
97
87
|
if @model.vm.nil?
|
98
|
-
|
88
|
+
allocate_vm
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Updates this domain object to reflect an existing instance running on an existing vm
|
94
|
+
def bind_existing_instance(instance_model, state, reservations)
|
95
|
+
raise DirectorError, "Instance `#{self}' model is already bound" if @model
|
96
|
+
@model = instance_model
|
97
|
+
@current_state = state
|
98
|
+
|
99
|
+
take_network_reservations(reservations)
|
100
|
+
add_allocated_vm(instance_model.vm, state)
|
101
|
+
end
|
102
|
+
|
103
|
+
def apply_partial_vm_state
|
104
|
+
@logger.info('Applying partial VM state')
|
105
|
+
|
106
|
+
state = @vm.current_state
|
107
|
+
state['job'] = job.spec
|
108
|
+
state['index'] = index
|
109
|
+
|
110
|
+
# Apply the assignment to the VM
|
111
|
+
agent = AgentClient.with_defaults(@vm.model.agent_id)
|
112
|
+
agent.apply(state)
|
113
|
+
|
114
|
+
# Our assumption here is that director database access
|
115
|
+
# is much less likely to fail than VM agent communication
|
116
|
+
# so we only update database after we see a successful agent apply.
|
117
|
+
# If database update fails subsequent deploy will try to
|
118
|
+
# assign a new VM to this instance which is ok.
|
119
|
+
@vm.model.db.transaction do
|
120
|
+
@vm.model.update(:apply_spec => state)
|
121
|
+
@model.update(:vm => @vm.model)
|
122
|
+
end
|
123
|
+
|
124
|
+
@current_state = state
|
125
|
+
end
|
126
|
+
|
127
|
+
def apply_vm_state
|
128
|
+
@logger.info('Applying VM state')
|
129
|
+
|
130
|
+
state = {
|
131
|
+
'deployment' => @job.deployment.name,
|
132
|
+
'networks' => network_settings,
|
133
|
+
'resource_pool' => @job.resource_pool.spec,
|
134
|
+
'job' => @job.spec,
|
135
|
+
'index' => @index,
|
136
|
+
}
|
137
|
+
|
138
|
+
if disk_size > 0
|
139
|
+
state['persistent_disk'] = disk_size
|
99
140
|
end
|
141
|
+
|
142
|
+
@model.vm.update(:apply_spec => state)
|
143
|
+
|
144
|
+
agent = AgentClient.with_defaults(@model.vm.agent_id)
|
145
|
+
agent.apply(state)
|
146
|
+
|
147
|
+
# Agent will potentially return modified version of state
|
148
|
+
# with resolved dynamic networks information
|
149
|
+
@current_state = agent.get_state
|
100
150
|
end
|
101
151
|
|
152
|
+
##
|
102
153
|
# Syncs instance state with instance model in DB. This is needed because
|
103
154
|
# not all instance states are available in the deployment manifest and we
|
104
155
|
# we cannot really persist this data in the agent state (as VM might be
|
@@ -138,18 +189,6 @@ module Bosh::Director
|
|
138
189
|
@network_reservations[name] = reservation
|
139
190
|
end
|
140
191
|
|
141
|
-
##
|
142
|
-
# Take any existing valid network reservations
|
143
|
-
#
|
144
|
-
# @param [Hash<String, NetworkReservation>] reservations
|
145
|
-
# @return [void]
|
146
|
-
def take_network_reservations(reservations)
|
147
|
-
reservations.each do |name, provided_reservation|
|
148
|
-
reservation = @network_reservations[name]
|
149
|
-
reservation.take(provided_reservation) if reservation
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
192
|
##
|
154
193
|
# @return [Hash] BOSH network settings used for Agent apply call
|
155
194
|
def network_settings
|
@@ -220,8 +259,7 @@ module Bosh::Director
|
|
220
259
|
end
|
221
260
|
|
222
261
|
##
|
223
|
-
# @return [Boolean] returns true if the persistent disk is attached to the
|
224
|
-
# VM
|
262
|
+
# @return [Boolean] returns true if the persistent disk is attached to the VM
|
225
263
|
def disk_currently_attached?
|
226
264
|
current_state['persistent_disk'].to_i > 0
|
227
265
|
end
|
@@ -233,8 +271,7 @@ module Bosh::Director
|
|
233
271
|
end
|
234
272
|
|
235
273
|
##
|
236
|
-
# @return [Boolean] returns true if the expected resource pool differs
|
237
|
-
# from the one provided by the VM
|
274
|
+
# @return [Boolean] returns true if the expected resource pool differs from the one provided by the VM
|
238
275
|
def resource_pool_changed?
|
239
276
|
if @recreate || @job.deployment.recreate
|
240
277
|
return true
|
@@ -251,8 +288,7 @@ module Bosh::Director
|
|
251
288
|
# doesn't persist VM env to the version that does, there needs to
|
252
289
|
# be at least one deployment that recreates all VMs before the following
|
253
290
|
# code path gets exercised.
|
254
|
-
if @model && @model.vm && @model.vm.env &&
|
255
|
-
@job.resource_pool.env != @model.vm.env
|
291
|
+
if @model && @model.vm && @model.vm.env && @job.resource_pool.env != @model.vm.env
|
256
292
|
return true
|
257
293
|
end
|
258
294
|
|
@@ -270,6 +306,8 @@ module Bosh::Director
|
|
270
306
|
# @return [Boolean] returns true if the expected job configuration differs
|
271
307
|
# from the one provided by the VM
|
272
308
|
def job_changed?
|
309
|
+
return true if @current_state.nil?
|
310
|
+
|
273
311
|
job_spec = @job.spec
|
274
312
|
if job_spec != @current_state['job']
|
275
313
|
# The agent job spec could be in legacy form. job_spec cannot be,
|
@@ -330,8 +368,7 @@ module Bosh::Director
|
|
330
368
|
end
|
331
369
|
|
332
370
|
##
|
333
|
-
# @return [Set<Symbol>] returns a set of all of the specification
|
334
|
-
# differences
|
371
|
+
# @return [Set<Symbol>] returns a set of all of the specification differences
|
335
372
|
def changes
|
336
373
|
changes = Set.new
|
337
374
|
unless @state == 'detached' && @current_state.nil?
|
@@ -351,7 +388,6 @@ module Bosh::Director
|
|
351
388
|
##
|
352
389
|
# Instance spec that's passed to the VM during the BOSH Agent apply call.
|
353
390
|
# It's what's used for comparing the expected vs the actual state.
|
354
|
-
#
|
355
391
|
# @return [Hash<String, Object>] instance spec
|
356
392
|
def spec
|
357
393
|
spec = {
|
@@ -399,31 +435,57 @@ module Bosh::Director
|
|
399
435
|
end
|
400
436
|
end
|
401
437
|
|
402
|
-
# Allocates an
|
403
|
-
# instance to that idle VM.
|
438
|
+
# Allocates an VM in this job resource pool and binds current instance to that VM.
|
404
439
|
# @return [void]
|
405
|
-
def
|
440
|
+
def allocate_vm
|
406
441
|
resource_pool = @job.resource_pool
|
407
|
-
|
442
|
+
vm = resource_pool.allocate_vm
|
408
443
|
network = resource_pool.network
|
409
444
|
|
410
|
-
if
|
445
|
+
if vm.model
|
411
446
|
# There's already a resource pool VM that can become our instance,
|
412
447
|
# so we can try to reuse its reservation
|
413
448
|
instance_reservation = @network_reservations[network.name]
|
414
449
|
if instance_reservation
|
415
|
-
instance_reservation.take(
|
450
|
+
instance_reservation.take(vm.network_reservation)
|
416
451
|
end
|
417
452
|
else
|
418
453
|
# VM is not created yet: let's just make it reference this instance
|
419
454
|
# so later it knows what it needs to become
|
420
|
-
|
455
|
+
vm.bound_instance = self
|
456
|
+
|
421
457
|
# this also means we no longer need previous VM network reservation
|
422
458
|
# (instance has its own)
|
423
|
-
|
459
|
+
vm.release_reservation
|
424
460
|
end
|
425
461
|
|
426
|
-
@
|
462
|
+
@vm = vm
|
463
|
+
end
|
464
|
+
|
465
|
+
private
|
466
|
+
|
467
|
+
##
|
468
|
+
# Take any existing valid network reservations
|
469
|
+
# @param [Hash<String, NetworkReservation>] reservations
|
470
|
+
# @return [void]
|
471
|
+
def take_network_reservations(reservations)
|
472
|
+
@logger.debug("Copying job instance `#{self}' network reservations")
|
473
|
+
reservations.each do |name, provided_reservation|
|
474
|
+
reservation = @network_reservations[name]
|
475
|
+
reservation.take(provided_reservation) if reservation
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
def add_allocated_vm(vm_model, state)
|
480
|
+
resource_pool = @job.resource_pool
|
481
|
+
vm = resource_pool.add_allocated_vm
|
482
|
+
|
483
|
+
@logger.debug("Found VM `#{vm_model.cid}' running job instance `#{self}' in resource pool `#{resource_pool.name}'")
|
484
|
+
vm.model = vm_model
|
485
|
+
vm.bound_instance = self
|
486
|
+
vm.current_state = state
|
487
|
+
|
488
|
+
@vm = vm
|
427
489
|
end
|
428
490
|
end
|
429
491
|
end
|
@@ -25,35 +25,13 @@ module Bosh::Director
|
|
25
25
|
|
26
26
|
ThreadPool.new(:max_threads => Config.max_threads).wrap do |pool|
|
27
27
|
unbound_instances.each do |instance|
|
28
|
-
pool.process
|
28
|
+
pool.process do
|
29
|
+
@event_log.track("#{instance.job.name}/#{instance.index}") do
|
30
|
+
instance.apply_partial_vm_state
|
31
|
+
end
|
32
|
+
end
|
29
33
|
end
|
30
34
|
end
|
31
35
|
end
|
32
|
-
|
33
|
-
# @param [DeploymentPlan::Instance] instance
|
34
|
-
def bind_instance_vm(instance)
|
35
|
-
@event_log.track("#{instance.job.name}/#{instance.index}") do
|
36
|
-
idle_vm = instance.idle_vm
|
37
|
-
|
38
|
-
# Apply the assignment to the VM
|
39
|
-
agent = AgentClient.with_defaults(idle_vm.vm.agent_id)
|
40
|
-
state = idle_vm.current_state
|
41
|
-
state['job'] = instance.job.spec
|
42
|
-
state['index'] = instance.index
|
43
|
-
agent.apply(state)
|
44
|
-
|
45
|
-
# Our assumption here is that director database access
|
46
|
-
# is much less likely to fail than VM agent communication
|
47
|
-
# so we only update database after we see a successful agent apply.
|
48
|
-
# If database update fails subsequent deploy will try to
|
49
|
-
# assign a new VM to this instance which is ok.
|
50
|
-
idle_vm.vm.db.transaction do
|
51
|
-
idle_vm.vm.update(:apply_spec => state)
|
52
|
-
instance.model.update(:vm => idle_vm.vm)
|
53
|
-
end
|
54
|
-
|
55
|
-
instance.current_state = state
|
56
|
-
end
|
57
|
-
end
|
58
36
|
end
|
59
37
|
end
|
@@ -68,12 +68,13 @@ module Bosh::Director
|
|
68
68
|
|
69
69
|
attr_accessor :all_properties
|
70
70
|
|
71
|
-
# @param [Bosh::Director::DeploymentPlan::Planner]
|
72
|
-
# deployment Deployment plan
|
71
|
+
# @param [Bosh::Director::DeploymentPlan::Planner] deployment Deployment plan
|
73
72
|
# @param [Hash] job_spec Raw job spec from the deployment manifest
|
73
|
+
# @param [Bosh::Director::EventLog::Log] event_log Event log for recording deprecations
|
74
|
+
# @param [Logger] logger Log for director logging
|
74
75
|
# @return [Bosh::Director::DeploymentPlan::Job]
|
75
|
-
def self.parse(deployment, job_spec, event_log)
|
76
|
-
parser = JobSpecParser.new(deployment, event_log)
|
76
|
+
def self.parse(deployment, job_spec, event_log, logger)
|
77
|
+
parser = JobSpecParser.new(deployment, event_log, logger)
|
77
78
|
parser.parse(job_spec)
|
78
79
|
end
|
79
80
|
|
@@ -234,9 +235,7 @@ module Bosh::Director
|
|
234
235
|
unless reservation.reserved?
|
235
236
|
network = @deployment.network(net_name)
|
236
237
|
network.reserve!(reservation, "`#{name}/#{instance.index}'")
|
237
|
-
if instance.
|
238
|
-
instance.idle_vm.use_reservation(reservation)
|
239
|
-
end
|
238
|
+
instance.vm.use_reservation(reservation) if instance.vm
|
240
239
|
end
|
241
240
|
end
|
242
241
|
end
|
@@ -9,9 +9,10 @@ module Bosh::Director
|
|
9
9
|
include IpUtil
|
10
10
|
|
11
11
|
# @param [Bosh::Director::DeploymentPlan] deployment Deployment plan
|
12
|
-
def initialize(deployment, event_log)
|
12
|
+
def initialize(deployment, event_log, logger)
|
13
13
|
@deployment = deployment
|
14
14
|
@event_log = event_log
|
15
|
+
@logger = logger
|
15
16
|
end
|
16
17
|
|
17
18
|
# @param [Hash] job_spec Raw job spec from the deployment manifest
|
@@ -222,7 +223,7 @@ module Bosh::Director
|
|
222
223
|
@job.resource_pool.reserve_capacity(job_size)
|
223
224
|
end
|
224
225
|
job_size.times do |index|
|
225
|
-
@job.instances[index] = Instance.new(@job, index)
|
226
|
+
@job.instances[index] = Instance.new(@job, index, @logger)
|
226
227
|
end
|
227
228
|
end
|
228
229
|
|
@@ -32,9 +32,6 @@ module Bosh::Director
|
|
32
32
|
# @return [Array<DeploymentPlan::IdleVm] List of allocated idle VMs
|
33
33
|
attr_reader :allocated_vms
|
34
34
|
|
35
|
-
# @return [Integer] Number of active resource pool VMs
|
36
|
-
attr_reader :active_vm_count
|
37
|
-
|
38
35
|
# @return [Integer] Number of VMs reserved
|
39
36
|
attr_reader :reserved_capacity
|
40
37
|
|
@@ -68,7 +65,6 @@ module Bosh::Director
|
|
68
65
|
|
69
66
|
@idle_vms = []
|
70
67
|
@allocated_vms = []
|
71
|
-
@active_vm_count = 0
|
72
68
|
@reserved_capacity = 0
|
73
69
|
@reserved_errand_capacity = 0
|
74
70
|
end
|
@@ -83,7 +79,7 @@ module Bosh::Director
|
|
83
79
|
}
|
84
80
|
end
|
85
81
|
|
86
|
-
# Creates
|
82
|
+
# Creates idle VMs for any missing resource pool VMs and reserves
|
87
83
|
# dynamic networks for all idle VMs.
|
88
84
|
# @return [void]
|
89
85
|
def process_idle_vms
|
@@ -107,34 +103,40 @@ module Bosh::Director
|
|
107
103
|
reservation
|
108
104
|
end
|
109
105
|
|
110
|
-
# Adds a new VM to
|
106
|
+
# Adds a new VM to idle_vms
|
111
107
|
def add_idle_vm
|
112
|
-
|
108
|
+
@logger.info("ResourcePool `#{name}' - Adding idle VM (index=#{@idle_vms.size})")
|
109
|
+
idle_vm = Vm.new(self)
|
113
110
|
@idle_vms << idle_vm
|
114
111
|
idle_vm
|
115
112
|
end
|
116
113
|
|
117
114
|
def allocate_vm
|
118
|
-
if @idle_vms.empty?
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
"Resource pool `#{@name}' has no more VMs to allocate"
|
124
|
-
end
|
115
|
+
if @idle_vms.empty? && dynamically_sized?
|
116
|
+
vm = Vm.new(self)
|
117
|
+
else
|
118
|
+
vm = @idle_vms.pop
|
119
|
+
raise ResourcePoolNotEnoughCapacity, "Resource pool `#{@name}' has no more VMs to allocate" if vm.nil?
|
125
120
|
end
|
126
|
-
|
127
|
-
|
128
|
-
|
121
|
+
|
122
|
+
add_allocated_vm(vm)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Adds an existing VM to allocated_vms
|
126
|
+
def add_allocated_vm(vm=nil)
|
127
|
+
vm ||= Vm.new(self)
|
128
|
+
@logger.info("ResourcePool `#{name}' - Adding allocated VM (index=#{@allocated_vms.size})")
|
129
|
+
@allocated_vms << vm
|
130
|
+
vm
|
129
131
|
end
|
130
132
|
|
131
|
-
def deallocate_vm(
|
132
|
-
deallocated_vm = @allocated_vms.find { |
|
133
|
+
def deallocate_vm(vm_cid)
|
134
|
+
deallocated_vm = @allocated_vms.find { |vm| vm.model.cid == vm_cid }
|
133
135
|
if deallocated_vm.nil?
|
134
|
-
raise DirectorError, "Resource pool `#{@name}' does not contain an allocated VM with the cid `#{
|
136
|
+
raise DirectorError, "Resource pool `#{@name}' does not contain an allocated VM with the cid `#{vm_cid}'"
|
135
137
|
end
|
136
138
|
|
137
|
-
@logger.info("Deallocating VM: #{deallocated_vm.
|
139
|
+
@logger.info("ResourcePool `#{name}' - Deallocating VM: #{deallocated_vm.model.cid}")
|
138
140
|
@allocated_vms.delete(deallocated_vm)
|
139
141
|
|
140
142
|
add_idle_vm unless dynamically_sized? # don't refill if dynamically sized
|
@@ -142,12 +144,6 @@ module Bosh::Director
|
|
142
144
|
nil
|
143
145
|
end
|
144
146
|
|
145
|
-
# "Active" VM is a VM that is currently running a job
|
146
|
-
# @return [void]
|
147
|
-
def mark_active_vm
|
148
|
-
@active_vm_count += 1
|
149
|
-
end
|
150
|
-
|
151
147
|
# Checks if there is enough capacity to run _extra_ N VMs,
|
152
148
|
# raise error if not enough capacity
|
153
149
|
# @raise [ResourcePoolNotEnoughCapacity]
|
@@ -177,18 +173,26 @@ module Bosh::Director
|
|
177
173
|
end
|
178
174
|
end
|
179
175
|
|
180
|
-
|
181
|
-
|
176
|
+
# Returns a number of VMs that need to be deleted in order to bring
|
177
|
+
# this resource pool to the desired size
|
178
|
+
# @return [Integer]
|
179
|
+
def extra_vm_count
|
180
|
+
return 0 if dynamically_sized?
|
181
|
+
@idle_vms.size + @allocated_vms.size - @size
|
182
182
|
end
|
183
183
|
|
184
184
|
private
|
185
185
|
|
186
|
+
def dynamically_sized?
|
187
|
+
@size.nil?
|
188
|
+
end
|
189
|
+
|
186
190
|
# Returns a number of VMs that need to be created in order to bring
|
187
|
-
# this resource pool to
|
191
|
+
# this resource pool to the desired size
|
188
192
|
# @return [Integer]
|
189
193
|
def missing_vm_count
|
190
194
|
return 0 if dynamically_sized?
|
191
|
-
@size - @
|
195
|
+
@size - @allocated_vms.size - @idle_vms.size
|
192
196
|
end
|
193
197
|
end
|
194
198
|
end
|
@@ -7,15 +7,15 @@ module Bosh::Director
|
|
7
7
|
# reserved for an instance to minimize the number of CPI operations
|
8
8
|
# (network & storage) required for the VM to match the instance
|
9
9
|
# requirements.
|
10
|
-
class
|
10
|
+
class Vm
|
11
11
|
# @return [DeploymentPlan::ResourcePool] Associated resource pool
|
12
12
|
attr_reader :resource_pool
|
13
13
|
|
14
14
|
# @return [NetworkReservation] VM network reservation
|
15
15
|
attr_accessor :network_reservation
|
16
16
|
|
17
|
-
# @return [Models::Vm] Associated model
|
18
|
-
attr_accessor :
|
17
|
+
# @return [Models::Vm] Associated DB model
|
18
|
+
attr_accessor :model
|
19
19
|
|
20
20
|
# @return [Hash] Current state as provided by the BOSH Agent
|
21
21
|
attr_writer :current_state
|
@@ -38,7 +38,7 @@ module Bosh::Director
|
|
38
38
|
@current_state = nil
|
39
39
|
@bound_instance = nil
|
40
40
|
@network_reservation = nil
|
41
|
-
@
|
41
|
+
@model = nil
|
42
42
|
end
|
43
43
|
|
44
44
|
#
|
@@ -98,7 +98,7 @@ module Bosh::Director
|
|
98
98
|
def resource_pool_changed?
|
99
99
|
return true if resource_pool.spec != @current_state['resource_pool']
|
100
100
|
return true if resource_pool.deployment_plan.recreate
|
101
|
-
return true if @
|
101
|
+
return true if @model && @model.env != resource_pool.env
|
102
102
|
|
103
103
|
false
|
104
104
|
end
|
@@ -110,8 +110,9 @@ module Bosh::Director
|
|
110
110
|
resource_pool_changed? || networks_changed?
|
111
111
|
end
|
112
112
|
|
113
|
+
#TODO: rename 'clean'
|
113
114
|
def clean_vm
|
114
|
-
self.
|
115
|
+
self.model = nil
|
115
116
|
self.current_state = nil
|
116
117
|
end
|
117
118
|
end
|
@@ -52,7 +52,7 @@ module Bosh::Director
|
|
52
52
|
# @return [void]
|
53
53
|
def deallocate_vms
|
54
54
|
@logger.info('Deallocating errand VMs')
|
55
|
-
instance_vm_cids = @job.instances.map { |
|
55
|
+
instance_vm_cids = @job.instances.map { |instance| instance.model.vm.cid }
|
56
56
|
instance_vm_cids.each { |cid| @job.resource_pool.deallocate_vm(cid) }
|
57
57
|
end
|
58
58
|
end
|
@@ -42,8 +42,8 @@ module Bosh::Director
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
|
46
|
-
|
45
|
+
@instance.apply_vm_state
|
46
|
+
@job_renderer.render_job_instance(@instance)
|
47
47
|
|
48
48
|
[@vm_model, @agent_client]
|
49
49
|
end
|
@@ -183,41 +183,5 @@ module Bosh::Director
|
|
183
183
|
@cloud.detach_disk(@vm_model.cid, @instance.model.persistent_disk_cid)
|
184
184
|
end
|
185
185
|
end
|
186
|
-
|
187
|
-
class VmStateApplier
|
188
|
-
def initialize(instance, vm_model, agent_client, job_renderer, logger)
|
189
|
-
@instance = instance
|
190
|
-
@vm_model = vm_model
|
191
|
-
@agent_client = agent_client
|
192
|
-
@job_renderer = job_renderer
|
193
|
-
@logger = logger
|
194
|
-
end
|
195
|
-
|
196
|
-
def apply
|
197
|
-
@logger.info('Applying VM state')
|
198
|
-
|
199
|
-
state = {
|
200
|
-
'deployment' => @instance.job.deployment.name,
|
201
|
-
'networks' => @instance.network_settings,
|
202
|
-
'resource_pool' => @instance.job.resource_pool.spec,
|
203
|
-
'job' => @instance.job.spec,
|
204
|
-
'index' => @instance.index,
|
205
|
-
}
|
206
|
-
|
207
|
-
if @instance.disk_size > 0
|
208
|
-
state['persistent_disk'] = @instance.disk_size
|
209
|
-
end
|
210
|
-
|
211
|
-
@vm_model.update(:apply_spec => state)
|
212
|
-
|
213
|
-
@agent_client.apply(state)
|
214
|
-
|
215
|
-
# Agent will potentially return modified version of state
|
216
|
-
# with resolved dynamic networks information
|
217
|
-
@instance.current_state = @agent_client.get_state
|
218
|
-
|
219
|
-
@job_renderer.render_job_instance(@instance)
|
220
|
-
end
|
221
|
-
end
|
222
186
|
end
|
223
187
|
end
|
@@ -12,26 +12,26 @@ module Bosh::Director
|
|
12
12
|
#
|
13
13
|
# @param [ThreadPool] thread_pool Thread pool that will be used to
|
14
14
|
# parallelize the operation
|
15
|
-
# @yield [
|
15
|
+
# @yield [VirtualMachine] filter for which missing VMs to create
|
16
16
|
def create_missing_vms(thread_pool)
|
17
17
|
counter = 0
|
18
18
|
vms_to_process = []
|
19
19
|
|
20
|
-
|
21
|
-
next if
|
22
|
-
if !block_given? || yield(
|
20
|
+
each_vm do |vm|
|
21
|
+
next if vm.model
|
22
|
+
if !block_given? || yield(vm)
|
23
23
|
counter += 1
|
24
|
-
vms_to_process <<
|
24
|
+
vms_to_process << vm
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
28
|
@logger.info("Creating #{counter} missing VMs")
|
29
|
-
vms_to_process.each_with_index do |
|
29
|
+
vms_to_process.each_with_index do |vm, index|
|
30
30
|
thread_pool.process do
|
31
31
|
@event_log.track("#{@resource_pool.name}/#{index}") do
|
32
32
|
with_thread_name("create_missing_vm(#{@resource_pool.name}, #{index}/#{counter})") do
|
33
33
|
@logger.info("Creating missing VM")
|
34
|
-
create_missing_vm(
|
34
|
+
create_missing_vm(vm)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -41,60 +41,60 @@ module Bosh::Director
|
|
41
41
|
# Creates missing VMs that have bound instances
|
42
42
|
# (as opposed to missing resource pool VMs)
|
43
43
|
def create_bound_missing_vms(thread_pool)
|
44
|
-
create_missing_vms(thread_pool) { |
|
44
|
+
create_missing_vms(thread_pool) { |vm| !vm.bound_instance.nil? }
|
45
45
|
end
|
46
46
|
|
47
|
-
def create_missing_vm(
|
47
|
+
def create_missing_vm(vm)
|
48
48
|
deployment = @resource_pool.deployment_plan.model
|
49
49
|
stemcell = @resource_pool.stemcell.model
|
50
50
|
|
51
|
-
|
52
|
-
|
51
|
+
vm_model = VmCreator.new.create(deployment, stemcell, @resource_pool.cloud_properties,
|
52
|
+
vm.network_settings, nil, @resource_pool.env)
|
53
53
|
|
54
|
-
agent = AgentClient.with_defaults(
|
54
|
+
agent = AgentClient.with_defaults(vm_model.agent_id)
|
55
55
|
agent.wait_until_ready
|
56
56
|
|
57
|
-
update_state(agent,
|
57
|
+
update_state(agent, vm_model, vm)
|
58
58
|
|
59
|
-
|
60
|
-
|
59
|
+
vm.model = vm_model
|
60
|
+
vm.current_state = agent.get_state
|
61
61
|
rescue Exception => e
|
62
62
|
@logger.info("Cleaning up the created VM due to an error: #{e}")
|
63
63
|
begin
|
64
|
-
@cloud.delete_vm(
|
65
|
-
|
64
|
+
@cloud.delete_vm(vm_model.cid) if vm_model && vm_model.cid
|
65
|
+
vm_model.destroy if vm_model && vm_model.id
|
66
66
|
rescue Exception
|
67
|
-
@logger.info("Could not cleanup VM: #{
|
67
|
+
@logger.info("Could not cleanup VM: #{vm_model.cid}") if vm_model
|
68
68
|
end
|
69
69
|
raise e
|
70
70
|
end
|
71
71
|
|
72
|
-
def update_state(agent,
|
72
|
+
def update_state(agent, vm_model, vm)
|
73
73
|
state = {
|
74
74
|
"deployment" => @resource_pool.deployment_plan.name,
|
75
75
|
"resource_pool" => @resource_pool.spec,
|
76
|
-
"networks" =>
|
76
|
+
"networks" => vm.network_settings
|
77
77
|
}
|
78
78
|
|
79
|
-
|
79
|
+
vm_model.update(:apply_spec => state)
|
80
80
|
agent.apply(state)
|
81
81
|
end
|
82
82
|
|
83
83
|
# Deletes extra VMs in a resource pool
|
84
84
|
# @param thread_pool Thread pool used to parallelize delete operations
|
85
85
|
def delete_extra_vms(thread_pool)
|
86
|
-
count = extra_vm_count
|
86
|
+
count = @resource_pool.extra_vm_count
|
87
87
|
@logger.info("Deleting #{count} extra VMs")
|
88
88
|
|
89
89
|
count.times do
|
90
|
-
|
91
|
-
vm_cid =
|
90
|
+
vm = @resource_pool.idle_vms.shift
|
91
|
+
vm_cid = vm.model.cid
|
92
92
|
|
93
93
|
thread_pool.process do
|
94
94
|
@event_log.track("#{@resource_pool.name}/#{vm_cid}") do
|
95
95
|
@logger.info("Deleting extra VM: #{vm_cid}")
|
96
96
|
@cloud.delete_vm(vm_cid)
|
97
|
-
|
97
|
+
vm.model.destroy
|
98
98
|
end
|
99
99
|
end
|
100
100
|
end
|
@@ -107,9 +107,9 @@ module Bosh::Director
|
|
107
107
|
|
108
108
|
@logger.info("Deleting #{count} outdated idle VMs")
|
109
109
|
|
110
|
-
@resource_pool.idle_vms.each do |
|
111
|
-
next unless
|
112
|
-
vm_cid =
|
110
|
+
@resource_pool.idle_vms.each do |vm|
|
111
|
+
next unless vm.model && vm.changed?
|
112
|
+
vm_cid = vm.model.cid
|
113
113
|
|
114
114
|
thread_pool.process do
|
115
115
|
@event_log.track("#{@resource_pool.name}/#{vm_cid}") do
|
@@ -118,9 +118,9 @@ module Bosh::Director
|
|
118
118
|
with_thread_name("delete_outdated_vm(#{@resource_pool.name}, #{index - 1}/#{count})") do
|
119
119
|
@logger.info("Deleting outdated VM: #{vm_cid}")
|
120
120
|
@cloud.delete_vm(vm_cid)
|
121
|
-
|
122
|
-
|
123
|
-
|
121
|
+
vm_model = vm.model
|
122
|
+
vm.clean_vm
|
123
|
+
vm_model.destroy
|
124
124
|
end
|
125
125
|
end
|
126
126
|
end
|
@@ -134,8 +134,8 @@ module Bosh::Director
|
|
134
134
|
def reserve_networks
|
135
135
|
network = @resource_pool.network
|
136
136
|
|
137
|
-
|
138
|
-
unless
|
137
|
+
each_vm_with_index do |vm, index|
|
138
|
+
unless vm.network_reservation
|
139
139
|
reservation = NetworkReservation.new(
|
140
140
|
:type => NetworkReservation::DYNAMIC)
|
141
141
|
network.reserve(reservation)
|
@@ -153,7 +153,7 @@ module Bosh::Director
|
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
156
|
-
|
156
|
+
vm.network_reservation = reservation
|
157
157
|
end
|
158
158
|
end
|
159
159
|
end
|
@@ -162,39 +162,35 @@ module Bosh::Director
|
|
162
162
|
SecureRandom.uuid
|
163
163
|
end
|
164
164
|
|
165
|
-
def
|
166
|
-
@resource_pool.allocated_vms.each { |
|
167
|
-
@resource_pool.idle_vms.each { |
|
165
|
+
def each_vm
|
166
|
+
@resource_pool.allocated_vms.each { |vm| yield vm }
|
167
|
+
@resource_pool.idle_vms.each { |vm| yield vm }
|
168
168
|
end
|
169
169
|
|
170
|
-
def
|
170
|
+
def each_vm_with_index
|
171
171
|
index = 0
|
172
|
-
|
173
|
-
yield(
|
172
|
+
each_vm do |vm|
|
173
|
+
yield(vm, index)
|
174
174
|
index += 1
|
175
175
|
end
|
176
176
|
end
|
177
177
|
|
178
178
|
def extra_vm_count
|
179
|
-
|
180
|
-
@resource_pool.active_vm_count +
|
181
|
-
@resource_pool.idle_vms.size +
|
182
|
-
@resource_pool.allocated_vms.size -
|
183
|
-
@resource_pool.size
|
179
|
+
@resource_pool.extra_vm_count
|
184
180
|
end
|
185
181
|
|
186
182
|
def outdated_idle_vm_count
|
187
183
|
counter = 0
|
188
|
-
@resource_pool.idle_vms.each do |
|
189
|
-
counter += 1 if
|
184
|
+
@resource_pool.idle_vms.each do |vm|
|
185
|
+
counter += 1 if vm.model && vm.changed?
|
190
186
|
end
|
191
187
|
counter
|
192
188
|
end
|
193
189
|
|
194
190
|
def missing_vm_count
|
195
191
|
counter = 0
|
196
|
-
|
197
|
-
next if
|
192
|
+
each_vm do |vm|
|
193
|
+
next if vm.model
|
198
194
|
counter += 1
|
199
195
|
end
|
200
196
|
counter
|
@@ -202,9 +198,9 @@ module Bosh::Director
|
|
202
198
|
|
203
199
|
def bound_missing_vm_count
|
204
200
|
counter = 0
|
205
|
-
|
206
|
-
next if
|
207
|
-
next if
|
201
|
+
each_vm do |vm|
|
202
|
+
next if vm.model
|
203
|
+
next if vm.bound_instance.nil?
|
208
204
|
counter += 1
|
209
205
|
end
|
210
206
|
counter
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bosh-director
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2624.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-07-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bcrypt-ruby
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: 1.
|
37
|
+
version: 1.2624.0
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 1.
|
45
|
+
version: 1.2624.0
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: bosh-core
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,7 +50,7 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 1.
|
53
|
+
version: 1.2624.0
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -58,7 +58,7 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.
|
61
|
+
version: 1.2624.0
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: bosh-director-core
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
requirements:
|
67
67
|
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 1.
|
69
|
+
version: 1.2624.0
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -74,7 +74,7 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 1.
|
77
|
+
version: 1.2624.0
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
79
|
name: bosh_common
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,7 +82,7 @@ dependencies:
|
|
82
82
|
requirements:
|
83
83
|
- - ~>
|
84
84
|
- !ruby/object:Gem::Version
|
85
|
-
version: 1.
|
85
|
+
version: 1.2624.0
|
86
86
|
type: :runtime
|
87
87
|
prerelease: false
|
88
88
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -90,7 +90,7 @@ dependencies:
|
|
90
90
|
requirements:
|
91
91
|
- - ~>
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version: 1.
|
93
|
+
version: 1.2624.0
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
95
|
name: bosh_cpi
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,7 +98,7 @@ dependencies:
|
|
98
98
|
requirements:
|
99
99
|
- - ~>
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version: 1.
|
101
|
+
version: 1.2624.0
|
102
102
|
type: :runtime
|
103
103
|
prerelease: false
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -106,7 +106,7 @@ dependencies:
|
|
106
106
|
requirements:
|
107
107
|
- - ~>
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version: 1.
|
109
|
+
version: 1.2624.0
|
110
110
|
- !ruby/object:Gem::Dependency
|
111
111
|
name: bosh_openstack_cpi
|
112
112
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,7 +114,7 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - ~>
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 1.
|
117
|
+
version: 1.2624.0
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -122,7 +122,7 @@ dependencies:
|
|
122
122
|
requirements:
|
123
123
|
- - ~>
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version: 1.
|
125
|
+
version: 1.2624.0
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
127
|
name: bosh_aws_cpi
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -130,7 +130,7 @@ dependencies:
|
|
130
130
|
requirements:
|
131
131
|
- - ~>
|
132
132
|
- !ruby/object:Gem::Version
|
133
|
-
version: 1.
|
133
|
+
version: 1.2624.0
|
134
134
|
type: :runtime
|
135
135
|
prerelease: false
|
136
136
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -138,7 +138,7 @@ dependencies:
|
|
138
138
|
requirements:
|
139
139
|
- - ~>
|
140
140
|
- !ruby/object:Gem::Version
|
141
|
-
version: 1.
|
141
|
+
version: 1.2624.0
|
142
142
|
- !ruby/object:Gem::Dependency
|
143
143
|
name: bosh_vsphere_cpi
|
144
144
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,7 +146,7 @@ dependencies:
|
|
146
146
|
requirements:
|
147
147
|
- - ~>
|
148
148
|
- !ruby/object:Gem::Version
|
149
|
-
version: 1.
|
149
|
+
version: 1.2624.0
|
150
150
|
type: :runtime
|
151
151
|
prerelease: false
|
152
152
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -154,7 +154,7 @@ dependencies:
|
|
154
154
|
requirements:
|
155
155
|
- - ~>
|
156
156
|
- !ruby/object:Gem::Version
|
157
|
-
version: 1.
|
157
|
+
version: 1.2624.0
|
158
158
|
- !ruby/object:Gem::Dependency
|
159
159
|
name: bosh_warden_cpi
|
160
160
|
requirement: !ruby/object:Gem::Requirement
|
@@ -162,7 +162,7 @@ dependencies:
|
|
162
162
|
requirements:
|
163
163
|
- - ~>
|
164
164
|
- !ruby/object:Gem::Version
|
165
|
-
version: 1.
|
165
|
+
version: 1.2624.0
|
166
166
|
type: :runtime
|
167
167
|
prerelease: false
|
168
168
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -170,7 +170,7 @@ dependencies:
|
|
170
170
|
requirements:
|
171
171
|
- - ~>
|
172
172
|
- !ruby/object:Gem::Version
|
173
|
-
version: 1.
|
173
|
+
version: 1.2624.0
|
174
174
|
- !ruby/object:Gem::Dependency
|
175
175
|
name: bosh_vcloud_cpi
|
176
176
|
requirement: !ruby/object:Gem::Requirement
|
@@ -256,7 +256,7 @@ dependencies:
|
|
256
256
|
requirement: !ruby/object:Gem::Requirement
|
257
257
|
none: false
|
258
258
|
requirements:
|
259
|
-
- -
|
259
|
+
- - '='
|
260
260
|
- !ruby/object:Gem::Version
|
261
261
|
version: 0.5.0.beta.12
|
262
262
|
type: :runtime
|
@@ -264,7 +264,7 @@ dependencies:
|
|
264
264
|
version_requirements: !ruby/object:Gem::Requirement
|
265
265
|
none: false
|
266
266
|
requirements:
|
267
|
-
- -
|
267
|
+
- - '='
|
268
268
|
- !ruby/object:Gem::Version
|
269
269
|
version: 0.5.0.beta.12
|
270
270
|
- !ruby/object:Gem::Dependency
|
@@ -509,7 +509,7 @@ dependencies:
|
|
509
509
|
version: '0'
|
510
510
|
description: ! 'BOSH Director
|
511
511
|
|
512
|
-
|
512
|
+
03f604'
|
513
513
|
email: support@cloudfoundry.com
|
514
514
|
executables:
|
515
515
|
- bosh-director
|
@@ -621,7 +621,6 @@ files:
|
|
621
621
|
- lib/bosh/director/deployment_plan/deployment_spec_parser.rb
|
622
622
|
- lib/bosh/director/deployment_plan/dns_binder.rb
|
623
623
|
- lib/bosh/director/deployment_plan/dynamic_network.rb
|
624
|
-
- lib/bosh/director/deployment_plan/idle_vm.rb
|
625
624
|
- lib/bosh/director/deployment_plan/instance.rb
|
626
625
|
- lib/bosh/director/deployment_plan/instance_vm_binder.rb
|
627
626
|
- lib/bosh/director/deployment_plan/job.rb
|
@@ -640,6 +639,7 @@ files:
|
|
640
639
|
- lib/bosh/director/deployment_plan/update_config.rb
|
641
640
|
- lib/bosh/director/deployment_plan/updater.rb
|
642
641
|
- lib/bosh/director/deployment_plan/vip_network.rb
|
642
|
+
- lib/bosh/director/deployment_plan/vm.rb
|
643
643
|
- lib/bosh/director/dns_helper.rb
|
644
644
|
- lib/bosh/director/download_helper.rb
|
645
645
|
- lib/bosh/director/duration.rb
|
@@ -770,7 +770,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
770
770
|
version: '0'
|
771
771
|
segments:
|
772
772
|
- 0
|
773
|
-
hash: -
|
773
|
+
hash: -2871542120814616469
|
774
774
|
requirements: []
|
775
775
|
rubyforge_project:
|
776
776
|
rubygems_version: 1.8.23.2
|