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
@@ -16,11 +16,11 @@ module Bosh::Director
16
16
  version = safe_property(spec, "version", :class => String)
17
17
 
18
18
  if name.nil? && os.nil?
19
- raise ValidationMissingField, "Required property `os' or `name' was not specified in object (#{spec})"
19
+ raise ValidationMissingField, "Required property 'os' or 'name' was not specified in object (#{spec})"
20
20
  end
21
21
 
22
22
  if !name.nil? && !os.nil?
23
- raise StemcellBothNameAndOS, "Properties `os' and `name' are both specified for stemcell, choose one. (#{spec})"
23
+ raise StemcellBothNameAndOS, "Properties 'os' and 'name' are both specified for stemcell, choose one. (#{spec})"
24
24
  end
25
25
 
26
26
  new(name_alias, name, os, version)
@@ -63,7 +63,7 @@ module Bosh::Director
63
63
  # Check if the package was compiled in a parallel deployment
64
64
  compiled_package = task.find_compiled_package(@logger, @event_log)
65
65
  if compiled_package.nil?
66
- build = Models::CompiledPackage.generate_build_number(package, stemcell.model)
66
+ build = Models::CompiledPackage.generate_build_number(package, stemcell.model.operating_system, stemcell.model.version)
67
67
  task_result = nil
68
68
 
69
69
  prepare_vm(stemcell) do |instance|
@@ -82,7 +82,8 @@ module Bosh::Director
82
82
 
83
83
  compiled_package = Models::CompiledPackage.create do |p|
84
84
  p.package = package
85
- p.stemcell = stemcell.model
85
+ p.stemcell_os = stemcell.os
86
+ p.stemcell_version = stemcell.version
86
87
  p.sha1 = task_result['sha1']
87
88
  p.build = build
88
89
  p.blobstore_id = task_result['blobstore_id']
@@ -1,6 +1,10 @@
1
+ require 'bosh/template/property_helper'
2
+
1
3
  module Bosh::Director
2
4
  module DeploymentPlan
3
5
  class Template
6
+ include Bosh::Template::PropertyHelper
7
+ include ValidationHelper
4
8
 
5
9
  attr_reader :name
6
10
  attr_reader :release
@@ -8,6 +12,9 @@ module Bosh::Director
8
12
  attr_reader :model
9
13
  attr_reader :package_models
10
14
 
15
+ attr_reader :link_infos
16
+ attr_reader :template_scoped_properties
17
+
11
18
  # @param [DeploymentPlan::ReleaseVersion] release Release version
12
19
  # @param [String] name Template name
13
20
  def initialize(release, name)
@@ -16,6 +23,15 @@ module Bosh::Director
16
23
  @model = nil
17
24
  @package_models = []
18
25
  @logger = Config.logger
26
+ @link_infos = {}
27
+
28
+ # This hash will contain the properties specific to this template,
29
+ # it will be a hash where the keys are the deployment job name, and
30
+ # the value of each key will be the properties defined in template
31
+ # section of the deployment manifest. This way if a template is used
32
+ # in multiple deployment jobs, the properties will not be shared across
33
+ # jobs
34
+ @template_scoped_properties = {}
19
35
  end
20
36
 
21
37
  # Looks up template model and its package models in DB
@@ -24,7 +40,7 @@ module Bosh::Director
24
40
  @model = @release.get_template_model_by_name(@name)
25
41
 
26
42
  if @model.nil?
27
- raise DeploymentUnknownTemplate, "Can't find template `#{@name}'"
43
+ raise DeploymentUnknownTemplate, "Can't find job '#{@name}'"
28
44
  end
29
45
 
30
46
  @package_models = @model.package_names.map do |name|
@@ -42,14 +58,14 @@ module Bosh::Director
42
58
  uuid = SecureRandom.uuid
43
59
  path = File.join(Dir.tmpdir, "template-#{uuid}")
44
60
 
45
- @logger.debug("Downloading template `#{@name}' (#{blobstore_id})...")
61
+ @logger.debug("Downloading job '#{@name}' (#{blobstore_id})...")
46
62
  t1 = Time.now
47
63
 
48
64
  File.open(path, "w") do |f|
49
65
  App.instance.blobstores.blobstore.get(blobstore_id, f)
50
66
  end
51
67
 
52
- @logger.debug("Template `#{@name}' downloaded to #{path} " +
68
+ @logger.debug("Job '#{@name}' downloaded to #{path} " +
53
69
  "(took #{Time.now - t1}s)")
54
70
 
55
71
  path
@@ -81,13 +97,82 @@ module Bosh::Director
81
97
  end
82
98
 
83
99
  # return [Array]
84
- def required_links
85
- present_model.requires.to_a.map { |l| TemplateLink.parse(l) }
100
+ def model_consumed_links
101
+ present_model.consumes.to_a.map { |l| TemplateLink.parse("consumes", l) }
86
102
  end
87
103
 
88
104
  # return [Array]
89
- def provided_links
90
- present_model.provides.to_a.map { |l| TemplateLink.parse(l) }
105
+ def model_provided_links
106
+ present_model.provides.to_a.map { |l| TemplateLink.parse('provides', l) }
107
+ end
108
+
109
+ # return [Array]
110
+ def consumed_links(job_name)
111
+ if @link_infos[job_name] != nil && @link_infos[job_name]["consumes"] != nil
112
+ @link_infos[job_name]["consumes"].map { |_, link_info| TemplateLink.parse("consumes", link_info) }
113
+ else
114
+ return []
115
+ end
116
+ end
117
+
118
+ # return [Array]
119
+ def provided_links(job_name)
120
+ if @link_infos[job_name] != nil && @link_infos[job_name]["provides"] != nil
121
+ @link_infos[job_name]["provides"].map { |_, link_info| TemplateLink.parse("provides", link_info) }
122
+ else
123
+ return []
124
+ end
125
+ end
126
+
127
+ def add_link_info(job_name, kind, link_name, source)
128
+ @link_infos[job_name] ||= {}
129
+ @link_infos[job_name][kind] ||= {}
130
+ @link_infos[job_name][kind][link_name] ||= {}
131
+
132
+ if source.eql? 'nil'
133
+ # This is the case where the user set link source to nil explicitly in the deployment manifest
134
+ # We should skip the binding of this link, even if it exist. This is used only when the link
135
+ # is optional
136
+ @link_infos[job_name][kind][link_name]['skip_link'] = true
137
+ else
138
+ source.to_a.each do |key, value|
139
+ @link_infos[job_name][kind][link_name][key] = value
140
+ end
141
+ end
142
+ end
143
+
144
+ def consumes_link_info(job_name, link_name)
145
+ @link_infos.fetch(job_name, {}).fetch('consumes', {}).fetch(link_name, {})
146
+ end
147
+
148
+ def provides_link_info(job_name, link_name)
149
+ @link_infos.fetch(job_name, {}).fetch('provides', {}).each do |index, link|
150
+ if link['as'] == link_name
151
+ return link
152
+ end
153
+ end
154
+ return @link_infos.fetch(job_name, {}).fetch('provides', {}).fetch(link_name, {})
155
+ end
156
+
157
+ def add_template_scoped_properties(template_scoped_properties, deployment_job_name)
158
+ @template_scoped_properties[deployment_job_name] = template_scoped_properties
159
+ end
160
+
161
+ def has_template_scoped_properties(deployment_job_name)
162
+ return !@template_scoped_properties[deployment_job_name].nil?
163
+ end
164
+
165
+ def bind_template_scoped_properties(deployment_job_name)
166
+ bound_template_scoped_properties = {}
167
+ properties.each_pair do |name, definition|
168
+ copy_property(
169
+ bound_template_scoped_properties,
170
+ @template_scoped_properties[deployment_job_name],
171
+ name,
172
+ definition["default"]
173
+ )
174
+ end
175
+ @template_scoped_properties[deployment_job_name] = bound_template_scoped_properties
91
176
  end
92
177
 
93
178
  private
@@ -96,7 +181,7 @@ module Bosh::Director
96
181
  # @return [Models::Template]
97
182
  def present_model
98
183
  if @model.nil?
99
- raise DirectorError, "Template `#{@name}' model is unbound"
184
+ raise DirectorError, "Job '#{@name}' model is unbound"
100
185
  end
101
186
  @model
102
187
  end
@@ -62,6 +62,16 @@ module Bosh::Director
62
62
  end
63
63
  end
64
64
 
65
+ def to_hash
66
+ {
67
+ 'canaries' => @canaries,
68
+ 'max_in_flight' => @max_in_flight,
69
+ 'canary_watch_time' => "#{@min_canary_watch_time}-#{@max_canary_watch_time}",
70
+ 'update_watch_time' => "#{@min_update_watch_time}-#{@max_update_watch_time}",
71
+ 'serial' => @serial
72
+ }
73
+ end
74
+
65
75
  def parse_watch_times(value)
66
76
  value = value.to_s
67
77
 
@@ -0,0 +1,27 @@
1
+ module Bosh::Director
2
+ module DeploymentPlan
3
+ class VmExtension
4
+ include ValidationHelper
5
+
6
+ attr_reader :name
7
+
8
+ attr_reader :cloud_properties
9
+
10
+ def initialize(spec)
11
+
12
+ @name = safe_property(spec, "name", class: String)
13
+
14
+ @cloud_properties =
15
+ safe_property(spec, "cloud_properties", class: Hash, default: {})
16
+
17
+ end
18
+
19
+ def spec
20
+ {
21
+ "name" => @name,
22
+ "cloud_properties" => @cloud_properties,
23
+ }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -18,7 +18,7 @@ module Bosh::Director
18
18
  # @return [String] short description of the errand result
19
19
  def run(&blk)
20
20
  unless instance
21
- raise DirectorError, 'Must have at least one job instance to run an errand'
21
+ raise DirectorError, 'Must have at least one instance group instance to run an errand'
22
22
  end
23
23
 
24
24
  agent_task_result = nil
@@ -78,6 +78,7 @@ module Bosh::Director
78
78
  ReleaseExistingJobFingerprintMismatch = err(30013)
79
79
  ReleaseVersionCommitHashMismatch = err(30014)
80
80
  ReleaseSha1DoesNotMatch = err(30015)
81
+ ReleasePackageDependencyKeyMismatch = err(30016)
81
82
 
82
83
  ValidationInvalidType = err(40000)
83
84
  ValidationMissingField = err(40001)
@@ -139,6 +140,8 @@ module Bosh::Director
139
140
  CompilationConfigInvalidAvailabilityZone = err(120002)
140
141
  CompilationConfigInvalidVmType = err(120003)
141
142
  CompilationConfigCloudPropertiesNotAllowed = err(120004)
143
+ CompilationConfigInvalidVmExtension = err(120005)
144
+ CompilationConfigVmTypeRequired = err(120004)
142
145
 
143
146
  # Manifest parsing: network section
144
147
  NetworkReservationInvalidIp = err(130001)
@@ -208,6 +211,7 @@ module Bosh::Director
208
211
  DeploymentDuplicateReleaseName = err(190002)
209
212
  DeploymentDuplicateResourcePoolName = err(190003)
210
213
  DeploymentDuplicateVmTypeName = err(190004)
214
+ DeploymentDuplicateVmExtensionName = err(190005)
211
215
  DeploymentCanonicalJobNameTaken = err(190006)
212
216
  DeploymentCanonicalNetworkNameTaken = err(190007)
213
217
  DeploymentNoNetworks = err(190008)
@@ -269,6 +273,12 @@ module Bosh::Director
269
273
  AttachDiskNoPersistentDisk = err(520002)
270
274
  AttachDiskInvalidInstanceState = err(520003)
271
275
 
276
+ # Addons
277
+ RuntimeAmbiguousReleaseSpec = err(530000)
278
+ RuntimeInvalidReleaseVersion = err(530001)
279
+ RuntimeReleaseNotListedInReleases = err(530002)
280
+ RuntimeInvalidDeploymentRelease = err(530003)
281
+
272
282
  # Authorization errors
273
- UnauthorizedToAccessDeployment = err(600000)
283
+ UnauthorizedToAccessDeployment = err(600000, UNAUTHORIZED)
274
284
  end
@@ -43,62 +43,63 @@ module Bosh::Director
43
43
  instance = instance_plan.instance
44
44
  @logger.info("Updating instance #{instance}, changes: #{instance_plan.changes.to_a.join(', ').inspect}")
45
45
 
46
- @canary = options.fetch(:canary, false)
46
+ InstanceUpdater::InstanceState.with_instance_update(instance.model) do
47
+ # Optimization to only update DNS if nothing else changed.
48
+ if dns_change_only?(instance_plan)
49
+ @logger.debug('Only change is DNS configuration')
50
+ update_dns(instance_plan)
51
+ return
52
+ end
47
53
 
48
- # Optimization to only update DNS if nothing else changed.
49
- if dns_change_only?(instance_plan)
50
- @logger.debug('Only change is DNS configuration')
51
- update_dns(instance_plan)
52
- return
53
- end
54
+ unless instance_plan.currently_detached?
55
+ Preparer.new(instance_plan, agent(instance), @logger).prepare
54
56
 
55
- unless instance_plan.currently_detached?
56
- Preparer.new(instance_plan, agent(instance), @logger).prepare
57
+ stop(instance_plan)
58
+ take_snapshot(instance)
59
+ end
57
60
 
58
- stop(instance_plan)
59
- take_snapshot(instance)
60
- end
61
+ if instance.state == 'detached'
62
+ @logger.info("Detaching instance #{instance}")
63
+ unless instance_plan.currently_detached?
64
+ @disk_manager.unmount_disk_for(instance_plan)
65
+ instance_model = instance_plan.new? ? instance_plan.instance.model : instance_plan.existing_instance
66
+ @vm_deleter.delete_for_instance(instance_model)
67
+ end
68
+ release_obsolete_ips(instance_plan)
69
+ instance.update_state
70
+ return
71
+ end
61
72
 
62
- if instance.state == 'detached'
63
- @logger.info("Detaching instance #{instance}")
64
- unless instance_plan.currently_detached?
73
+ recreated = false
74
+ if needs_recreate?(instance_plan)
75
+ @logger.debug('Failed to update in place. Recreating VM')
65
76
  @disk_manager.unmount_disk_for(instance_plan)
66
- instance_model = instance_plan.new? ? instance_plan.instance.model : instance_plan.existing_instance
67
- @vm_deleter.delete_for_instance(instance_model)
77
+ @vm_recreator.recreate_vm(instance_plan, nil)
78
+ recreated = true
68
79
  end
69
- release_obsolete_ips(instance_plan)
70
- instance.update_state
71
- return
72
- end
73
-
74
- recreated = false
75
- if needs_recreate?(instance_plan)
76
- @logger.debug('Failed to update in place. Recreating VM')
77
- @disk_manager.unmount_disk_for(instance_plan)
78
- @vm_recreator.recreate_vm(instance_plan, nil)
79
- recreated = true
80
- end
81
80
 
82
- release_obsolete_ips(instance_plan)
81
+ release_obsolete_ips(instance_plan)
83
82
 
84
- update_dns(instance_plan)
85
- @disk_manager.update_persistent_disk(instance_plan, @vm_recreator)
83
+ update_dns(instance_plan)
84
+ @disk_manager.update_persistent_disk(instance_plan, @vm_recreator)
86
85
 
87
- unless recreated
88
- if instance.trusted_certs_changed?
89
- @logger.debug('Updating trusted certs')
90
- instance.update_trusted_certs
86
+ unless recreated
87
+ if instance.trusted_certs_changed?
88
+ @logger.debug('Updating trusted certs')
89
+ instance.update_trusted_certs
90
+ end
91
91
  end
92
- end
93
92
 
94
- cleaner = RenderedJobTemplatesCleaner.new(instance.model, @blobstore, @logger)
95
- state_applier = InstanceUpdater::StateApplier.new(instance_plan, agent(instance), cleaner, @logger)
96
- state_applier.apply
97
-
98
- job = instance_plan.desired_instance.job
99
- min_watch_time = get_min_watch_time(job.update)
100
- max_watch_time = get_max_watch_time(job.update)
101
- state_applier.post_start(min_watch_time, max_watch_time)
93
+ cleaner = RenderedJobTemplatesCleaner.new(instance.model, @blobstore, @logger)
94
+ state_applier = InstanceUpdater::StateApplier.new(
95
+ instance_plan,
96
+ agent(instance),
97
+ cleaner,
98
+ @logger,
99
+ canary: options[:canary]
100
+ )
101
+ state_applier.apply(instance_plan.desired_instance.job.update)
102
+ end
102
103
  end
103
104
 
104
105
  private
@@ -132,18 +133,6 @@ module Bosh::Director
132
133
  @dns_manager.flush_dns_cache
133
134
  end
134
135
 
135
- def get_min_watch_time(update_config)
136
- canary? ? update_config.min_canary_watch_time : update_config.min_update_watch_time
137
- end
138
-
139
- def get_max_watch_time(update_config)
140
- canary? ? update_config.max_canary_watch_time : update_config.max_update_watch_time
141
- end
142
-
143
- def canary?
144
- @canary
145
- end
146
-
147
136
  def dns_change_only?(instance_plan)
148
137
  instance_plan.changes.include?(:dns) && instance_plan.changes.size == 1
149
138
  end
@@ -0,0 +1,9 @@
1
+ module Bosh::Director
2
+ class InstanceUpdater::InstanceState
3
+ def self.with_instance_update(instance_model)
4
+ instance_model.update(update_completed: false)
5
+ yield
6
+ instance_model.update(update_completed: true)
7
+ end
8
+ end
9
+ end
@@ -1,31 +1,45 @@
1
1
  module Bosh::Director
2
2
  class InstanceUpdater::StateApplier
3
- def initialize(instance_plan, agent_client, rendered_job_templates_cleaner, logger)
3
+ def initialize(instance_plan, agent_client, rendered_job_templates_cleaner, logger, options)
4
4
  @instance_plan = instance_plan
5
5
  @instance = @instance_plan.instance
6
6
  @agent_client = agent_client
7
7
  @rendered_job_templates_cleaner = rendered_job_templates_cleaner
8
8
  @logger = logger
9
+ @is_canary = options.fetch(:canary, false)
9
10
  end
10
11
 
11
- def apply
12
+ def apply(update_config)
12
13
  @instance.apply_vm_state(@instance_plan.spec)
13
14
  @instance.update_templates(@instance_plan.templates)
14
15
  @rendered_job_templates_cleaner.clean
15
16
 
16
17
  if @instance.state == 'started'
18
+ @logger.info("Running pre-start for #{@instance}")
17
19
  @agent_client.run_script('pre-start', {})
20
+
21
+ @logger.info("Starting instance #{@instance}")
18
22
  @agent_client.start
19
23
  end
24
+
25
+ # for backwards compatibility with instances that don't have update config
26
+ if update_config
27
+ min_watch_time = @is_canary ? update_config.min_canary_watch_time : update_config.min_update_watch_time
28
+ max_watch_time = @is_canary ? update_config.max_canary_watch_time : update_config.max_update_watch_time
29
+
30
+ post_start(min_watch_time, max_watch_time)
31
+ end
20
32
  end
21
33
 
34
+ private
35
+
22
36
  def post_start(min_watch_time, max_watch_time)
23
37
  current_state = wait_until_desired_state(min_watch_time, max_watch_time)
24
38
 
25
39
  if @instance.state == 'started'
26
40
  if current_state['job_state'] != 'running'
27
41
  failing_jobs = Array(current_state['processes']).map do |process|
28
- process['name'] if process['state'] != 'starting' && process['state'] != 'running'
42
+ process['name'] if process['state'] != 'running'
29
43
  end.compact
30
44
 
31
45
  error_message = "`#{@instance}' is not running after update."
@@ -33,6 +47,7 @@ module Bosh::Director
33
47
 
34
48
  raise AgentJobNotRunning, error_message
35
49
  else
50
+ @logger.info("Running post-start for #{@instance}")
36
51
  @agent_client.run_script('post-start', {})
37
52
  end
38
53
  end
@@ -44,8 +59,6 @@ module Bosh::Director
44
59
  @instance.update_state
45
60
  end
46
61
 
47
- private
48
-
49
62
  def wait_until_desired_state(min_watch_time, max_watch_time)
50
63
  current_state = {}
51
64
  watch_schedule(min_watch_time, max_watch_time).each do |watch_time|