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
@@ -5,8 +5,8 @@ module Bosh::Director
5
5
  # Abstracts the resque system.
6
6
 
7
7
  class JobQueue
8
- def enqueue(username, job_class, description, params)
9
- task = Api::TaskHelper.new.create_task(username, job_class.job_type, description)
8
+ def enqueue(username, job_class, description, params, deployment_name = nil)
9
+ task = Api::TaskHelper.new.create_task(username, job_class.job_type, description, deployment_name)
10
10
 
11
11
  Resque.enqueue(job_class, task.id, *params)
12
12
 
@@ -12,8 +12,8 @@ module Bosh::Director
12
12
  @logger = logger
13
13
  end
14
14
 
15
- def render_job_instances(instance_plan)
16
- instance_plan.each { |instance_plan| render_job_instance(instance_plan) }
15
+ def render_job_instances(instance_plans)
16
+ instance_plans.each { |instance_plan| render_job_instance(instance_plan) }
17
17
  end
18
18
 
19
19
  def render_job_instance(instance_plan)
@@ -31,6 +31,8 @@ module Bosh::Director
31
31
  if instance_plans.empty?
32
32
  @logger.info("No instances to update for '#{@job.name}'")
33
33
  return
34
+ else
35
+ @job.did_change = true
34
36
  end
35
37
 
36
38
  instance_plans.each do |instance_plan|
@@ -81,7 +83,11 @@ module Bosh::Director
81
83
  def delete_unneeded_instances
82
84
  unneeded_instance_plans = @job.obsolete_instance_plans
83
85
  unneeded_instances = @job.unneeded_instances
84
- return if unneeded_instances.empty?
86
+ if unneeded_instances.empty?
87
+ return
88
+ else
89
+ @job.did_change = true
90
+ end
85
91
 
86
92
  event_log_stage = @event_log.begin_stage('Deleting unneeded instances', unneeded_instances.size, [@job.name])
87
93
  dns_manager = DnsManagerProvider.create
@@ -9,7 +9,7 @@ module Bosh::Director
9
9
  end
10
10
 
11
11
  def self.enqueue(username, deployment_name, job_name, instance_id, disk_cid, job_queue)
12
- job_queue.enqueue(username, Jobs::AttachDisk, "attach disk '#{disk_cid}' to '#{job_name}/#{instance_id}'", [deployment_name, job_name, instance_id, disk_cid])
12
+ job_queue.enqueue(username, Jobs::AttachDisk, "attach disk '#{disk_cid}' to '#{job_name}/#{instance_id}'", [deployment_name, job_name, instance_id, disk_cid], deployment_name)
13
13
  end
14
14
 
15
15
  def initialize(deployment_name, job_name, instance_id, disk_cid)
@@ -54,8 +54,8 @@ module Bosh::Director
54
54
  previous_persistent_disk.update(active: false)
55
55
 
56
56
  if instance.state == 'stopped'
57
- @disk_manager.detach_disk(instance, previous_persistent_disk)
58
57
  @disk_manager.unmount_disk(instance, previous_persistent_disk)
58
+ @disk_manager.detach_disk(instance, previous_persistent_disk)
59
59
  end
60
60
 
61
61
  @disk_manager.orphan_disk(previous_persistent_disk)
@@ -35,7 +35,12 @@ module Bosh::Director
35
35
 
36
36
  def perform
37
37
  with_deployment_lock(@deployment) do
38
- count = @problem_resolver.apply_resolutions(@resolutions)
38
+ count, error_message = @problem_resolver.apply_resolutions(@resolutions)
39
+
40
+ if error_message
41
+ raise Bosh::Director::ProblemHandlerError, error_message
42
+ end
43
+
39
44
  "#{count} resolved"
40
45
  end
41
46
  end
@@ -26,6 +26,9 @@ module Bosh::Director
26
26
  def perform
27
27
  jobs = filtered_jobs
28
28
 
29
+ resolved_problems = 0
30
+ error_message = nil
31
+
29
32
  begin
30
33
  with_deployment_lock(@deployment, :timeout => 0) do
31
34
 
@@ -34,10 +37,18 @@ module Bosh::Director
34
37
  scanner.scan_vms(jobs)
35
38
 
36
39
  resolver = ProblemResolver.new(@deployment)
37
- resolver.apply_resolutions(resolutions(jobs))
40
+ resolved_problems, error_message = resolver.apply_resolutions(resolutions(jobs))
38
41
 
39
42
  'scan and fix complete'
40
43
  end
44
+ if resolved_problems > 0
45
+ PostDeploymentScriptRunner.run_post_deploys_after_resurrection(@deployment)
46
+ end
47
+
48
+ if error_message
49
+ raise Bosh::Director::ProblemHandlerError, error_message
50
+ end
51
+
41
52
  rescue Lock::TimeoutError
42
53
  raise 'Unable to get deployment lock, maybe a deployment is in progress. Try again later.'
43
54
  end
@@ -46,7 +57,7 @@ module Bosh::Director
46
57
  def resolutions(jobs)
47
58
  all_resolutions = {}
48
59
  jobs.each do |job, index|
49
- instance = @instance_manager.find_by_name(@deployment.name, job, index)
60
+ instance = @instance_manager.find_by_name(@deployment, job, index)
50
61
  next if instance.resurrection_paused
51
62
  problems = Models::DeploymentProblem.filter(deployment: @deployment, resource_id: instance.id, state: 'open')
52
63
  problems.each do |problem|
@@ -63,7 +74,7 @@ module Bosh::Director
63
74
  return @jobs if @fix_stateful_jobs
64
75
 
65
76
  @jobs.reject do |job, index|
66
- instance = @instance_manager.find_by_name(@deployment.name, job, index)
77
+ instance = @instance_manager.find_by_name(@deployment, job, index)
67
78
  instance.persistent_disk
68
79
  end
69
80
  end
@@ -54,7 +54,7 @@ module Bosh::Director
54
54
 
55
55
  export_release_job = create_job_with_all_the_templates_so_everything_compiles(release_version_model, release, planner, deployment_plan_stemcell)
56
56
  planner.add_job(export_release_job)
57
- planner.bind_models
57
+ planner.bind_models(true)
58
58
 
59
59
  lock_timeout = 15 * 60 # 15 minutes
60
60
 
@@ -23,10 +23,7 @@ module Bosh::Director
23
23
  def perform
24
24
  instance = @instance_manager.find_instance(@instance_id)
25
25
 
26
- deployment = instance.deployment
27
- with_deployment_lock(deployment) do
28
- @logs_fetcher.fetch(instance, @log_type, @filters)
29
- end
26
+ @logs_fetcher.fetch(instance, @log_type, @filters)
30
27
  end
31
28
  end
32
29
  end
@@ -8,10 +8,9 @@ module Bosh::Director::Jobs
8
8
 
9
9
  def delete(compiled_package, options = {})
10
10
  package = compiled_package.package
11
- stemcell = compiled_package.stemcell
12
11
  @logger.info('Deleting compiled package: ' +
13
12
  "#{package.name}/#{package.version}" +
14
- "for #{stemcell.name}/#{stemcell.version}")
13
+ "for #{compiled_package.stemcell_os}/#{compiled_package.stemcell_version}")
15
14
 
16
15
  errors = []
17
16
  if @blob_deleter.delete(compiled_package.blobstore_id, errors, options['force'])
@@ -28,22 +28,6 @@ module Bosh::Director::Jobs
28
28
  @logger.info("Force deleting is set, ignoring exception: #{e.message}")
29
29
  end
30
30
 
31
- @logger.info('Looking for any compiled packages on this stemcell')
32
- compiled_packages = Bosh::Director::Models::CompiledPackage.filter(:stemcell_id => stemcell.id)
33
-
34
- stage = @event_log.begin_stage('Deleting compiled packages',
35
- compiled_packages.count, [stemcell.name, stemcell.version])
36
- @logger.info('Deleting compiled packages ' +
37
- "(#{compiled_packages.count}) for `#{stemcell.name}/#{stemcell.version}'")
38
-
39
- compiled_packages.each do |compiled_package|
40
- message = "#{compiled_package.name}/#{compiled_package.version}"
41
- stage.advance_and_track(message) do
42
- @logger.info(message)
43
- @compiled_package_deleter.delete(compiled_package, options)
44
- end
45
- end
46
-
47
31
  stemcell.destroy
48
32
  end
49
33
  end
@@ -48,8 +48,8 @@ module Bosh::Director
48
48
  template.properties = job_manifest['properties']
49
49
 
50
50
  validate_links(job_manifest)
51
- template.provides = job_manifest['provides']
52
- template.requires = job_manifest['requires']
51
+ template.provides = job_manifest['provides'] if job_manifest['provides']
52
+ template.consumes = job_manifest['consumes'] if job_manifest['consumes']
53
53
 
54
54
  template.save
55
55
  end
@@ -149,21 +149,21 @@ module Bosh::Director
149
149
 
150
150
  def validate_links(job_manifest)
151
151
  parse_links(job_manifest['provides'], 'provides') if job_manifest['provides']
152
- parse_links(job_manifest['requires'], 'requires') if job_manifest['requires']
152
+ parse_links(job_manifest['consumes'], 'consumes') if job_manifest['consumes']
153
153
  end
154
154
 
155
- def parse_links(links, desc)
155
+ def parse_links(links, kind)
156
156
  if !links.is_a?(Array)
157
157
  raise JobInvalidLinkSpec,
158
- "Job '#{@name}' has invalid spec format: '#{desc}' must be an array of strings or hashes with name and type"
158
+ "Job '#{@name}' has invalid spec format: '#{kind}' must be an array of hashes with name and type"
159
159
  end
160
160
 
161
161
  parsed_links = {}
162
162
  links.each do |link_spec|
163
- parsed_link = DeploymentPlan::TemplateLink.parse(link_spec)
163
+ parsed_link = DeploymentPlan::TemplateLink.parse(kind, link_spec)
164
164
  if parsed_links[parsed_link.name]
165
165
  raise JobDuplicateLinkName,
166
- "Job '#{@name}' '#{desc}' specifies links with duplicate name '#{parsed_link.name}'"
166
+ "Job '#{@name}' '#{kind}' specifies links with duplicate name '#{parsed_link.name}'"
167
167
  end
168
168
 
169
169
  parsed_links[parsed_link.name] = true
@@ -23,7 +23,7 @@ module Bosh::Director
23
23
 
24
24
  def perform
25
25
  deployment_model = @deployment_manager.find_by_name(@deployment_name)
26
- deployment_manifest = Manifest.load_from_text(deployment_model.manifest, deployment_model.cloud_config)
26
+ deployment_manifest = Manifest.load_from_text(deployment_model.manifest, deployment_model.cloud_config, deployment_model.runtime_config)
27
27
  deployment_name = deployment_manifest.to_hash['name']
28
28
  with_deployment_lock(deployment_name) do
29
29
  deployment = nil
@@ -32,7 +32,7 @@ module Bosh::Director
32
32
  event_log.begin_stage('Preparing deployment', 1)
33
33
  event_log.track('Preparing deployment') do
34
34
  planner_factory = DeploymentPlan::PlannerFactory.create(logger)
35
- deployment = planner_factory.create_from_manifest(deployment_manifest, deployment_model.cloud_config, {})
35
+ deployment = planner_factory.create_from_manifest(deployment_manifest, deployment_model.cloud_config, deployment_model.runtime_config, {})
36
36
  deployment.bind_models
37
37
  job = deployment.job(@errand_name)
38
38
 
@@ -40,14 +40,14 @@ module Bosh::Director
40
40
  raise JobNotFound, "Errand `#{@errand_name}' doesn't exist"
41
41
  end
42
42
 
43
- unless job.can_run_as_errand?
43
+ unless job.is_errand?
44
44
  raise RunErrandError,
45
- "Job `#{job.name}' is not an errand. To mark a job as an errand " +
45
+ "Instance group '#{job.name}' is not an errand. To mark an instance group as an errand " +
46
46
  "set its lifecycle to 'errand' in the deployment manifest."
47
47
  end
48
48
 
49
49
  if job.instances.empty?
50
- raise InstanceNotFound, "Instance `#{@deployment_name}/#{@errand_name}/0' doesn't exist"
50
+ raise InstanceNotFound, "Instance '#{@deployment_name}/#{@errand_name}/0' doesn't exist"
51
51
  end
52
52
 
53
53
  logger.info('Starting to prepare for deployment')
@@ -21,12 +21,12 @@ module Bosh::Director
21
21
  def perform
22
22
  target = Target.new(@target_payload)
23
23
 
24
- filter = { deployment_id: @deployment_id }
24
+ filter = {}
25
25
  filter[:job] = target.job if target.job
26
-
27
26
  filter.merge!(target.id_filter)
28
27
 
29
- instances = @instance_manager.filter_by(filter)
28
+ deployment = Models::Deployment[@deployment_id]
29
+ instances = @instance_manager.filter_by(deployment, filter)
30
30
 
31
31
  ssh_info = instances.map do |instance|
32
32
  agent = @instance_manager.agent_client_for(instance)
@@ -9,10 +9,11 @@ module Bosh::Director
9
9
  :update_deployment
10
10
  end
11
11
 
12
- def initialize(manifest_file_path, cloud_config_id, options = {})
12
+ def initialize(manifest_file_path, cloud_config_id, runtime_config_id, options = {})
13
13
  @blobstore = App.instance.blobstores.blobstore
14
14
  @manifest_file_path = manifest_file_path
15
15
  @cloud_config_id = cloud_config_id
16
+ @runtime_config_id = runtime_config_id
16
17
  @options = options
17
18
  end
18
19
 
@@ -28,8 +29,16 @@ module Bosh::Director
28
29
  logger.debug("Cloud config:\n#{cloud_config_model.manifest}")
29
30
  end
30
31
 
31
- deployment_manifest = Manifest.load_from_text(manifest_text, cloud_config_model)
32
+ runtime_config_model = Bosh::Director::Models::RuntimeConfig[@runtime_config_id]
33
+ if runtime_config_model.nil?
34
+ logger.debug("No runtime config uploaded yet.")
35
+ else
36
+ logger.debug("Runtime config:\n#{runtime_config_model.manifest}")
37
+ end
38
+
39
+ deployment_manifest = Manifest.load_from_text(manifest_text, cloud_config_model, runtime_config_model)
32
40
  deployment_name = deployment_manifest.to_hash['name']
41
+
33
42
  with_deployment_lock(deployment_name) do
34
43
  @notifier = DeploymentPlan::Notifier.new(deployment_name, Config.nats_rpc, logger)
35
44
  @notifier.send_start_event
@@ -39,14 +48,19 @@ module Bosh::Director
39
48
  event_log.begin_stage('Preparing deployment', 1)
40
49
  event_log.track('Preparing deployment') do
41
50
  planner_factory = DeploymentPlan::PlannerFactory.create(logger)
42
- deployment_plan = planner_factory.create_from_manifest(deployment_manifest, cloud_config_model, @options)
51
+ deployment_plan = planner_factory.create_from_manifest(deployment_manifest, cloud_config_model, runtime_config_model, @options)
43
52
  deployment_plan.bind_models
44
53
  end
45
54
 
55
+ render_job_templates(deployment_plan.jobs_starting_on_deploy)
46
56
  deployment_plan.compile_packages
47
57
 
48
- render_job_templates(deployment_plan.jobs_starting_on_deploy)
49
58
  update_step(deployment_plan).perform
59
+
60
+ if check_for_changes(deployment_plan)
61
+ PostDeploymentScriptRunner.run_post_deploys_after_deployment(deployment_plan)
62
+ end
63
+
50
64
  @notifier.send_end_event
51
65
  logger.info('Finished updating deployment')
52
66
 
@@ -68,6 +82,13 @@ module Bosh::Director
68
82
 
69
83
  # Job tasks
70
84
 
85
+ def check_for_changes(deployment_plan)
86
+ deployment_plan.jobs.each do |job|
87
+ return true if job.did_change
88
+ end
89
+ false
90
+ end
91
+
71
92
  def update_step(deployment_plan)
72
93
  DeploymentPlan::Steps::UpdateStep.new(
73
94
  self,
@@ -87,9 +108,24 @@ module Bosh::Director
87
108
  end
88
109
 
89
110
  def render_job_templates(jobs)
111
+ errors = []
90
112
  job_renderer = JobRenderer.create
91
113
  jobs.each do |job|
92
- job_renderer.render_job_instances(job.needed_instance_plans)
114
+ begin
115
+ job_renderer.render_job_instances(job.needed_instance_plans)
116
+ rescue Exception => e
117
+ errors.push e
118
+ end
119
+ end
120
+
121
+ if errors.length > 0
122
+ message = 'Unable to render instance groups for deployment. Errors are:'
123
+
124
+ errors.each do |e|
125
+ message = "#{message}\n - #{e.message.gsub(/\n/, "\n ")}"
126
+ end
127
+
128
+ raise message
93
129
  end
94
130
  end
95
131
  end
@@ -30,8 +30,6 @@ module Bosh::Director
30
30
  @release_path = release_path
31
31
  end
32
32
 
33
- @release_model, @release_version_model, @manifest, @name, @version = nil, nil, nil, nil, nil
34
-
35
33
  @rebase = !!options['rebase']
36
34
  @fix = !!options['fix']
37
35
  end
@@ -133,10 +131,10 @@ module Bosh::Director
133
131
 
134
132
  @version = next_release_version if @rebase
135
133
 
136
- version_attrs = { :release => @release_model, :version => @version.to_s }
137
-
138
134
  release_is_new = false
139
- @release_version_model = Models::ReleaseVersion.find_or_create(version_attrs){ release_is_new = true }
135
+ @release_version_model = Models::ReleaseVersion.find_or_create(release: @release_model, version: @version.to_s) do
136
+ release_is_new = true
137
+ end
140
138
 
141
139
  if release_is_new
142
140
  @release_version_model.uncommitted_changes = @uncommitted_changes if @uncommitted_changes
@@ -214,7 +212,7 @@ module Bosh::Director
214
212
  end
215
213
  end
216
214
 
217
- packages = Models::Package.where(fingerprint: package_meta["fingerprint"]).all
215
+ packages = Models::Package.where(fingerprint: package_meta['fingerprint']).all
218
216
 
219
217
  if packages.empty?
220
218
  new_packages << package_meta
@@ -223,8 +221,8 @@ module Bosh::Director
223
221
 
224
222
  existing_package = packages.find do |package|
225
223
  package.release_id == @release_model.id &&
226
- package.name == package_meta["name"] &&
227
- package.version == package_meta["version"]
224
+ package.name == package_meta['name'] &&
225
+ package.version == package_meta['version']
228
226
  end
229
227
 
230
228
  if existing_package
@@ -240,8 +238,8 @@ module Bosh::Director
240
238
  if existing_package.blobstore_id.nil?
241
239
  packages.each do |package|
242
240
  unless package.blobstore_id.nil?
243
- package_meta["blobstore_id"] = package.blobstore_id
244
- package_meta["sha1"] = package.sha1
241
+ package_meta['blobstore_id'] = package.blobstore_id
242
+ package_meta['sha1'] = package.sha1
245
243
  break
246
244
  end
247
245
  end
@@ -257,8 +255,8 @@ module Bosh::Director
257
255
  # of the package blob and create a new db entry for it
258
256
  packages.each do |package|
259
257
  unless package.blobstore_id.nil?
260
- package_meta["blobstore_id"] = package.blobstore_id
261
- package_meta["sha1"] = package.sha1
258
+ package_meta['blobstore_id'] = package.blobstore_id
259
+ package_meta['sha1'] = package.sha1
262
260
  break
263
261
  end
264
262
  end
@@ -267,21 +265,19 @@ module Bosh::Director
267
265
  end
268
266
  end
269
267
 
270
- package_stemcell_hashes1 = create_packages(new_packages, release_dir)
268
+ created_package_refs = create_packages(new_packages, release_dir)
271
269
 
272
- package_stemcell_hashes2 = use_existing_packages(existing_packages, release_dir)
270
+ existing_package_refs = use_existing_packages(existing_packages, release_dir)
273
271
 
274
272
  if @compiled_release
275
- compatible_stemcell_combos = registered_packages.flat_map do |pkg, pkg_meta|
276
- stemcells_used_by_package(pkg_meta).map do |stemcell|
277
- {
278
- package: pkg,
279
- stemcell: stemcell
280
- }
281
- end
273
+ registered_package_refs = registered_packages.map do |pkg, pkg_meta|
274
+ {
275
+ package: pkg,
276
+ package_meta: pkg_meta,
277
+ }
282
278
  end
283
- consolidated_package_stemcell_hashes = Array(package_stemcell_hashes1) | Array(package_stemcell_hashes2) | compatible_stemcell_combos
284
- create_compiled_packages(consolidated_package_stemcell_hashes, release_dir, packages_existing_from_other_releases)
279
+ all_package_refs = Array(created_package_refs) | Array(existing_package_refs) | registered_package_refs
280
+ create_compiled_packages(all_package_refs, release_dir, packages_existing_from_other_releases)
285
281
  else
286
282
  backfill_source_for_packages(registered_packages, release_dir)
287
283
  end
@@ -307,13 +303,13 @@ module Bosh::Director
307
303
 
308
304
  # Points release DB model to existing packages described by given metadata
309
305
  # @param [Array<Array>] packages Existing packages metadata.
310
- # @return [Array<Hash>] package & stemcell matching pairs that were registered. empty if no packages were changed.
306
+ # @return [Array<Hash>] array of registered package models and their metadata, empty if no packages were changed.
311
307
  def use_existing_packages(packages, release_dir)
312
308
  if packages.empty?
313
309
  return []
314
310
  end
315
311
 
316
- package_stemcell_hashes = []
312
+ package_refs = []
317
313
 
318
314
  single_step_stage("Processing #{packages.size} existing package#{"s" if packages.size > 1}") do
319
315
  packages.each do |package, package_meta|
@@ -322,11 +318,10 @@ module Bosh::Director
322
318
  register_package(package)
323
319
 
324
320
  if compiled_release
325
- stemcells = stemcells_used_by_package(package_meta)
326
- stemcells.each do |stemcell|
327
- hash = { package: package, stemcell: stemcell}
328
- package_stemcell_hashes << hash
329
- end
321
+ package_refs << {
322
+ package: package,
323
+ package_meta: package_meta,
324
+ }
330
325
  end
331
326
 
332
327
  if source_release && (package.blobstore_id.nil? || @fix)
@@ -336,19 +331,19 @@ module Bosh::Director
336
331
  end
337
332
  end
338
333
 
339
- return package_stemcell_hashes
334
+ return package_refs
340
335
  end
341
336
 
342
337
  # Creates packages using provided metadata
343
338
  # @param [Array<Hash>] packages Packages metadata
344
339
  # @param [String] release_dir local path to the unpacked release
345
- # @return [Array<Hash>, boolean] array of compiled package & stemcell matching pairs that were registered, and a
340
+ # @return [Array<Hash>, boolean] array of package models and their metadata, empty if no packages were changed.
346
341
  def create_packages(package_metas, release_dir)
347
342
  if package_metas.empty?
348
343
  return []
349
344
  end
350
345
 
351
- package_stemcell_hashes = []
346
+ package_refs = []
352
347
 
353
348
  event_log.begin_stage("Creating new packages", package_metas.size)
354
349
 
@@ -362,15 +357,14 @@ module Bosh::Director
362
357
  end
363
358
 
364
359
  if @compiled_release
365
- stemcells = stemcells_used_by_package(package_meta)
366
- stemcells.each do |stemcell|
367
- hash = { package: package, stemcell: stemcell}
368
- package_stemcell_hashes << hash
369
- end
360
+ package_refs << {
361
+ package: package,
362
+ package_meta: package_meta,
363
+ }
370
364
  end
371
365
  end
372
366
 
373
- return package_stemcell_hashes
367
+ return package_refs
374
368
  end
375
369
 
376
370
  # @return [boolean] true if at least one job was created; false if the call had no effect.
@@ -382,19 +376,24 @@ module Bosh::Director
382
376
 
383
377
  all_compiled_packages.each do |compiled_package_spec|
384
378
  package = compiled_package_spec[:package]
385
- stemcell = compiled_package_spec[:stemcell]
379
+ stemcell = Models::CompiledPackage.split_stemcell_os_and_version(compiled_package_spec[:package_meta]['stemcell'])
386
380
  compiled_pkg_tgz = File.join(release_dir, 'compiled_packages', "#{package.name}.tgz")
387
381
 
388
- existing_compiled_packages = Models::CompiledPackage.where(:package_id => package.id, :stemcell_id => stemcell.id)
389
- if existing_compiled_packages.empty?
382
+ stemcell_os = stemcell[:os]
383
+ stemcell_version = stemcell[:version]
390
384
 
391
- package_desc = "#{package.name}/#{package.version} for #{stemcell.name}/#{stemcell.version}"
385
+ existing_compiled_packages = find_compiled_packages(package.id, stemcell_os, stemcell_version, dependency_key(package))
386
+
387
+ if existing_compiled_packages.empty?
388
+ package_desc = "#{package.name}/#{package.version} for #{stemcell_os}/#{stemcell_version}"
392
389
  event_log.track(package_desc) do
393
- other_compiled_package = get_other_compiled_package(package, packages_existing_from_other_releases, stemcell)
394
- if @fix && !other_compiled_package.nil?
395
- fix_compiled_package(other_compiled_package, compiled_pkg_tgz)
390
+ other_compiled_packages = compiled_packages_matching(package, packages_existing_from_other_releases, stemcell)
391
+ if @fix
392
+ other_compiled_packages.each do |other_compiled_package|
393
+ fix_compiled_package(other_compiled_package, compiled_pkg_tgz)
394
+ end
396
395
  end
397
- create_compiled_package(package, stemcell, release_dir, other_compiled_package)
396
+ create_compiled_package(package, stemcell_os, stemcell_version, release_dir, other_compiled_packages.first)
398
397
  had_effect = true
399
398
  end
400
399
  elsif @fix
@@ -407,41 +406,21 @@ module Bosh::Director
407
406
  had_effect
408
407
  end
409
408
 
410
- def get_other_compiled_package(package, packages_existing_from_other_releases, stemcell)
411
- other_compiled_package = nil
409
+ def compiled_packages_matching(package, packages_existing_from_other_releases, stemcell)
410
+ other_compiled_packages = []
411
+ dependency_key = dependency_key(package)
412
412
  packages_existing_from_other_releases.each do |other_package_meta|
413
413
  if other_package_meta["fingerprint"] == package.fingerprint
414
414
  packages = Models::Package.where(fingerprint: other_package_meta["fingerprint"]).all
415
415
  packages.each do |pkg|
416
- other_compiled_package = Models::CompiledPackage.where(:package_id => pkg.id, :stemcell_id => stemcell.id).first
417
- break unless other_compiled_package.nil?
416
+ other_compiled_packages.concat(find_compiled_packages(pkg.id, stemcell[:os], stemcell[:version], dependency_key).all)
418
417
  end
419
418
  end
420
419
  end
421
- other_compiled_package
420
+ other_compiled_packages
422
421
  end
423
422
 
424
- def stemcells_used_by_package(package_meta)
425
- if package_meta['stemcell'].nil?
426
- raise 'stemcell informatiom(operating system/version) should be listed for each package of a compiled tarball'
427
- end
428
-
429
- values = package_meta['stemcell'].split('/', 2)
430
- operating_system = values[0]
431
- stemcell_version = values[1]
432
- unless operating_system && stemcell_version
433
- raise 'stemcell informatiom(operating system/version) should be listed for each package of a compiled tarball'
434
- end
435
-
436
- stemcells = Models::Stemcell.where(:operating_system => operating_system, :version => stemcell_version)
437
- if stemcells.empty?
438
- raise "No stemcells matching OS #{operating_system} version #{stemcell_version}"
439
- end
440
-
441
- stemcells
442
- end
443
-
444
- def create_compiled_package(package, stemcell, release_dir, other_compiled_package)
423
+ def create_compiled_package(package, stemcell_os, stemcell_version, release_dir, other_compiled_package)
445
424
  if other_compiled_package.nil?
446
425
  tgz = File.join(release_dir, 'compiled_packages', "#{package.name}.tgz")
447
426
  validate_tgz(tgz, "#{package.name}.tgz")
@@ -455,13 +434,17 @@ module Bosh::Director
455
434
  compiled_package = Models::CompiledPackage.new
456
435
  compiled_package.blobstore_id = blobstore_id
457
436
  compiled_package.sha1 = sha1
437
+ release_version_model_dependency_key = dependency_key(package)
438
+ if release_version_model_dependency_key != CompiledRelease::Manifest.new(@manifest).dependency_key(package.name)
439
+ raise ReleasePackageDependencyKeyMismatch, "The uploaded release contains package dependencies in '#{package.name}' that do not match database records."
440
+ end
441
+ compiled_package.dependency_key = release_version_model_dependency_key
458
442
 
459
- transitive_dependencies = @release_version_model.transitive_dependencies(package)
460
- compiled_package.dependency_key = Models::CompiledPackage.create_dependency_key(transitive_dependencies)
461
-
462
- compiled_package.build = Models::CompiledPackage.generate_build_number(package, stemcell)
443
+ compiled_package.build = Models::CompiledPackage.generate_build_number(package, stemcell_os, stemcell_version)
463
444
  compiled_package.package_id = package.id
464
- compiled_package.stemcell_id = stemcell.id
445
+
446
+ compiled_package.stemcell_os = stemcell_os
447
+ compiled_package.stemcell_version = stemcell_version
465
448
 
466
449
  compiled_package.save
467
450
  end
@@ -640,6 +623,19 @@ module Bosh::Director
640
623
 
641
624
  private
642
625
 
626
+ def dependency_key(package)
627
+ KeyGenerator.new.dependency_key_from_models(package, @release_version_model)
628
+ end
629
+
630
+ def find_compiled_packages(pkg_id, stemcell_os, stemcell_version, dependency_key)
631
+ Models::CompiledPackage.where(
632
+ :package_id => pkg_id,
633
+ :stemcell_os => stemcell_os,
634
+ :stemcell_version => stemcell_version,
635
+ :dependency_key => dependency_key
636
+ )
637
+ end
638
+
643
639
  # Marks job template model as being used by release version
644
640
  # @param [Models::Template] template Job template model
645
641
  # @return [void]
@@ -673,8 +669,8 @@ with blobstore_id '#{package.blobstore_id}'")
673
669
  def delete_compiled_packages(package)
674
670
  package.compiled_packages.each do |compiled_pkg|
675
671
  unless BlobUtil.verify_blob(compiled_pkg.blobstore_id, compiled_pkg.sha1)
676
- logger.info("Deleting compiled package '#{compiled_pkg.name}' \
677
- for '#{compiled_pkg.stemcell.name}/#{compiled_pkg.stemcell.version}' with blobstore_id '#{compiled_pkg.blobstore_id}'")
672
+ logger.info("Deleting compiled package '#{compiled_pkg.name}' for \
673
+ '#{compiled_pkg.stemcell_os}/#{compiled_pkg.stemcell_version}' with blobstore_id '#{compiled_pkg.blobstore_id}'")
678
674
  begin
679
675
  logger.info("Deleting compiled package '#{compiled_pkg.name}'")
680
676
  BlobUtil.delete_blob(compiled_pkg.blobstore_id)
@@ -689,8 +685,8 @@ for '#{compiled_pkg.stemcell.name}/#{compiled_pkg.stemcell.version}' with blobst
689
685
 
690
686
  def fix_compiled_package(compiled_pkg, compiled_pkg_tgz)
691
687
  begin
692
- logger.info("Deleting compiled package '#{compiled_pkg.name}/#{compiled_pkg.version}' \
693
- for '#{compiled_pkg.stemcell.name}/#{compiled_pkg.stemcell.version}' with blobstore_id '#{compiled_pkg.blobstore_id}'")
688
+ logger.info("Deleting compiled package '#{compiled_pkg.name}/#{compiled_pkg.version}' for \
689
+ '#{compiled_pkg.stemcell_os}/#{compiled_pkg.stemcell_version}' with blobstore_id '#{compiled_pkg.blobstore_id}'")
694
690
  BlobUtil.delete_blob compiled_pkg.blobstore_id
695
691
  rescue Bosh::Blobstore::BlobstoreError => e
696
692
  logger.info("Error deleting compiled package '#{compiled_pkg.name}' \