bosh-director 1.3202.0 → 1.3213.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/db/migrations/director/20151223172000_rename_requires_json.rb +7 -0
  3. data/db/migrations/director/20160106162749_runtime_configs.rb +19 -0
  4. data/db/migrations/director/20160106163433_add_runtime_configs_to_deployments.rb +7 -0
  5. data/db/migrations/director/20160202162216_add_post_start_completed_to_instance.rb +7 -0
  6. data/db/migrations/director/20160210201838_denormalize_compiled_package_stemcell_id_to_stemcell_name_and_version.rb +57 -0
  7. data/db/migrations/director/20160219175840_add_column_teams_to_deployments.rb +8 -0
  8. data/db/migrations/director/20160224222508_add_deployment_name_to_task.rb +7 -0
  9. data/db/migrations/director/20160225182206_rename_post_start_completed.rb +8 -0
  10. data/lib/bosh/director.rb +9 -0
  11. data/lib/bosh/director/api.rb +1 -1
  12. data/lib/bosh/director/api/api_helper.rb +27 -0
  13. data/lib/bosh/director/api/controllers/base_controller.rb +28 -5
  14. data/lib/bosh/director/api/controllers/cloud_configs_controller.rb +4 -3
  15. data/lib/bosh/director/api/controllers/deployments_controller.rb +165 -81
  16. data/lib/bosh/director/api/controllers/locks_controller.rb +1 -1
  17. data/lib/bosh/director/api/controllers/packages_controller.rb +4 -35
  18. data/lib/bosh/director/api/controllers/releases_controller.rb +6 -4
  19. data/lib/bosh/director/api/controllers/runtime_configs_controller.rb +41 -0
  20. data/lib/bosh/director/api/controllers/stemcells_controller.rb +1 -1
  21. data/lib/bosh/director/api/controllers/tasks_controller.rb +72 -5
  22. data/lib/bosh/director/api/deployment_manager.rb +10 -42
  23. data/lib/bosh/director/api/extensions/scoping.rb +11 -24
  24. data/lib/bosh/director/api/instance_lookup.rb +10 -22
  25. data/lib/bosh/director/api/instance_manager.rb +27 -15
  26. data/lib/bosh/director/api/local_identity_provider.rb +0 -8
  27. data/lib/bosh/director/api/problem_manager.rb +7 -19
  28. data/lib/bosh/director/api/property_manager.rb +12 -21
  29. data/lib/bosh/director/api/resurrector_manager.rb +4 -4
  30. data/lib/bosh/director/api/route_configuration.rb +1 -0
  31. data/lib/bosh/director/api/runtime_config_manager.rb +35 -0
  32. data/lib/bosh/director/api/snapshot_manager.rb +2 -2
  33. data/lib/bosh/director/api/task_helper.rb +2 -1
  34. data/lib/bosh/director/api/task_manager.rb +2 -8
  35. data/lib/bosh/director/api/uaa_identity_provider.rb +0 -16
  36. data/lib/bosh/director/blob_util.rb +3 -2
  37. data/lib/bosh/director/cloudcheck_helper.rb +17 -3
  38. data/lib/bosh/director/compile_task.rb +53 -24
  39. data/lib/bosh/director/compile_task_generator.rb +6 -6
  40. data/lib/bosh/director/compiled_package_group.rb +4 -3
  41. data/lib/bosh/director/compiled_release.rb +6 -0
  42. data/lib/bosh/director/compiled_release/manifest.rb +30 -0
  43. data/lib/bosh/director/compiled_release_manifest.rb +3 -3
  44. data/lib/bosh/director/config.rb +11 -1
  45. data/lib/bosh/director/deployment_plan.rb +1 -0
  46. data/lib/bosh/director/deployment_plan/assembler.rb +6 -2
  47. data/lib/bosh/director/deployment_plan/cloud_manifest_parser.rb +26 -10
  48. data/lib/bosh/director/deployment_plan/compilation_config.rb +43 -7
  49. data/lib/bosh/director/deployment_plan/compilation_instance_pool.rb +10 -3
  50. data/lib/bosh/director/deployment_plan/deployment_repo.rb +4 -10
  51. data/lib/bosh/director/deployment_plan/dynamic_network.rb +1 -1
  52. data/lib/bosh/director/deployment_plan/instance.rb +36 -17
  53. data/lib/bosh/director/deployment_plan/instance_plan.rb +13 -2
  54. data/lib/bosh/director/deployment_plan/instance_spec.rb +12 -4
  55. data/lib/bosh/director/deployment_plan/job.rb +73 -39
  56. data/lib/bosh/director/deployment_plan/job_availability_zone_parser.rb +4 -4
  57. data/lib/bosh/director/deployment_plan/job_migrator.rb +7 -7
  58. data/lib/bosh/director/deployment_plan/job_network_parser.rb +6 -6
  59. data/lib/bosh/director/deployment_plan/job_spec_parser.rb +91 -33
  60. data/lib/bosh/director/deployment_plan/links/link.rb +9 -4
  61. data/lib/bosh/director/deployment_plan/links/link_lookup.rb +23 -15
  62. data/lib/bosh/director/deployment_plan/links/link_path.rb +168 -15
  63. data/lib/bosh/director/deployment_plan/links/links_resolver.rb +34 -32
  64. data/lib/bosh/director/deployment_plan/links/template_link.rb +28 -8
  65. data/lib/bosh/director/deployment_plan/manifest_validator.rb +1 -1
  66. data/lib/bosh/director/deployment_plan/network_settings.rb +27 -13
  67. data/lib/bosh/director/deployment_plan/package_validator.rb +9 -5
  68. data/lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb +4 -4
  69. data/lib/bosh/director/deployment_plan/planner.rb +31 -7
  70. data/lib/bosh/director/deployment_plan/planner_factory.rb +147 -6
  71. data/lib/bosh/director/deployment_plan/runtime_manifest_parser.rb +142 -0
  72. data/lib/bosh/director/deployment_plan/stemcell.rb +2 -2
  73. data/lib/bosh/director/deployment_plan/steps/package_compile_step.rb +3 -2
  74. data/lib/bosh/director/deployment_plan/template.rb +93 -8
  75. data/lib/bosh/director/deployment_plan/update_config.rb +10 -0
  76. data/lib/bosh/director/deployment_plan/vm_extension.rb +27 -0
  77. data/lib/bosh/director/errand/runner.rb +1 -1
  78. data/lib/bosh/director/errors.rb +11 -1
  79. data/lib/bosh/director/instance_updater.rb +46 -57
  80. data/lib/bosh/director/instance_updater/instance_state.rb +9 -0
  81. data/lib/bosh/director/instance_updater/state_applier.rb +18 -5
  82. data/lib/bosh/director/job_queue.rb +2 -2
  83. data/lib/bosh/director/job_renderer.rb +2 -2
  84. data/lib/bosh/director/job_updater.rb +7 -1
  85. data/lib/bosh/director/jobs/attach_disk.rb +2 -2
  86. data/lib/bosh/director/jobs/cloud_check/apply_resolutions.rb +6 -1
  87. data/lib/bosh/director/jobs/cloud_check/scan_and_fix.rb +14 -3
  88. data/lib/bosh/director/jobs/export_release.rb +1 -1
  89. data/lib/bosh/director/jobs/fetch_logs.rb +1 -4
  90. data/lib/bosh/director/jobs/helpers/compiled_package_deleter.rb +1 -2
  91. data/lib/bosh/director/jobs/helpers/stemcell_deleter.rb +0 -16
  92. data/lib/bosh/director/jobs/release/release_job.rb +7 -7
  93. data/lib/bosh/director/jobs/run_errand.rb +5 -5
  94. data/lib/bosh/director/jobs/ssh.rb +3 -3
  95. data/lib/bosh/director/jobs/update_deployment.rb +41 -5
  96. data/lib/bosh/director/jobs/update_release.rb +78 -82
  97. data/lib/bosh/director/jobs/update_stemcell.rb +1 -1
  98. data/lib/bosh/director/jobs/vm_state.rb +34 -21
  99. data/lib/bosh/director/key_generator.rb +54 -0
  100. data/lib/bosh/director/lock.rb +2 -2
  101. data/lib/bosh/director/log_bundles_cleaner.rb +1 -0
  102. data/lib/bosh/director/manifest/changeset.rb +39 -22
  103. data/lib/bosh/director/manifest/diff_lines.rb +1 -27
  104. data/lib/bosh/director/manifest/manifest.rb +22 -7
  105. data/lib/bosh/director/manifest/redactor.rb +44 -0
  106. data/lib/bosh/director/models.rb +1 -0
  107. data/lib/bosh/director/models/compiled_package.rb +21 -15
  108. data/lib/bosh/director/models/deployment.rb +10 -0
  109. data/lib/bosh/director/models/instance.rb +2 -1
  110. data/lib/bosh/director/models/release_version.rb +0 -16
  111. data/lib/bosh/director/models/runtime_config.rb +19 -0
  112. data/lib/bosh/director/models/template.rb +4 -4
  113. data/lib/bosh/director/package_dependencies_manager.rb +22 -0
  114. data/lib/bosh/director/password_helper.rb +18 -0
  115. data/lib/bosh/director/permission_authorizer.rb +50 -30
  116. data/lib/bosh/director/post_deployment_script_runner.rb +40 -0
  117. data/lib/bosh/director/problem_handlers/missing_disk.rb +2 -2
  118. data/lib/bosh/director/problem_resolver.rb +8 -2
  119. data/lib/bosh/director/problem_scanner/scanner.rb +1 -1
  120. data/lib/bosh/director/problem_scanner/vm_scan_stage.rb +1 -1
  121. data/lib/bosh/director/validation_helper.rb +5 -5
  122. data/lib/bosh/director/version.rb +1 -1
  123. data/lib/bosh/director/vm_creator.rb +8 -0
  124. data/lib/cloud/dummy.rb +1 -0
  125. metadata +51 -19
  126. data/lib/bosh/director/api/vm_state_manager.rb +0 -9
  127. data/lib/bosh/director/compiled_package/blob_sha_mismatch_error.rb +0 -5
  128. data/lib/bosh/director/compiled_package/compiled_package.rb +0 -30
@@ -30,6 +30,7 @@ module Bosh
30
30
  return @changes if @changes
31
31
 
32
32
  @changes = Set.new
33
+ @changes << :dirty if @instance.dirty?
33
34
  @changes << :restart if needs_restart?
34
35
  @changes << :recreate if needs_recreate?
35
36
  @changes << :cloud_properties if instance.cloud_properties_changed?
@@ -38,7 +39,7 @@ module Bosh
38
39
  @changes << :network if networks_changed?
39
40
  @changes << :packages if packages_changed?
40
41
  @changes << :persistent_disk if persistent_disk_changed?
41
- @changes << :configuration if instance.configuration_changed?
42
+ @changes << :configuration if configuration_changed?
42
43
  @changes << :job if job_changed?
43
44
  @changes << :state if state_changed?
44
45
  @changes << :dns if dns_changed?
@@ -132,6 +133,12 @@ module Bosh
132
133
  end
133
134
  end
134
135
 
136
+ def configuration_changed?
137
+ changed = instance.configuration_hash != instance_model.spec['configuration_hash']
138
+ log_changes(__method__, instance_model.spec['configuration_hash'], instance.configuration_hash, instance) if changed
139
+ changed
140
+ end
141
+
135
142
  def mark_desired_network_plans_as_existing
136
143
  network_plans.select(&:desired?).each { |network_plan| network_plan.existing = true }
137
144
  end
@@ -166,7 +173,7 @@ module Bosh
166
173
  @instance.model.deployment.name,
167
174
  @desired_instance.job.default_network,
168
175
  desired_reservations,
169
- @instance.current_state,
176
+ @instance.current_networks,
170
177
  @instance.availability_zone,
171
178
  @instance.index,
172
179
  @instance.uuid,
@@ -178,6 +185,10 @@ module Bosh
178
185
  network_settings.to_hash
179
186
  end
180
187
 
188
+ def network_address(network_name)
189
+ network_settings.network_address(network_name)
190
+ end
191
+
181
192
  def network_addresses
182
193
  network_settings.network_addresses
183
194
  end
@@ -21,6 +21,7 @@ module Bosh::Director
21
21
  'job' => job.spec,
22
22
  'index' => instance.index,
23
23
  'bootstrap' => instance.bootstrap?,
24
+ 'name' => instance.job_name,
24
25
  'id' => instance.uuid,
25
26
  'az' => instance.availability_zone_name,
26
27
  'networks' => instance_plan.network_settings_hash,
@@ -31,6 +32,8 @@ module Bosh::Director
31
32
  'properties' => job.properties,
32
33
  'dns_domain_name' => dns_manager.dns_domain_name,
33
34
  'links' => job.link_spec,
35
+ 'address' => instance_plan.network_settings.network_address,
36
+ 'update' => job.update_spec
34
37
  }
35
38
 
36
39
  if job.persistent_disk_type
@@ -104,21 +107,24 @@ module Bosh::Director
104
107
  'job',
105
108
  'index',
106
109
  'bootstrap',
110
+ 'name',
107
111
  'id',
108
112
  'az',
109
113
  'networks',
110
- 'packages',
111
114
  'properties',
112
115
  'dns_domain_name',
113
116
  'links',
114
- 'persistent_disk'
117
+ 'persistent_disk',
118
+ 'address'
115
119
  ]
116
120
  template_hash = @full_spec.select {|k,v| keys.include?(k) }
117
121
 
118
122
  networks_hash = template_hash['networks']
119
123
  networks_hash_with_dns = networks_hash.each_pair do |network_name, network_settings|
120
- settings_with_dns = network_settings.merge({'dns_record_name' => @dns_manager.dns_record_name(@full_spec['index'], @full_spec['job']['name'], network_name, @full_spec['deployment'])})
121
- networks_hash[network_name] = settings_with_dns
124
+ if @full_spec['job'] != nil
125
+ settings_with_dns = network_settings.merge({'dns_record_name' => @dns_manager.dns_record_name(@full_spec['index'], @full_spec['job']['name'], network_name, @full_spec['deployment'])})
126
+ networks_hash[network_name] = settings_with_dns
127
+ end
122
128
  end
123
129
 
124
130
  template_hash.merge({
@@ -138,7 +144,9 @@ module Bosh::Director
138
144
  'deployment',
139
145
  'job',
140
146
  'index',
147
+ 'name',
141
148
  'id',
149
+ 'az',
142
150
  'networks',
143
151
  'packages',
144
152
  'dns_domain_name',
@@ -37,6 +37,9 @@ module Bosh::Director
37
37
  # @return [DeploymentPlan::VmType]
38
38
  attr_accessor :vm_type
39
39
 
40
+ # @return [DeploymentPlan::VmExtension]
41
+ attr_accessor :vm_extensions
42
+
40
43
  # @return [DeploymentPlan::Env]
41
44
  attr_accessor :env
42
45
 
@@ -80,6 +83,8 @@ module Bosh::Director
80
83
 
81
84
  attr_reader :link_paths
82
85
 
86
+ attr_accessor :did_change
87
+
83
88
  def self.parse(plan, job_spec, event_log, logger)
84
89
  parser = JobSpecParser.new(plan, event_log, logger)
85
90
  parser.parse(job_spec)
@@ -106,6 +111,8 @@ module Bosh::Director
106
111
  @availability_zones = []
107
112
 
108
113
  @instance_plans = []
114
+
115
+ @did_change = false
109
116
  end
110
117
 
111
118
  def self.is_legacy_spec?(job_spec)
@@ -136,7 +143,12 @@ module Bosh::Director
136
143
  "sha1" => job_spec["sha1"],
137
144
  "blobstore_id" => job_spec["blobstore_id"]
138
145
  }
139
- job_spec["templates"] = [template]
146
+
147
+ # Supporting 'template_scoped_properties' for legacy spec is going to be messy.
148
+ # So we will support this feature if a user want to use legacy spec. If they
149
+ # want to use properties per template, let them use the regular way of defining
150
+ # templates, i.e. by using the 'templates' key
151
+ job_spec['templates'] = [template]
140
152
  end
141
153
 
142
154
 
@@ -160,35 +172,46 @@ module Bosh::Director
160
172
  # populate agent state.
161
173
  # @return [Hash] Hash representation
162
174
  def spec
163
- first_template = @templates[0]
164
- result = {
165
- "name" => @name,
166
- "templates" => [],
167
- # --- Legacy ---
168
- "template" => first_template.name,
169
- "version" => first_template.version,
170
- "sha1" => first_template.sha1,
171
- "blobstore_id" => first_template.blobstore_id
172
- }
173
- if first_template.logs
174
- result["logs"] = first_template.logs
175
- end
176
- # --- /Legacy ---
177
-
178
- @templates.each do |template|
179
- template_entry = {
180
- "name" => template.name,
181
- "version" => template.version,
182
- "sha1" => template.sha1,
183
- "blobstore_id" => template.blobstore_id
175
+ if @templates.size >= 1
176
+ first_template = @templates[0]
177
+ result = {
178
+ "name" => @name,
179
+ "templates" => [],
180
+ # --- Legacy ---
181
+ "template" => first_template.name,
182
+ "version" => first_template.version,
183
+ "sha1" => first_template.sha1,
184
+ "blobstore_id" => first_template.blobstore_id
184
185
  }
185
- if template.logs
186
- template_entry["logs"] = template.logs
186
+
187
+ result['template_scoped_properties'] = first_template.template_scoped_properties[@name] unless first_template.template_scoped_properties[@name].nil?
188
+
189
+ if first_template.logs
190
+ result["logs"] = first_template.logs
191
+ end
192
+ # --- /Legacy ---
193
+
194
+ @templates.each do |template|
195
+ template_entry = {
196
+ "name" => template.name,
197
+ "version" => template.version,
198
+ "sha1" => template.sha1,
199
+ "blobstore_id" => template.blobstore_id
200
+ }
201
+
202
+ template_entry['template_scoped_properties'] = template.template_scoped_properties[@name] unless template.template_scoped_properties[@name].nil?
203
+
204
+ if template.logs
205
+ template_entry["logs"] = template.logs
206
+ end
207
+ result["templates"] << template_entry
187
208
  end
188
- result["templates"] << template_entry
209
+ result
189
210
  end
211
+ end
190
212
 
191
- result
213
+ def update_spec
214
+ update.to_hash
192
215
  end
193
216
 
194
217
  # Returns package specs for all packages in the job indexed by package
@@ -248,9 +271,9 @@ module Bosh::Director
248
271
  offending_template2 = templates.find { |t| t.release == release2 }
249
272
 
250
273
  raise JobPackageCollision,
251
- "Package name collision detected in job `#{@name}': "\
252
- "template `#{release1.name}/#{offending_template1.name}' depends on package `#{release1.name}/#{package_name}', "\
253
- "template `#{release2.name}/#{offending_template2.name}' depends on `#{release2.name}/#{package_name}'. " +
274
+ "Package name collision detected in instance group '#{@name}': "\
275
+ "job '#{release1.name}/#{offending_template1.name}' depends on package '#{release1.name}/#{package_name}', "\
276
+ "job '#{release2.name}/#{offending_template2.name}' depends on '#{release2.name}/#{package_name}'. " +
254
277
  'BOSH cannot currently collocate two packages with identical names from separate releases.'
255
278
  end
256
279
  end
@@ -273,11 +296,17 @@ module Bosh::Director
273
296
  end
274
297
  end
275
298
 
276
- def starts_on_deploy?
299
+ def has_network?(network_name)
300
+ networks.any? do |network|
301
+ network.name == network_name
302
+ end
303
+ end
304
+
305
+ def is_service?
277
306
  @lifecycle == 'service'
278
307
  end
279
308
 
280
- def can_run_as_errand?
309
+ def is_errand?
281
310
  @lifecycle == 'errand'
282
311
  end
283
312
 
@@ -318,10 +347,6 @@ module Bosh::Director
318
347
  # @param [Hash] collection All properties collection
319
348
  # @return [Hash] Properties required by templates included in this job
320
349
  def filter_properties(collection)
321
- if @templates.empty?
322
- raise DirectorError, "Can't extract job properties before parsing job templates"
323
- end
324
-
325
350
  if @templates.none? { |template| template.properties }
326
351
  return collection
327
352
  end
@@ -331,17 +356,26 @@ module Bosh::Director
331
356
  end
332
357
 
333
358
  raise JobIncompatibleSpecs,
334
- "Job `#{name}' has specs with conflicting property definition styles between" +
359
+ "Instance group '#{name}' has specs with conflicting property definition styles between" +
335
360
  " its job spec templates. This may occur if colocating jobs, one of which has a spec file including" +
336
- " `properties' and one which doesn't."
361
+ " 'properties' and one which doesn't."
337
362
  end
338
363
 
339
364
  def extract_template_properties(collection)
340
365
  result = {}
341
366
 
342
367
  @templates.each do |template|
343
- template.properties.each_pair do |name, definition|
344
- copy_property(result, collection, name, definition["default"])
368
+ # If a template has properties that were defined in the deployment manifest
369
+ # for that template only, then we need to bind only these properties, and not
370
+ # make them available to other templates in the same deployment job. That can
371
+ # be done by checking @template_scoped_properties variable of each
372
+ # template
373
+ if template.has_template_scoped_properties(@name)
374
+ template.bind_template_scoped_properties(@name)
375
+ else
376
+ template.properties.each_pair do |name, definition|
377
+ copy_property(result, collection, name, definition["default"])
378
+ end
345
379
  end
346
380
  end
347
381
 
@@ -16,19 +16,19 @@ module Bosh::Director
16
16
  networks.each do |network|
17
17
  unless network.has_azs?(az_names)
18
18
  raise JobNetworkMissingRequiredAvailabilityZone,
19
- "Job '#{job.name}' must specify availability zone that matches availability zones of network '#{network.name}'"
19
+ "Instance group '#{job.name}' must specify availability zone that matches availability zones of network '#{network.name}'"
20
20
  end
21
21
  end
22
22
  end
23
23
 
24
24
  def check_validity_of(az_names, job_name)
25
25
  if az_names.empty?
26
- raise JobMissingAvailabilityZones, "Job '#{job_name}' has empty availability zones"
26
+ raise JobMissingAvailabilityZones, "Instance group '#{job_name}' has empty availability zones"
27
27
  end
28
28
 
29
29
  az_names.each do |name|
30
30
  unless name.is_a?(String)
31
- raise JobInvalidAvailabilityZone, "Job '#{job_name}' has invalid availability zone '#{name}', string expected"
31
+ raise JobInvalidAvailabilityZone, "Instance group '#{job_name}' has invalid availability zone '#{name}', string expected"
32
32
  end
33
33
  end
34
34
  end
@@ -37,7 +37,7 @@ module Bosh::Director
37
37
  az_names.map do |name|
38
38
  az = deployment.availability_zone(name)
39
39
  if az.nil?
40
- raise JobUnknownAvailabilityZone, "Job '#{job_name}' references unknown availability zone '#{name}'"
40
+ raise JobUnknownAvailabilityZone, "Instance group '#{job_name}' references unknown availability zone '#{name}'"
41
41
  end
42
42
  az
43
43
  end
@@ -36,9 +36,9 @@ module Bosh::Director
36
36
  existing_job = @deployment_plan.job(migrated_from_job.name)
37
37
  if existing_job && existing_job.name != desired_job.name
38
38
  raise DeploymentInvalidMigratedFromJob,
39
- "Failed to migrate job '#{migrated_from_job.name}' to '#{desired_job_name}'. " +
40
- 'A deployment can not migrate a job and also specify it. ' +
41
- "Please remove job '#{migrated_from_job.name}'."
39
+ "Failed to migrate instance group '#{migrated_from_job.name}' to '#{desired_job_name}'. " +
40
+ 'A deployment can not migrate an instance group and also specify it. ' +
41
+ "Please remove instance group '#{migrated_from_job.name}'."
42
42
  end
43
43
 
44
44
  other_jobs = @deployment_plan.jobs.reject { |job| job.name == desired_job_name }
@@ -51,7 +51,7 @@ module Bosh::Director
51
51
 
52
52
  if migrate_to_multiple_jobs
53
53
  raise DeploymentInvalidMigratedFromJob,
54
- "Failed to migrate job '#{migrated_from_job.name}' to '#{desired_job_name}'. A job may be migrated to only one job."
54
+ "Failed to migrate instance group '#{migrated_from_job.name}' to '#{desired_job_name}'. An instance group may be migrated to only one instance group."
55
55
  end
56
56
 
57
57
  migrated_from_job_instances = []
@@ -62,13 +62,13 @@ module Bosh::Director
62
62
  migrated_from_job.availability_zone.nil? &&
63
63
  desired_job.availability_zones.to_a.compact.any?
64
64
  raise DeploymentInvalidMigratedFromJob,
65
- "Failed to migrate job '#{migrated_from_job.name}' to '#{desired_job_name}', availability zone of '#{migrated_from_job.name}' is not specified"
65
+ "Failed to migrate instance group '#{migrated_from_job.name}' to '#{desired_job_name}', availability zone of '#{migrated_from_job.name}' is not specified"
66
66
  end
67
67
 
68
68
  if !migrated_from_job.availability_zone.nil? && !instance.availability_zone.nil?
69
69
  if migrated_from_job.availability_zone != instance.availability_zone
70
70
  raise DeploymentInvalidMigratedFromJob,
71
- "Failed to migrate job '#{migrated_from_job.name}' to '#{desired_job_name}', '#{migrated_from_job.name}' belongs to availability zone '#{instance.availability_zone}' and manifest specifies '#{migrated_from_job.availability_zone}'"
71
+ "Failed to migrate instance group '#{migrated_from_job.name}' to '#{desired_job_name}', '#{migrated_from_job.name}' belongs to availability zone '#{instance.availability_zone}' and manifest specifies '#{migrated_from_job.availability_zone}'"
72
72
  end
73
73
  end
74
74
 
@@ -78,7 +78,7 @@ module Bosh::Director
78
78
 
79
79
  migrated_from_job_instances << instance
80
80
 
81
- @logger.debug("Migrating job '#{migrated_from_job.name}/#{instance.uuid} (#{instance.index})' to '#{desired_job.name}/#{instance.uuid} (#{instance.index})'")
81
+ @logger.debug("Migrating instance group '#{migrated_from_job.name}/#{instance.uuid} (#{instance.index})' to '#{desired_job.name}/#{instance.uuid} (#{instance.index})'")
82
82
  end
83
83
  end
84
84
 
@@ -26,7 +26,7 @@ module Bosh::Director
26
26
  def parse_networks(job_spec, job_name, manifest_networks)
27
27
  network_specs = safe_property(job_spec, "networks", :class => Array)
28
28
  if network_specs.empty?
29
- raise JobMissingNetwork, "Job `#{job_name}' must specify at least one network"
29
+ raise JobMissingNetwork, "Instance group '#{job_name}' must specify at least one network"
30
30
  end
31
31
  network_specs.map do |network_spec|
32
32
  network_name = safe_property(network_spec, "name", :class => String)
@@ -43,7 +43,7 @@ module Bosh::Director
43
43
  def look_up_deployment_network(manifest_networks, job_name, network_name)
44
44
  deployment_network = manifest_networks.find{ |network| network.name == network_name }
45
45
  if deployment_network.nil?
46
- raise JobUnknownNetwork, "Job '#{job_name}' references an unknown network '#{network_name}'"
46
+ raise JobUnknownNetwork, "Instance group '#{job_name}' references an unknown network '#{network_name}'"
47
47
  end
48
48
  deployment_network
49
49
  end
@@ -54,7 +54,7 @@ module Bosh::Director
54
54
  static_ips = []
55
55
  each_ip(static_ips_raw) do |ip|
56
56
  if static_ips.include?(ip)
57
- raise JobInvalidStaticIPs, "Job '#{job_name}' specifies static IP '#{format_ip(ip)}' more than once"
57
+ raise JobInvalidStaticIPs, "Instance group '#{job_name}' specifies static IP '#{format_ip(ip)}' more than once"
58
58
  end
59
59
 
60
60
  static_ips.push(ip)
@@ -67,7 +67,7 @@ module Bosh::Director
67
67
  network.properties_for_which_the_network_is_the_default.each do |property|
68
68
  unless @properties_that_require_defaults.include?(property)
69
69
  raise JobNetworkInvalidDefault,
70
- "Job `#{job_name}' specified an invalid default network property `#{property}', " +
70
+ "Instance group '#{job_name}' specified an invalid default network property '#{property}', " +
71
71
  "valid properties are: " + @properties_that_require_defaults.join(", ")
72
72
  end
73
73
  end
@@ -89,7 +89,7 @@ module Bosh::Director
89
89
  }
90
90
  unless missing_default_properties.empty?
91
91
  raise JobNetworkMissingDefault,
92
- "Job `#{job_name}' must specify which network is default for " +
92
+ "Instance group '#{job_name}' must specify which network is default for " +
93
93
  missing_default_properties.sort.join(", ") + ", since it has more than one network configured"
94
94
  end
95
95
  end
@@ -104,7 +104,7 @@ module Bosh::Director
104
104
  "'#{property}' has default networks: #{quoted_network_names}."
105
105
  end
106
106
  raise JobNetworkMultipleDefaults,
107
- "Job `#{job_name}' specified more than one network to contain default. #{message_for_each_property.join(' ')}"
107
+ "Instance group '#{job_name}' specified more than one network to contain default. #{message_for_each_property.join(' ')}"
108
108
  end
109
109
  end
110
110
 
@@ -33,6 +33,8 @@ module Bosh::Director
33
33
  parse_disk
34
34
  parse_properties
35
35
  parse_resource_pool
36
+ check_remove_dev_tools
37
+
36
38
  parse_update_config
37
39
 
38
40
  networks = JobNetworksParser.new(Network::VALID_DEFAULTS).parse(@job_spec, @job.name, @deployment.networks)
@@ -66,7 +68,7 @@ module Bosh::Director
66
68
 
67
69
  unless Job::VALID_LIFECYCLE_PROFILES.include?(lifecycle)
68
70
  raise JobInvalidLifecycle,
69
- "Invalid lifecycle `#{lifecycle}' for `#{@job.name}', " +
71
+ "Invalid lifecycle '#{lifecycle}' for '#{@job.name}', " +
70
72
  "valid lifecycle profiles are: #{Job::VALID_LIFECYCLE_PROFILES.join(', ')}"
71
73
  end
72
74
 
@@ -85,7 +87,7 @@ module Bosh::Director
85
87
 
86
88
  if @job.release.nil?
87
89
  raise JobUnknownRelease,
88
- "Job `#{@job.name}' references an unknown release `#{release_name}'"
90
+ "Instance group '#{@job.name}' references an unknown release '#{release_name}'"
89
91
  end
90
92
  end
91
93
  end
@@ -95,8 +97,8 @@ module Bosh::Director
95
97
  if template_names
96
98
  if template_names.is_a?(Array)
97
99
  @event_log.warn_deprecated(
98
- "Please use `templates' when specifying multiple templates for a job. " +
99
- "`template' for multiple templates will soon be unsupported."
100
+ "Please use 'templates' when specifying multiple templates for a job. " +
101
+ "'template' for multiple templates will soon be unsupported."
100
102
  )
101
103
  end
102
104
 
@@ -105,7 +107,7 @@ module Bosh::Director
105
107
  end
106
108
 
107
109
  unless @job.release
108
- raise JobMissingRelease, "Cannot tell what release job `#{@job.name}' is supposed to use, please explicitly specify one"
110
+ raise JobMissingRelease, "Cannot tell what release job '#{@job.name}' is supposed to use, please explicitly specify one"
109
111
  end
110
112
 
111
113
  Array(template_names).each do |template_name|
@@ -123,6 +125,12 @@ module Bosh::Director
123
125
  end
124
126
 
125
127
  if templates
128
+ release_manager = Api::ReleaseManager.new
129
+
130
+ # Key: release name.
131
+ # Value: list of templates models of release version.
132
+ release_versions_templates_models_hash = {}
133
+
126
134
  templates.each do |template_spec|
127
135
  template_name = safe_property(template_spec, 'name', class: String)
128
136
  release_name = safe_property(template_spec, 'release', class: String, optional: true)
@@ -131,24 +139,59 @@ module Bosh::Director
131
139
  release = @deployment.release(release_name)
132
140
  unless release
133
141
  raise JobUnknownRelease,
134
- "Template `#{template_name}' (job `#{@job.name}') references an unknown release `#{release_name}'"
142
+ "Job '#{template_name}' (instance group '#{@job.name}') references an unknown release '#{release_name}'"
135
143
  end
136
144
  else
137
145
  release = @job.release
138
146
  unless release
139
- raise JobMissingRelease, "Cannot tell what release template `#{template_name}' (job `#{@job.name}') is supposed to use, please explicitly specify one"
147
+ raise JobMissingRelease, "Cannot tell what release template '#{template_name}' (instance group '#{@job.name}') is supposed to use, please explicitly specify one"
140
148
  end
141
149
  end
142
150
 
143
- @job.templates << release.get_or_create_template(template_name)
151
+ if !release_versions_templates_models_hash.has_key?(release_name)
152
+ release_model = release_manager.find_by_name(release.name)
153
+ current_release_version = release_manager.find_version(release_model, release.version)
154
+ release_versions_templates_models_hash[release_name] = current_release_version.templates
155
+ end
156
+
157
+ templates_models_list = release_versions_templates_models_hash[release_name]
158
+ current_template_model = templates_models_list.find {|target| target.name == template_name }
159
+
160
+ template = release.get_or_create_template(template_name)
144
161
 
145
- links = safe_property(template_spec, 'links', class: Hash, optional: true)
146
- @logger.debug("Parsing template links: #{links.inspect}")
162
+ if current_template_model == nil
163
+ raise "Job '#{template_name}' not found in Template table"
164
+ end
165
+
166
+ if current_template_model.consumes != nil
167
+ current_template_model.consumes.each do |consumes|
168
+ template.add_link_info(@job.name,'consumes', consumes["name"], consumes)
169
+ end
170
+ end
171
+ if current_template_model.provides != nil
172
+ current_template_model.provides.each do |provides|
173
+ template.add_link_info(@job.name, 'provides', provides["name"], provides)
174
+ end
175
+ end
147
176
 
148
- links.to_a.each do |name, path|
149
- link_path = LinkPath.parse(@deployment.name, path, @logger)
150
- @job.add_link_path(template_name, name, link_path)
177
+ provides_links = safe_property(template_spec, 'provides', class: Hash, optional: true)
178
+ provides_links.to_a.each do |link_name, source|
179
+ template.add_link_info(@job.name, "provides", link_name, source)
151
180
  end
181
+
182
+ consumes_links = safe_property(template_spec, 'consumes', class: Hash, optional: true)
183
+ consumes_links.to_a.each do |link_name, source|
184
+ template.add_link_info(@job.name, 'consumes', link_name, source)
185
+ end
186
+
187
+ if template_spec.has_key?("properties")
188
+ template.add_template_scoped_properties(
189
+ safe_property(template_spec, 'properties', class: Hash, optional: true, default: nil),
190
+ @job.name
191
+ )
192
+ end
193
+
194
+ @job.templates << template
152
195
  end
153
196
  end
154
197
  end
@@ -158,7 +201,7 @@ module Bosh::Director
158
201
  @job.templates.each do |template|
159
202
  if all_names.count(template.name) > 1
160
203
  raise JobInvalidTemplates,
161
- "Colocated job template `#{template.name}' has the same name in multiple releases. " +
204
+ "Colocated job template '#{template.name}' has the same name in multiple releases. " +
162
205
  "BOSH cannot currently colocate two job templates with identical names from separate releases."
163
206
  end
164
207
  end
@@ -171,7 +214,7 @@ module Bosh::Director
171
214
 
172
215
  if disk_type_name && disk_pool_name
173
216
  raise JobInvalidPersistentDisk,
174
- "Job `#{@job.name}' specifies both 'disk_types' and 'disk_pools', only one key is allowed. " +
217
+ "Instance group '#{@job.name}' specifies both 'disk_types' and 'disk_pools', only one key is allowed. " +
175
218
  "'disk_pools' key will be DEPRECATED in the future."
176
219
  end
177
220
 
@@ -185,14 +228,14 @@ module Bosh::Director
185
228
 
186
229
  if disk_size && disk_name
187
230
  raise JobInvalidPersistentDisk,
188
- "Job `#{@job.name}' references both a persistent disk size `#{disk_size}' " +
189
- "and a persistent disk #{disk_source} `#{disk_name}'"
231
+ "Instance group '#{@job.name}' references both a persistent disk size '#{disk_size}' " +
232
+ "and a persistent disk #{disk_source} '#{disk_name}'"
190
233
  end
191
234
 
192
235
  if disk_size
193
236
  if disk_size < 0
194
237
  raise JobInvalidPersistentDisk,
195
- "Job `#{@job.name}' references an invalid persistent disk size `#{disk_size}'"
238
+ "Instance group '#{@job.name}' references an invalid persistent disk size '#{disk_size}'"
196
239
  else
197
240
  @job.persistent_disk = disk_size
198
241
  end
@@ -202,7 +245,7 @@ module Bosh::Director
202
245
  disk_type = @deployment.disk_type(disk_name)
203
246
  if disk_type.nil?
204
247
  raise JobUnknownDiskType,
205
- "Job `#{@job.name}' references an unknown disk #{disk_source} `#{disk_name}'"
248
+ "Instance group '#{@job.name}' references an unknown disk #{disk_source} '#{disk_name}'"
206
249
  else
207
250
  @job.persistent_disk_type = disk_type
208
251
  end
@@ -222,7 +265,7 @@ module Bosh::Director
222
265
 
223
266
  if resolved.nil?
224
267
  raise JobInvalidPropertyMapping,
225
- "Cannot satisfy property mapping `#{to}: #{from}', as `#{from}' is not in deployment properties"
268
+ "Cannot satisfy property mapping '#{to}: #{from}', as '#{from}' is not in deployment properties"
226
269
  end
227
270
 
228
271
  @job.all_properties[to] = resolved
@@ -237,7 +280,7 @@ module Bosh::Director
237
280
  resource_pool = @deployment.resource_pool(resource_pool_name)
238
281
  if resource_pool.nil?
239
282
  raise JobUnknownResourcePool,
240
- "Job `#{@job.name}' references an unknown resource pool `#{resource_pool_name}'"
283
+ "Instance group '#{@job.name}' references an unknown resource pool '#{resource_pool_name}'"
241
284
  end
242
285
 
243
286
  vm_type = VmType.new({
@@ -245,11 +288,13 @@ module Bosh::Director
245
288
  'cloud_properties' => resource_pool.cloud_properties
246
289
  })
247
290
 
291
+ vm_extensions = []
292
+
248
293
  stemcell = resource_pool.stemcell
249
294
 
250
295
  if !env_hash.empty? && !resource_pool.env.empty?
251
296
  raise JobAmbiguousEnv,
252
- "Job '#{@job.name}' and resource pool: '#{resource_pool_name}' both declare env properties"
297
+ "Instance group '#{@job.name}' and resource pool: '#{resource_pool_name}' both declare env properties"
253
298
  end
254
299
 
255
300
  if env_hash.empty?
@@ -260,18 +305,22 @@ module Bosh::Director
260
305
  vm_type = @deployment.vm_type(vm_type_name)
261
306
  if vm_type.nil?
262
307
  raise JobUnknownVmType,
263
- "Job `#{@job.name}' references an unknown vm type `#{vm_type_name}'"
308
+ "Instance group '#{@job.name}' references an unknown vm type '#{vm_type_name}'"
264
309
  end
265
310
 
311
+ vm_extension_names = Array(safe_property(@job_spec, 'vm_extensions', class: Array, optional: true))
312
+ vm_extensions = Array(vm_extension_names).map {|vm_extension_name| @deployment.vm_extension(vm_extension_name)}
313
+
266
314
  stemcell_name = safe_property(@job_spec, 'stemcell', class: String)
267
315
  stemcell = @deployment.stemcell(stemcell_name)
268
316
  if stemcell.nil?
269
317
  raise JobUnknownStemcell,
270
- "Job `#{@job.name}' references an unknown stemcell `#{stemcell_name}'"
318
+ "Instance group '#{@job.name}' references an unknown stemcell '#{stemcell_name}'"
271
319
  end
272
320
  end
273
321
 
274
322
  @job.vm_type = vm_type
323
+ @job.vm_extensions = vm_extensions
275
324
  @job.stemcell = stemcell
276
325
  @job.env = Env.new(env_hash)
277
326
  end
@@ -290,14 +339,14 @@ module Bosh::Director
290
339
  static_ips = network.static_ips
291
340
  if static_ips && static_ips.size != job_size
292
341
  raise JobNetworkInstanceIpMismatch,
293
- "Job `#{@job.name}' has #{job_size} instances but was allocated #{static_ips.size} static IPs"
342
+ "Instance group '#{@job.name}' has #{job_size} instances but was allocated #{static_ips.size} static IPs"
294
343
  end
295
344
  end
296
345
 
297
346
  instance_states.each_pair do |index_or_id, state|
298
347
  unless Job::VALID_JOB_STATES.include?(state)
299
348
  raise JobInvalidInstanceState,
300
- "Invalid state `#{state}' for `#{@job.name}/#{index_or_id}', valid states are: #{Job::VALID_JOB_STATES.join(", ")}"
349
+ "Invalid state '#{state}' for '#{@job.name}/#{index_or_id}', valid states are: #{Job::VALID_JOB_STATES.join(", ")}"
301
350
  end
302
351
 
303
352
  @job.instance_states[index_or_id] = state
@@ -305,7 +354,7 @@ module Bosh::Director
305
354
 
306
355
  if @job.state && !Job::VALID_JOB_STATES.include?(@job.state)
307
356
  raise JobInvalidJobState,
308
- "Invalid state `#{@job.state}' for `#{@job.name}', valid states are: #{Job::VALID_JOB_STATES.join(", ")}"
357
+ "Invalid state '#{@job.state}' for '#{@job.name}', valid states are: #{Job::VALID_JOB_STATES.join(", ")}"
309
358
  end
310
359
 
311
360
  job_size.times.map { DesiredInstance.new(@job, @deployment) }
@@ -319,8 +368,8 @@ module Bosh::Director
319
368
  unless az.nil?
320
369
  unless @job.availability_zones.to_a.map(&:name).include?(az)
321
370
  raise DeploymentInvalidMigratedFromJob,
322
- "Job '#{name}' specified for migration to job '#{@job.name}' refers to availability zone '#{az}'. " +
323
- "Az '#{az}' is not in the list of availability zones of job '#{@job.name}'."
371
+ "Instance group '#{name}' specified for migration to instance group '#{@job.name}' refers to availability zone '#{az}'. " +
372
+ "Az '#{az}' is not in the list of availability zones of instance group '#{@job.name}'."
324
373
  end
325
374
  end
326
375
  @job.migrated_from << MigratedFromJob.new(name, az)
@@ -333,20 +382,20 @@ module Bosh::Director
333
382
  jobs_property = safe_property(@job_spec, 'jobs', optional: true)
334
383
 
335
384
  if template_property && templates_property
336
- raise JobInvalidTemplates, "Job `#{@job.name}' specifies both template and templates keys, only one is allowed"
385
+ raise JobInvalidTemplates, "Instance group '#{@job.name}' specifies both template and templates keys, only one is allowed"
337
386
  end
338
387
 
339
388
  if templates_property && jobs_property
340
- raise JobInvalidTemplates, "Job `#{@job.name}' specifies both templates and jobs keys, only one is allowed"
389
+ raise JobInvalidTemplates, "Instance group '#{@job.name}' specifies both templates and jobs keys, only one is allowed"
341
390
  end
342
391
 
343
392
  if template_property && jobs_property
344
- raise JobInvalidTemplates, "Job `#{@job.name}' specifies both template and jobs keys, only one is allowed"
393
+ raise JobInvalidTemplates, "Instance group '#{@job.name}' specifies both template and jobs keys, only one is allowed"
345
394
  end
346
395
 
347
396
  if [template_property, templates_property, jobs_property].compact.empty?
348
397
  raise ValidationMissingField,
349
- "Job `#{@job.name}' does not specify template, templates, or jobs keys, one is required"
398
+ "Instance group '#{@job.name}' does not specify template, templates, or jobs keys, one is required"
350
399
  end
351
400
  end
352
401
 
@@ -356,6 +405,15 @@ module Bosh::Director
356
405
  @job.default_network[property] = network.name if network
357
406
  end
358
407
  end
408
+
409
+ def check_remove_dev_tools
410
+ if Config.remove_dev_tools
411
+ @job.env.spec['bosh'] ||= {}
412
+ unless @job.env.spec['bosh'].has_key?('remove_dev_tools')
413
+ @job.env.spec['bosh']['remove_dev_tools'] = Config.remove_dev_tools
414
+ end
415
+ end
416
+ end
359
417
  end
360
418
  end
361
419
  end