bosh-director 1.3232.24.0 → 1.3262.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/db/migrations/director/20160414183654_set_teams_on_task.rb +7 -0
- data/db/migrations/director/20160427164345_add_teams.rb +48 -0
- data/db/migrations/director/20160511191928_ephemeral_blobs.rb +10 -0
- data/db/migrations/director/20160513102035_add_tracking_to_instance.rb +7 -0
- data/db/migrations/director/20160531164756_add_local_dns_blobs.rb +14 -0
- data/lib/bosh/director.rb +5 -1
- data/lib/bosh/director/api.rb +1 -0
- data/lib/bosh/director/api/api_helper.rb +2 -2
- data/lib/bosh/director/api/controllers/cleanup_controller.rb +1 -1
- data/lib/bosh/director/api/controllers/deployments_controller.rb +39 -25
- data/lib/bosh/director/api/controllers/disks_controller.rb +2 -1
- data/lib/bosh/director/api/controllers/events_controller.rb +34 -0
- data/lib/bosh/director/api/controllers/releases_controller.rb +1 -1
- data/lib/bosh/director/api/controllers/resurrection_controller.rb +1 -1
- data/lib/bosh/director/api/controllers/stemcells_controller.rb +1 -1
- data/lib/bosh/director/api/controllers/tasks_controller.rb +31 -46
- data/lib/bosh/director/api/controllers/users_controller.rb +2 -2
- data/lib/bosh/director/api/controllers/vms_controller.rb +18 -0
- data/lib/bosh/director/api/deployment_manager.rb +3 -3
- data/lib/bosh/director/api/instance_ignore_manager.rb +11 -0
- data/lib/bosh/director/api/instance_manager.rb +3 -3
- data/lib/bosh/director/api/local_identity_provider.rb +1 -1
- data/lib/bosh/director/api/problem_manager.rb +3 -3
- data/lib/bosh/director/api/release_manager.rb +9 -4
- data/lib/bosh/director/api/resurrector_manager.rb +13 -1
- data/lib/bosh/director/api/route_configuration.rb +1 -0
- data/lib/bosh/director/api/snapshot_manager.rb +2 -2
- data/lib/bosh/director/api/stemcell_manager.rb +29 -9
- data/lib/bosh/director/api/task_helper.rb +4 -3
- data/lib/bosh/director/api/uaa_identity_provider.rb +9 -3
- data/lib/bosh/director/api/user/config_user_manager.rb +1 -1
- data/lib/bosh/director/api/user/database_user_manager.rb +2 -2
- data/lib/bosh/director/cidr_range_combiner.rb +51 -0
- data/lib/bosh/director/cloudcheck_helper.rb +17 -6
- data/lib/bosh/director/config.rb +27 -1
- data/lib/bosh/director/db_backup/adapter/postgres.rb +0 -1
- data/lib/bosh/director/deployment_plan.rb +1 -1
- data/lib/bosh/director/deployment_plan/assembler.rb +8 -5
- data/lib/bosh/director/deployment_plan/deployment_repo.rb +10 -3
- data/lib/bosh/director/deployment_plan/deployment_spec_parser.rb +17 -6
- data/lib/bosh/director/deployment_plan/global_network_resolver.rb +44 -23
- data/lib/bosh/director/deployment_plan/instance.rb +2 -2
- data/lib/bosh/director/deployment_plan/{job.rb → instance_group.rb} +5 -5
- data/lib/bosh/director/deployment_plan/{job_spec_parser.rb → instance_group_spec_parser.rb} +17 -15
- data/lib/bosh/director/deployment_plan/instance_plan.rb +14 -10
- data/lib/bosh/director/deployment_plan/instance_planner.rb +22 -0
- data/lib/bosh/director/deployment_plan/job_migrator.rb +2 -2
- data/lib/bosh/director/deployment_plan/links/link_lookup.rb +3 -3
- data/lib/bosh/director/deployment_plan/links/link_path.rb +2 -2
- data/lib/bosh/director/deployment_plan/links/links_resolver.rb +1 -1
- data/lib/bosh/director/deployment_plan/manual_network.rb +1 -1
- data/lib/bosh/director/deployment_plan/manual_network_subnet.rb +1 -1
- data/lib/bosh/director/deployment_plan/placement_planner/availability_zone_picker.rb +53 -1
- data/lib/bosh/director/deployment_plan/placement_planner/static_ips_availability_zone_picker.rb +39 -1
- data/lib/bosh/director/deployment_plan/placement_planner/unplaced_existing_instances.rb +4 -0
- data/lib/bosh/director/deployment_plan/planner.rb +37 -31
- data/lib/bosh/director/deployment_plan/planner_factory.rb +26 -11
- data/lib/bosh/director/deployment_plan/runtime_manifest_parser.rb +15 -6
- data/lib/bosh/director/deployment_plan/steps/update_step.rb +1 -1
- data/lib/bosh/director/deployment_plan/template.rb +14 -1
- data/lib/bosh/director/dns/blobstore_dns_publisher.rb +35 -0
- data/lib/bosh/director/dns/dns_manager.rb +37 -74
- data/lib/bosh/director/errand/job_manager.rb +1 -1
- data/lib/bosh/director/error_ignorer.rb +1 -2
- data/lib/bosh/director/errors.rb +4 -0
- data/lib/bosh/director/event_log.rb +10 -2
- data/lib/bosh/director/instance_deleter.rb +11 -2
- data/lib/bosh/director/instance_updater.rb +21 -25
- data/lib/bosh/director/instance_updater/instance_state.rb +24 -2
- data/lib/bosh/director/instance_updater/state_applier.rb +4 -4
- data/lib/bosh/director/job_queue.rb +2 -2
- data/lib/bosh/director/job_updater.rb +3 -1
- data/lib/bosh/director/jobs/attach_disk.rb +7 -2
- data/lib/bosh/director/jobs/cleanup_artifacts.rb +15 -5
- data/lib/bosh/director/jobs/cloud_check/apply_resolutions.rb +2 -0
- data/lib/bosh/director/jobs/cloud_check/scan_and_fix.rb +5 -5
- data/lib/bosh/director/jobs/db_job.rb +10 -13
- data/lib/bosh/director/jobs/delete_deployment.rb +13 -1
- data/lib/bosh/director/jobs/delete_vm.rb +58 -0
- data/lib/bosh/director/jobs/export_release.rb +11 -4
- data/lib/bosh/director/jobs/helpers.rb +2 -0
- data/lib/bosh/director/jobs/helpers/config_parser.rb +66 -0
- data/lib/bosh/director/jobs/helpers/deep_hash_replacement.rb +38 -0
- data/lib/bosh/director/jobs/run_errand.rb +1 -1
- data/lib/bosh/director/jobs/ssh.rb +3 -2
- data/lib/bosh/director/jobs/update_deployment.rb +73 -14
- data/lib/bosh/director/jobs/update_release.rb +3 -1
- data/lib/bosh/director/jobs/update_stemcell.rb +1 -0
- data/lib/bosh/director/jobs/vm_state.rb +4 -3
- data/lib/bosh/director/legacy_deployment_helper.rb +7 -0
- data/lib/bosh/director/manifest/diff_lines.rb +4 -0
- data/lib/bosh/director/manifest/manifest.rb +18 -6
- data/lib/bosh/director/models.rb +3 -0
- data/lib/bosh/director/models/deployment.rb +17 -8
- data/lib/bosh/director/models/deployment_problem.rb +2 -2
- data/lib/bosh/director/models/ephemeral_blob.rb +11 -0
- data/lib/bosh/director/models/event.rb +2 -2
- data/lib/bosh/director/models/instance.rb +35 -5
- data/lib/bosh/director/models/local_dns_blob.rb +4 -0
- data/lib/bosh/director/models/orphan_disk.rb +2 -2
- data/lib/bosh/director/models/package.rb +2 -2
- data/lib/bosh/director/models/persistent_disk.rb +2 -2
- data/lib/bosh/director/models/task.rb +15 -0
- data/lib/bosh/director/models/team.rb +35 -0
- data/lib/bosh/director/models/template.rb +6 -2
- data/lib/bosh/director/nats_rpc.rb +3 -3
- data/lib/bosh/director/permission_authorizer.rb +14 -4
- data/lib/bosh/director/post_deployment_script_runner.rb +5 -4
- data/lib/bosh/director/problem_handlers/missing_vm.rb +7 -2
- data/lib/bosh/director/problem_handlers/unresponsive_agent.rb +11 -1
- data/lib/bosh/director/problem_resolver.rb +1 -1
- data/lib/bosh/director/problem_scanner/disk_scan_stage.rb +1 -1
- data/lib/bosh/director/problem_scanner/vm_scan_stage.rb +5 -1
- data/lib/bosh/director/version.rb +1 -1
- data/lib/bosh/director/vm_deleter.rb +8 -7
- data/lib/bosh/director/worker.rb +1 -0
- metadata +36 -34
@@ -207,11 +207,11 @@ module Bosh::Director
|
|
207
207
|
end
|
208
208
|
|
209
209
|
def current_job_spec
|
210
|
-
@model.
|
210
|
+
@model.spec_p('job')
|
211
211
|
end
|
212
212
|
|
213
213
|
def current_packages
|
214
|
-
@model.
|
214
|
+
@model.spec_p('packages')
|
215
215
|
end
|
216
216
|
|
217
217
|
def current_job_state
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require 'bosh/director/deployment_plan/
|
1
|
+
require 'bosh/director/deployment_plan/instance_group_spec_parser'
|
2
2
|
require 'bosh/template/property_helper'
|
3
3
|
|
4
4
|
module Bosh::Director
|
5
5
|
module DeploymentPlan
|
6
|
-
class
|
6
|
+
class InstanceGroup
|
7
7
|
include Bosh::Template::PropertyHelper
|
8
8
|
|
9
9
|
VALID_LIFECYCLE_PROFILES = %w(service errand)
|
@@ -85,9 +85,9 @@ module Bosh::Director
|
|
85
85
|
|
86
86
|
attr_accessor :did_change
|
87
87
|
|
88
|
-
def self.parse(plan, job_spec, event_log, logger)
|
89
|
-
parser =
|
90
|
-
parser.parse(job_spec)
|
88
|
+
def self.parse(plan, job_spec, event_log, logger, parse_options = {})
|
89
|
+
parser = InstanceGroupSpecParser.new(plan, event_log, logger)
|
90
|
+
parser.parse(job_spec, parse_options)
|
91
91
|
end
|
92
92
|
|
93
93
|
def initialize(logger)
|
@@ -2,7 +2,7 @@ require 'bosh/template/property_helper'
|
|
2
2
|
|
3
3
|
module Bosh::Director
|
4
4
|
module DeploymentPlan
|
5
|
-
class
|
5
|
+
class InstanceGroupSpecParser
|
6
6
|
include ValidationHelper
|
7
7
|
include Bosh::Template::PropertyHelper
|
8
8
|
include IpUtil
|
@@ -16,9 +16,9 @@ module Bosh::Director
|
|
16
16
|
|
17
17
|
# @param [Hash] job_spec Raw job spec from the deployment manifest
|
18
18
|
# @return [DeploymentPlan::Job] Job as build from job_spec
|
19
|
-
def parse(job_spec)
|
19
|
+
def parse(job_spec, options = {})
|
20
20
|
@job_spec = job_spec
|
21
|
-
@job =
|
21
|
+
@job = InstanceGroup.new(@logger)
|
22
22
|
|
23
23
|
parse_name
|
24
24
|
parse_lifecycle
|
@@ -35,7 +35,10 @@ module Bosh::Director
|
|
35
35
|
parse_resource_pool
|
36
36
|
check_remove_dev_tools
|
37
37
|
|
38
|
-
|
38
|
+
parse_options = {}
|
39
|
+
parse_options['canaries'] = options['canaries'] if options['canaries']
|
40
|
+
parse_options['max_in_flight'] = options['max_in_flight'] if options['max_in_flight']
|
41
|
+
parse_update_config(parse_options)
|
39
42
|
|
40
43
|
networks = JobNetworksParser.new(Network::VALID_DEFAULTS).parse(@job_spec, @job.name, @deployment.networks)
|
41
44
|
@job.networks = networks
|
@@ -63,13 +66,13 @@ module Bosh::Director
|
|
63
66
|
lifecycle = safe_property(@job_spec, "lifecycle",
|
64
67
|
:class => String,
|
65
68
|
:optional => true,
|
66
|
-
:default =>
|
69
|
+
:default => InstanceGroup::DEFAULT_LIFECYCLE_PROFILE,
|
67
70
|
)
|
68
71
|
|
69
|
-
unless
|
72
|
+
unless InstanceGroup::VALID_LIFECYCLE_PROFILES.include?(lifecycle)
|
70
73
|
raise JobInvalidLifecycle,
|
71
74
|
"Invalid lifecycle '#{lifecycle}' for '#{@job.name}', " +
|
72
|
-
"valid lifecycle profiles are: #{
|
75
|
+
"valid lifecycle profiles are: #{InstanceGroup::VALID_LIFECYCLE_PROFILES.join(', ')}"
|
73
76
|
end
|
74
77
|
|
75
78
|
@job.lifecycle = lifecycle
|
@@ -201,8 +204,7 @@ module Bosh::Director
|
|
201
204
|
@job.templates.each do |template|
|
202
205
|
if all_names.count(template.name) > 1
|
203
206
|
raise JobInvalidTemplates,
|
204
|
-
"Colocated job
|
205
|
-
"BOSH cannot currently colocate two job templates with identical names from separate releases."
|
207
|
+
"Colocated job '#{template.name}' is already added to the instance group '#{@job.name}'"
|
206
208
|
end
|
207
209
|
end
|
208
210
|
end
|
@@ -325,9 +327,9 @@ module Bosh::Director
|
|
325
327
|
@job.env = Env.new(env_hash)
|
326
328
|
end
|
327
329
|
|
328
|
-
def parse_update_config
|
330
|
+
def parse_update_config(parse_options)
|
329
331
|
update_spec = safe_property(@job_spec, "update", class: Hash, optional: true)
|
330
|
-
@job.update = UpdateConfig.new(update_spec, @deployment.update)
|
332
|
+
@job.update = UpdateConfig.new((update_spec || {}).merge(parse_options), @deployment.update)
|
331
333
|
end
|
332
334
|
|
333
335
|
def parse_desired_instances(availability_zones, networks)
|
@@ -344,17 +346,17 @@ module Bosh::Director
|
|
344
346
|
end
|
345
347
|
|
346
348
|
instance_states.each_pair do |index_or_id, state|
|
347
|
-
unless
|
349
|
+
unless InstanceGroup::VALID_JOB_STATES.include?(state)
|
348
350
|
raise JobInvalidInstanceState,
|
349
|
-
"Invalid state '#{state}' for '#{@job.name}/#{index_or_id}', valid states are: #{
|
351
|
+
"Invalid state '#{state}' for '#{@job.name}/#{index_or_id}', valid states are: #{InstanceGroup::VALID_JOB_STATES.join(", ")}"
|
350
352
|
end
|
351
353
|
|
352
354
|
@job.instance_states[index_or_id] = state
|
353
355
|
end
|
354
356
|
|
355
|
-
if @job.state && !
|
357
|
+
if @job.state && !InstanceGroup::VALID_JOB_STATES.include?(@job.state)
|
356
358
|
raise JobInvalidJobState,
|
357
|
-
"Invalid state '#{@job.state}' for '#{@job.name}', valid states are: #{
|
359
|
+
"Invalid state '#{@job.state}' for '#{@job.name}', valid states are: #{InstanceGroup::VALID_JOB_STATES.join(", ")}"
|
358
360
|
end
|
359
361
|
|
360
362
|
job_size.times.map { DesiredInstance.new(@job, @deployment) }
|
@@ -68,6 +68,10 @@ module Bosh
|
|
68
68
|
new? ? instance.model : existing_instance
|
69
69
|
end
|
70
70
|
|
71
|
+
def should_be_ignored?
|
72
|
+
!instance_model.nil? && instance_model.ignore
|
73
|
+
end
|
74
|
+
|
71
75
|
def needs_restart?
|
72
76
|
@instance.virtual_state == 'restart'
|
73
77
|
end
|
@@ -85,7 +89,7 @@ module Bosh
|
|
85
89
|
desired_network_plans = network_plans.select(&:desired?)
|
86
90
|
obsolete_network_plans = network_plans.select(&:obsolete?)
|
87
91
|
|
88
|
-
old_network_settings = new? ? {} : @existing_instance.
|
92
|
+
old_network_settings = new? ? {} : @existing_instance.spec_p('networks')
|
89
93
|
new_network_settings = network_settings.to_hash
|
90
94
|
|
91
95
|
changed = false
|
@@ -134,8 +138,8 @@ module Bosh
|
|
134
138
|
end
|
135
139
|
|
136
140
|
def configuration_changed?
|
137
|
-
changed = instance.configuration_hash != instance_model.
|
138
|
-
log_changes(__method__, instance_model.
|
141
|
+
changed = instance.configuration_hash != instance_model.spec_p('configuration_hash')
|
142
|
+
log_changes(__method__, instance_model.spec_p('configuration_hash'), instance.configuration_hash, instance) if changed
|
139
143
|
changed
|
140
144
|
end
|
141
145
|
|
@@ -231,7 +235,7 @@ module Bosh
|
|
231
235
|
# The agent job spec could be in legacy form. job_spec cannot be,
|
232
236
|
# though, because we got it from the spec function in job.rb which
|
233
237
|
# automatically makes it non-legacy.
|
234
|
-
converted_current =
|
238
|
+
converted_current = InstanceGroup.convert_from_legacy_spec(@instance.current_job_spec)
|
235
239
|
changed = job.spec != converted_current
|
236
240
|
log_changes(__method__, converted_current, job.spec, @instance) if changed
|
237
241
|
changed
|
@@ -245,7 +249,7 @@ module Bosh
|
|
245
249
|
changed
|
246
250
|
end
|
247
251
|
|
248
|
-
def
|
252
|
+
def already_detached?
|
249
253
|
return false if new?
|
250
254
|
|
251
255
|
@existing_instance.state == 'detached'
|
@@ -279,13 +283,13 @@ module Bosh
|
|
279
283
|
end
|
280
284
|
|
281
285
|
def stemcell_changed?
|
282
|
-
if @existing_instance && @instance.stemcell.name != @existing_instance.
|
283
|
-
log_changes(__method__, @existing_instance.
|
286
|
+
if @existing_instance && @instance.stemcell.name != @existing_instance.spec_p('stemcell.name')
|
287
|
+
log_changes(__method__, @existing_instance.spec_p('stemcell.name'), @instance.stemcell.name, @existing_instance)
|
284
288
|
return true
|
285
289
|
end
|
286
290
|
|
287
|
-
if @existing_instance && @instance.stemcell.version != @existing_instance.
|
288
|
-
log_changes(__method__, "version: #{@existing_instance.
|
291
|
+
if @existing_instance && @instance.stemcell.version != @existing_instance.spec_p('stemcell.version')
|
292
|
+
log_changes(__method__, "version: #{@existing_instance.spec_p('stemcell.version')}", "version: #{@instance.stemcell.version}", @existing_instance)
|
289
293
|
return true
|
290
294
|
end
|
291
295
|
|
@@ -323,7 +327,7 @@ module Bosh
|
|
323
327
|
|
324
328
|
class ResurrectionInstancePlan < InstancePlan
|
325
329
|
def network_settings_hash
|
326
|
-
@existing_instance.
|
330
|
+
@existing_instance.spec_p('networks')
|
327
331
|
end
|
328
332
|
|
329
333
|
def spec
|
@@ -8,6 +8,10 @@ module Bosh
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def plan_job_instances(job, desired_instances, existing_instance_models)
|
11
|
+
if existing_instance_models.count(&:ignore) > 0
|
12
|
+
fail_if_specifically_changing_state_of_ignored_vms(job, existing_instance_models)
|
13
|
+
end
|
14
|
+
|
11
15
|
network_planner = NetworkPlanner::Planner.new(@logger)
|
12
16
|
placement_plan = PlacementPlanner::Plan.new(@instance_plan_factory, network_planner, @logger)
|
13
17
|
vip_networks, non_vip_networks = job.networks.to_a.partition(&:vip?)
|
@@ -32,6 +36,14 @@ module Bosh
|
|
32
36
|
desired_job_names.include?(existing_instance_model.job) ||
|
33
37
|
migrating_job_names.include?(existing_instance_model.job)
|
34
38
|
end
|
39
|
+
|
40
|
+
obsolete_existing_instances.each do |instance_model|
|
41
|
+
if instance_model.ignore
|
42
|
+
raise DeploymentIgnoredInstancesDeletion, "You are trying to delete instance group '#{instance_model.job}', which " +
|
43
|
+
'contains ignored instance(s). Operation not allowed.'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
35
47
|
obsolete_existing_instances.map do |obsolete_existing_instance|
|
36
48
|
@instance_plan_factory.obsolete_instance_plan(obsolete_existing_instance)
|
37
49
|
end
|
@@ -80,6 +92,16 @@ module Bosh
|
|
80
92
|
end
|
81
93
|
end
|
82
94
|
|
95
|
+
def fail_if_specifically_changing_state_of_ignored_vms(job, existing_instance_models)
|
96
|
+
ignored_models = existing_instance_models.select(&:ignore)
|
97
|
+
ignored_models.each do |model|
|
98
|
+
unless job.instance_states["#{model.index}"].nil?
|
99
|
+
raise JobInstanceIgnored, "You are trying to change the state of the ignored instance '#{model.job}/#{model.uuid}'. " +
|
100
|
+
'This operation is not allowed. You need to unignore it first.'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
83
105
|
def log_outcome(instance_plans)
|
84
106
|
instance_plans.select(&:new?).each do |instance_plan|
|
85
107
|
instance = instance_plan.desired_instance
|
@@ -33,7 +33,7 @@ module Bosh::Director
|
|
33
33
|
migrated_from_instances = []
|
34
34
|
|
35
35
|
migrated_from_jobs.each do |migrated_from_job|
|
36
|
-
existing_job = @deployment_plan.
|
36
|
+
existing_job = @deployment_plan.instance_group(migrated_from_job.name)
|
37
37
|
if existing_job && existing_job.name != desired_job.name
|
38
38
|
raise DeploymentInvalidMigratedFromJob,
|
39
39
|
"Failed to migrate instance group '#{migrated_from_job.name}' to '#{desired_job_name}'. " +
|
@@ -41,7 +41,7 @@ module Bosh::Director
|
|
41
41
|
"Please remove instance group '#{migrated_from_job.name}'."
|
42
42
|
end
|
43
43
|
|
44
|
-
other_jobs = @deployment_plan.
|
44
|
+
other_jobs = @deployment_plan.instance_groups.reject { |job| job.name == desired_job_name }
|
45
45
|
|
46
46
|
migrate_to_multiple_jobs = other_jobs.any? do |job|
|
47
47
|
job.migrated_from.any? do |other_migrated_from_job|
|
@@ -3,7 +3,7 @@ module Bosh::Director
|
|
3
3
|
# tested in link_resolver_spec
|
4
4
|
|
5
5
|
class LinkLookupFactory
|
6
|
-
def self.create(consumed_link, link_path, deployment_plan, link_network
|
6
|
+
def self.create(consumed_link, link_path, deployment_plan, link_network)
|
7
7
|
if link_path.deployment == deployment_plan.name
|
8
8
|
PlannerLinkLookup.new(consumed_link, link_path, deployment_plan, link_network)
|
9
9
|
else
|
@@ -24,7 +24,7 @@ module Bosh::Director
|
|
24
24
|
def initialize(consumed_link, link_path, deployment_plan, link_network)
|
25
25
|
@consumed_link = consumed_link
|
26
26
|
@link_path = link_path
|
27
|
-
@jobs = deployment_plan.
|
27
|
+
@jobs = deployment_plan.instance_groups
|
28
28
|
@link_network = link_network
|
29
29
|
end
|
30
30
|
|
@@ -71,4 +71,4 @@ module Bosh::Director
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
74
|
-
end
|
74
|
+
end
|
@@ -55,7 +55,7 @@ module Bosh::Director
|
|
55
55
|
link_network = link_info["network"]
|
56
56
|
found_link_paths = []
|
57
57
|
|
58
|
-
@deployment_plan.
|
58
|
+
@deployment_plan.instance_groups.each do |provides_job|
|
59
59
|
if !link_network || provides_job.has_network?(link_network)
|
60
60
|
provides_job.templates.each do |provides_template|
|
61
61
|
if provides_template.link_infos.has_key?(provides_job.name) && provides_template.link_infos[provides_job.name].has_key?('provides')
|
@@ -106,7 +106,7 @@ module Bosh::Director
|
|
106
106
|
|
107
107
|
def get_link_path_from_deployment_plan(name, link_network)
|
108
108
|
found_link_paths = []
|
109
|
-
@deployment_plan.
|
109
|
+
@deployment_plan.instance_groups.each do |job|
|
110
110
|
if !link_network || job.has_network?(link_network)
|
111
111
|
job.templates.each do |template|
|
112
112
|
if template.link_infos.has_key?(job.name) && template.link_infos[job.name].has_key?('provides')
|
@@ -33,7 +33,7 @@ module Bosh::Director
|
|
33
33
|
job.add_resolved_link(link_name, link_path.manual_spec)
|
34
34
|
else
|
35
35
|
link_network = template.consumes_link_info(job.name, link_name)['network']
|
36
|
-
link_lookup = LinkLookupFactory.create(consumed_link, link_path, @deployment_plan, link_network
|
36
|
+
link_lookup = LinkLookupFactory.create(consumed_link, link_path, @deployment_plan, link_network)
|
37
37
|
link_spec = link_lookup.find_link_spec
|
38
38
|
|
39
39
|
unless link_spec
|
@@ -11,7 +11,7 @@ module Bosh::Director
|
|
11
11
|
def self.parse(network_spec, availability_zones, global_network_resolver, logger)
|
12
12
|
name = safe_property(network_spec, "name", :class => String)
|
13
13
|
|
14
|
-
reserved_ranges = global_network_resolver.
|
14
|
+
reserved_ranges = global_network_resolver.reserved_ranges
|
15
15
|
subnet_specs = safe_property(network_spec, 'subnets', :class => Array)
|
16
16
|
subnets = []
|
17
17
|
subnet_specs.each do |subnet_spec|
|
@@ -10,7 +10,7 @@ module Bosh::Director
|
|
10
10
|
def self.parse(network_name, subnet_spec, availability_zones, legacy_reserved_ranges)
|
11
11
|
@logger = Config.logger
|
12
12
|
|
13
|
-
@logger.debug("reserved ranges #{legacy_reserved_ranges.
|
13
|
+
@logger.debug("reserved ranges #{legacy_reserved_ranges.map {|r| r.first == r.last ? "#{r.first}" : "#{r.first}-#{r.last}"}.join(', ')}")
|
14
14
|
range_property = safe_property(subnet_spec, "range", :class => String)
|
15
15
|
range = NetAddr::CIDR.create(range_property)
|
16
16
|
|
@@ -12,12 +12,17 @@ module Bosh
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def place_and_match_in(desired_instances, existing_instance_models)
|
15
|
+
validate_networks_not_changed_for_ignore_vms(existing_instance_models)
|
16
|
+
|
15
17
|
unplaced_existing_instances = UnplacedExistingInstances.new(existing_instance_models)
|
16
18
|
desired_azs_sorted = unplaced_existing_instances.azs_sorted_by_existing_instance_count_descending(@desired_azs)
|
17
19
|
@logger.debug("Desired azs: #{desired_azs_sorted.inspect}")
|
20
|
+
validate_desired_azs_contains_all_azs_from_ignored_instances(unplaced_existing_instances, desired_instances)
|
21
|
+
|
18
22
|
placed_instances = PlacedDesiredInstances.new(desired_azs_sorted)
|
19
23
|
|
20
|
-
|
24
|
+
remaining_desired_instances_minus_ignored = place_instances_that_have_ignore_flag_as_true(desired_azs_sorted, desired_instances, placed_instances, unplaced_existing_instances)
|
25
|
+
remaining_desired_instances = place_instances_that_have_persistent_disk_in_existing_az(desired_azs_sorted, remaining_desired_instances_minus_ignored, placed_instances, unplaced_existing_instances)
|
21
26
|
balance_across_desired_azs(remaining_desired_instances, placed_instances, unplaced_existing_instances)
|
22
27
|
|
23
28
|
obsolete_instance_plans(unplaced_existing_instances.unclaimed) +
|
@@ -27,6 +32,39 @@ module Bosh
|
|
27
32
|
|
28
33
|
private
|
29
34
|
|
35
|
+
def place_instances_that_have_ignore_flag_as_true(desired_azs, desired_instances, placed_instances, unplaced_existing_instances)
|
36
|
+
return desired_instances if unplaced_existing_instances.ignored_instances.empty?
|
37
|
+
|
38
|
+
desired_instances = desired_instances.dup
|
39
|
+
return desired_instances if desired_azs.nil?
|
40
|
+
unplaced_existing_instances.ignored_instances.each do |existing_instance|
|
41
|
+
az = desired_azs.find { |az| az.name == existing_instance.availability_zone }
|
42
|
+
next if az.nil?
|
43
|
+
desired_instance = desired_instances.pop
|
44
|
+
unplaced_existing_instances.claim_instance(existing_instance)
|
45
|
+
placed_instances.record_placement(az, desired_instance, existing_instance)
|
46
|
+
end
|
47
|
+
desired_instances
|
48
|
+
end
|
49
|
+
|
50
|
+
def validate_desired_azs_contains_all_azs_from_ignored_instances(unplaced_existing_instances, desired_instances)
|
51
|
+
return if unplaced_existing_instances.ignored_instances.empty?
|
52
|
+
|
53
|
+
if unplaced_existing_instances.ignored_instances.count > desired_instances.count
|
54
|
+
@logger.info("Desired instances count, #{desired_instances.count}, is less than existing ignored instances, #{unplaced_existing_instances.ignored_instances.count}")
|
55
|
+
raise DeploymentIgnoredInstancesModification, "Instance Group '#{unplaced_existing_instances.ignored_instances.first.job}' has #{unplaced_existing_instances.ignored_instances.count} ignored instance(s)." +
|
56
|
+
" #{desired_instances.count} instance(s) of that instance group were requested. Deleting ignored instances is not allowed."
|
57
|
+
end
|
58
|
+
|
59
|
+
ignore_instances_az_names = unplaced_existing_instances.ignored_instances.map(&:availability_zone).compact.uniq
|
60
|
+
desired_az_names = @desired_azs.nil? ? [] : @desired_azs.map(&:name)
|
61
|
+
ignore_instances_az_names_attempted_to_be_deleted = ignore_instances_az_names - desired_az_names
|
62
|
+
unless ignore_instances_az_names_attempted_to_be_deleted.empty?
|
63
|
+
raise DeploymentIgnoredInstancesModification, "Instance Group '#{unplaced_existing_instances.ignored_instances.first.job}' no longer contains AZs " +
|
64
|
+
"#{ignore_instances_az_names_attempted_to_be_deleted} where ignored instance(s) exist."
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
30
68
|
def place_instances_that_have_persistent_disk_in_existing_az(desired_azs, desired_instances, placed_instances, unplaced_existing_instances)
|
31
69
|
desired_instances = desired_instances.dup
|
32
70
|
return desired_instances if desired_azs.nil?
|
@@ -83,6 +121,20 @@ module Bosh
|
|
83
121
|
instance_plan.network_plans << @network_planner.network_plan_with_dynamic_reservation(instance_plan, network)
|
84
122
|
end
|
85
123
|
end
|
124
|
+
|
125
|
+
def validate_networks_not_changed_for_ignore_vms(existing_instance_models)
|
126
|
+
existing_instance_models.each do |existing_instance_model|
|
127
|
+
next if !existing_instance_model.ignore
|
128
|
+
|
129
|
+
desired_networks_names = @networks.map(&:name).uniq.sort
|
130
|
+
existing_networks_names = existing_instance_model.ip_addresses.map(&:network_name).uniq.sort
|
131
|
+
|
132
|
+
if desired_networks_names != existing_networks_names
|
133
|
+
raise DeploymentIgnoredInstancesModification, "In instance group '#{existing_instance_model.job}', which contains ignored vms,"+
|
134
|
+
' an attempt was made to modify the networks. This operation is not allowed.'
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
86
138
|
end
|
87
139
|
end
|
88
140
|
end
|
data/lib/bosh/director/deployment_plan/placement_planner/static_ips_availability_zone_picker.rb
CHANGED
@@ -18,14 +18,48 @@ module Bosh
|
|
18
18
|
def place_and_match_in(desired_instances, existing_instance_models)
|
19
19
|
@networks_to_static_ips.validate_azs_are_declared_in_job_and_subnets(@desired_azs)
|
20
20
|
@networks_to_static_ips.validate_ips_are_in_desired_azs(@desired_azs)
|
21
|
+
validate_ignored_instances_networks(existing_instance_models)
|
22
|
+
|
21
23
|
desired_instances = desired_instances.dup
|
22
24
|
|
23
25
|
instance_plans = place_existing_instance_plans(desired_instances, existing_instance_models)
|
24
|
-
place_new_instance_plans(desired_instances, instance_plans)
|
26
|
+
instance_plans = place_new_instance_plans(desired_instances, instance_plans)
|
27
|
+
|
28
|
+
if ignored_instances_are_obsolete?(instance_plans)
|
29
|
+
raise DeploymentIgnoredInstancesModification, "In instance group '#{@job_name}', an attempt was made to remove a static ip"+
|
30
|
+
' that is used by an ignored instance. This operation is not allowed.'
|
31
|
+
end
|
32
|
+
|
33
|
+
instance_plans
|
25
34
|
end
|
26
35
|
|
27
36
|
private
|
28
37
|
|
38
|
+
def validate_ignored_instances_networks(existing_instance_models)
|
39
|
+
existing_instance_models.each do |existing_instance_model|
|
40
|
+
next if !existing_instance_model.ignore
|
41
|
+
|
42
|
+
# Validate that no networks were added or deleted
|
43
|
+
desired_networks_names = @job_networks.map(&:name).uniq.sort
|
44
|
+
existing_networks_names = existing_instance_model.ip_addresses.map(&:network_name).uniq.sort
|
45
|
+
|
46
|
+
if desired_networks_names != existing_networks_names
|
47
|
+
raise DeploymentIgnoredInstancesModification, "In instance group '#{@job_name}', which contains ignored vms,"+
|
48
|
+
' an attempt was made to modify the networks. This operation is not allowed.'
|
49
|
+
end
|
50
|
+
|
51
|
+
# Validate that no ip addresses, that were assigned to an ignored VM, have been removed
|
52
|
+
existing_instance_model.ip_addresses.each do |ip_address|
|
53
|
+
ignored_vm_network = @job_networks.select { |n| n.name == ip_address.network_name }.first
|
54
|
+
|
55
|
+
if !ignored_vm_network.static_ips.include?(ip_address.address)
|
56
|
+
raise DeploymentIgnoredInstancesModification, "In instance group '#{@job_name}', an attempt was made to remove a static ip"+
|
57
|
+
' that is used by an ignored instance. This operation is not allowed.'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
29
63
|
def place_existing_instance_plans(desired_instances, existing_instance_models)
|
30
64
|
instance_plans = []
|
31
65
|
# create existing instance plans with network plans that use specified static IPs
|
@@ -231,6 +265,10 @@ module Bosh
|
|
231
265
|
def instance_name(existing_instance_model)
|
232
266
|
"#{existing_instance_model.job}/#{existing_instance_model.index}"
|
233
267
|
end
|
268
|
+
|
269
|
+
def ignored_instances_are_obsolete?(instance_plans)
|
270
|
+
instance_plans.select{ |i| i.obsolete? && i.should_be_ignored? }.any?
|
271
|
+
end
|
234
272
|
end
|
235
273
|
end
|
236
274
|
end
|