bosh-director 1.3160.0 → 1.3163.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (195) hide show
  1. checksums.yaml +4 -4
  2. data/bin/bosh-director-worker +2 -14
  3. data/db/migrations/director/20150513225143_ip_addresses.rb +11 -0
  4. data/db/migrations/director/20150702004608_add_links.rb +8 -0
  5. data/db/migrations/director/20150708231924_add_link_spec.rb +7 -0
  6. data/db/migrations/director/20150724183256_add_debugging_to_ip_addresses.rb +8 -0
  7. data/db/migrations/director/20150730225029_add_uuid_to_instances.rb +16 -0
  8. data/db/migrations/director/20150803215805_add_availabililty_zone_and_cloud_properties_to_instances.rb +8 -0
  9. data/db/migrations/director/20150804211419_add_compilation_flag_to_instance.rb +7 -0
  10. data/db/migrations/director/20150918003455_add_bootstrap_node_to_instance.rb +7 -0
  11. data/db/migrations/director/20151008232214_add_dns_records.rb +7 -0
  12. data/db/migrations/director/20151015172551_add_orphan_disks_and_snapshots.rb +29 -0
  13. data/db/migrations/director/20151030222853_add_templates_to_instance.rb +10 -0
  14. data/db/migrations/director/20151031001039_add_spec_to_instance.rb +19 -0
  15. data/db/migrations/director/20151109190602_rename_orphan_columns.rb +13 -0
  16. data/lib/bosh/director.rb +19 -9
  17. data/lib/bosh/director/agent_client.rb +0 -17
  18. data/lib/bosh/director/api/cloud_config_manager.rb +7 -5
  19. data/lib/bosh/director/api/controllers/base_controller.rb +3 -2
  20. data/lib/bosh/director/api/controllers/cleanup_controller.rb +15 -0
  21. data/lib/bosh/director/api/controllers/deployments_controller.rb +38 -26
  22. data/lib/bosh/director/api/controllers/disks_controller.rb +20 -0
  23. data/lib/bosh/director/api/controllers/info_controller.rb +2 -2
  24. data/lib/bosh/director/api/controllers/releases_controller.rb +1 -16
  25. data/lib/bosh/director/api/controllers/stemcells_controller.rb +1 -9
  26. data/lib/bosh/director/api/deployment_manager.rb +2 -1
  27. data/lib/bosh/director/api/instance_lookup.rb +17 -0
  28. data/lib/bosh/director/api/instance_manager.rb +20 -10
  29. data/lib/bosh/director/api/release_manager.rb +28 -8
  30. data/lib/bosh/director/api/resurrector_manager.rb +9 -2
  31. data/lib/bosh/director/api/route_configuration.rb +2 -0
  32. data/lib/bosh/director/api/snapshot_manager.rb +9 -5
  33. data/lib/bosh/director/api/stemcell_manager.rb +50 -0
  34. data/lib/bosh/director/app.rb +1 -1
  35. data/lib/bosh/director/cloudcheck_helper.rb +119 -132
  36. data/lib/bosh/director/compile_task.rb +1 -1
  37. data/lib/bosh/director/compile_task_generator.rb +2 -2
  38. data/lib/bosh/director/config.rb +21 -12
  39. data/lib/bosh/director/deployment_deleter.rb +69 -0
  40. data/lib/bosh/director/deployment_plan.rb +35 -4
  41. data/lib/bosh/director/deployment_plan/agent_state_migrator.rb +47 -0
  42. data/lib/bosh/director/deployment_plan/assembler.rb +115 -241
  43. data/lib/bosh/director/deployment_plan/availability_zone.rb +27 -0
  44. data/lib/bosh/director/deployment_plan/cloud_manifest_parser.rb +144 -35
  45. data/lib/bosh/director/deployment_plan/compilation_config.rb +21 -19
  46. data/lib/bosh/director/deployment_plan/compilation_instance_pool.rb +169 -0
  47. data/lib/bosh/director/deployment_plan/deployment_repo.rb +4 -8
  48. data/lib/bosh/director/deployment_plan/deployment_spec_parser.rb +13 -1
  49. data/lib/bosh/director/deployment_plan/deployment_validator.rb +17 -0
  50. data/lib/bosh/director/deployment_plan/desired_instance.rb +15 -0
  51. data/lib/bosh/director/deployment_plan/{disk_pool.rb → disk_type.rb} +14 -19
  52. data/lib/bosh/director/deployment_plan/dynamic_network.rb +105 -53
  53. data/lib/bosh/director/deployment_plan/dynamic_network_subnet.rb +13 -0
  54. data/lib/bosh/director/deployment_plan/env.rb +18 -0
  55. data/lib/bosh/director/deployment_plan/global_network_resolver.rb +77 -0
  56. data/lib/bosh/director/deployment_plan/instance.rb +222 -390
  57. data/lib/bosh/director/deployment_plan/instance_network_reservations.rb +71 -0
  58. data/lib/bosh/director/deployment_plan/instance_plan.rb +336 -0
  59. data/lib/bosh/director/deployment_plan/instance_plan_factory.rb +54 -0
  60. data/lib/bosh/director/deployment_plan/instance_plan_sorter.rb +61 -0
  61. data/lib/bosh/director/deployment_plan/instance_planner.rb +101 -0
  62. data/lib/bosh/director/deployment_plan/instance_repository.rb +36 -0
  63. data/lib/bosh/director/deployment_plan/instance_spec.rb +154 -0
  64. data/lib/bosh/director/deployment_plan/ip_provider/database_ip_repo.rb +136 -0
  65. data/lib/bosh/director/deployment_plan/ip_provider/in_memory_ip_repo.rb +81 -0
  66. data/lib/bosh/director/deployment_plan/ip_provider/ip_provider.rb +153 -0
  67. data/lib/bosh/director/deployment_plan/ip_provider/ip_provider_factory.rb +22 -0
  68. data/lib/bosh/director/deployment_plan/job.rb +116 -53
  69. data/lib/bosh/director/deployment_plan/job_availability_zone_parser.rb +49 -0
  70. data/lib/bosh/director/deployment_plan/job_migrator.rb +90 -0
  71. data/lib/bosh/director/deployment_plan/job_network.rb +42 -0
  72. data/lib/bosh/director/deployment_plan/job_network_parser.rb +118 -0
  73. data/lib/bosh/director/deployment_plan/job_spec_parser.rb +123 -126
  74. data/lib/bosh/director/deployment_plan/links/link.rb +30 -0
  75. data/lib/bosh/director/deployment_plan/links/link_lookup.rb +66 -0
  76. data/lib/bosh/director/deployment_plan/links/link_path.rb +27 -0
  77. data/lib/bosh/director/deployment_plan/links/links_resolver.rb +70 -0
  78. data/lib/bosh/director/deployment_plan/links/template_link.rb +21 -0
  79. data/lib/bosh/director/deployment_plan/manifest_migrator.rb +3 -17
  80. data/lib/bosh/director/deployment_plan/manifest_validator.rb +46 -0
  81. data/lib/bosh/director/deployment_plan/manual_network.rb +70 -97
  82. data/lib/bosh/director/deployment_plan/manual_network_subnet.rb +148 -0
  83. data/lib/bosh/director/deployment_plan/network.rb +50 -39
  84. data/lib/bosh/director/deployment_plan/network_planner.rb +4 -0
  85. data/lib/bosh/director/deployment_plan/network_planner/plan.rb +26 -0
  86. data/lib/bosh/director/deployment_plan/network_planner/planner.rb +21 -0
  87. data/lib/bosh/director/deployment_plan/network_planner/reservation_reconciler.rb +81 -0
  88. data/lib/bosh/director/deployment_plan/network_planner/vip_static_ips_planner.rb +50 -0
  89. data/lib/bosh/director/deployment_plan/network_settings.rb +65 -0
  90. data/lib/bosh/director/deployment_plan/options/skip_drain.rb +7 -0
  91. data/lib/bosh/director/deployment_plan/package_validator.rb +79 -0
  92. data/lib/bosh/director/deployment_plan/placement_planner.rb +8 -0
  93. data/lib/bosh/director/deployment_plan/placement_planner/availability_zone_picker.rb +90 -0
  94. data/lib/bosh/director/deployment_plan/placement_planner/bruteforce_ip_allocation.rb +124 -0
  95. data/lib/bosh/director/deployment_plan/placement_planner/index_assigner.rb +32 -0
  96. data/lib/bosh/director/deployment_plan/placement_planner/networks_to_static_ips.rb +125 -0
  97. data/lib/bosh/director/deployment_plan/placement_planner/placed_desired_instances.rb +40 -0
  98. data/lib/bosh/director/deployment_plan/placement_planner/plan.rb +42 -0
  99. data/lib/bosh/director/deployment_plan/placement_planner/static_ips_availability_zone_picker.rb +237 -0
  100. data/lib/bosh/director/deployment_plan/placement_planner/unplaced_existing_instances.rb +53 -0
  101. data/lib/bosh/director/deployment_plan/planner.rb +186 -74
  102. data/lib/bosh/director/deployment_plan/planner_factory.rb +30 -147
  103. data/lib/bosh/director/deployment_plan/release_version.rb +3 -3
  104. data/lib/bosh/director/deployment_plan/resource_pool.rb +2 -174
  105. data/lib/bosh/director/deployment_plan/stemcell.rb +57 -14
  106. data/lib/bosh/director/deployment_plan/steps/package_compile_step.rb +28 -135
  107. data/lib/bosh/director/deployment_plan/steps/update_step.rb +23 -44
  108. data/lib/bosh/director/deployment_plan/template.rb +15 -4
  109. data/lib/bosh/director/deployment_plan/vip_network.rb +14 -42
  110. data/lib/bosh/director/deployment_plan/vm.rb +1 -99
  111. data/lib/bosh/director/deployment_plan/vm_type.rb +27 -0
  112. data/lib/bosh/director/disk_manager.rb +268 -0
  113. data/lib/bosh/director/dns/canonicalizer.rb +28 -0
  114. data/lib/bosh/director/dns/dns_manager.rb +163 -0
  115. data/lib/bosh/director/dns/local_dns_repo.rb +20 -0
  116. data/lib/bosh/director/dns/powerdns.rb +170 -0
  117. data/lib/bosh/director/errand/job_manager.rb +18 -29
  118. data/lib/bosh/director/error_ignorer.rb +16 -0
  119. data/lib/bosh/director/errors.rb +51 -20
  120. data/lib/bosh/director/event_log.rb +6 -0
  121. data/lib/bosh/director/instance_deleter.rb +53 -81
  122. data/lib/bosh/director/instance_reuser.rb +89 -0
  123. data/lib/bosh/director/instance_updater.rb +139 -281
  124. data/lib/bosh/director/instance_updater/preparer.rb +8 -5
  125. data/lib/bosh/director/instance_updater/state_applier.rb +21 -0
  126. data/lib/bosh/director/ip_util.rb +46 -26
  127. data/lib/bosh/director/job_renderer.rb +22 -10
  128. data/lib/bosh/director/job_runner.rb +1 -4
  129. data/lib/bosh/director/job_updater.rb +47 -35
  130. data/lib/bosh/director/job_updater_factory.rb +5 -4
  131. data/lib/bosh/director/jobs/base_job.rb +8 -0
  132. data/lib/bosh/director/jobs/cleanup_artifacts.rb +93 -0
  133. data/lib/bosh/director/jobs/delete_deployment.rb +10 -154
  134. data/lib/bosh/director/jobs/delete_deployment_snapshots.rb +1 -1
  135. data/lib/bosh/director/jobs/delete_orphan_disks.rb +44 -0
  136. data/lib/bosh/director/jobs/delete_release.rb +19 -196
  137. data/lib/bosh/director/jobs/delete_stemcell.rb +10 -76
  138. data/lib/bosh/director/jobs/export_release.rb +41 -121
  139. data/lib/bosh/director/jobs/fetch_logs.rb +0 -6
  140. data/lib/bosh/director/jobs/helpers.rb +10 -0
  141. data/lib/bosh/director/jobs/helpers/blob_deleter.rb +24 -0
  142. data/lib/bosh/director/jobs/helpers/compiled_package_deleter.rb +24 -0
  143. data/lib/bosh/director/jobs/helpers/name_version_release_deleter.rb +48 -0
  144. data/lib/bosh/director/jobs/helpers/package_deleter.rb +33 -0
  145. data/lib/bosh/director/jobs/helpers/release_deleter.rb +52 -0
  146. data/lib/bosh/director/jobs/helpers/release_version_deleter.rb +115 -0
  147. data/lib/bosh/director/jobs/helpers/releases_to_delete_picker.rb +31 -0
  148. data/lib/bosh/director/jobs/helpers/stemcell_deleter.rb +61 -0
  149. data/lib/bosh/director/jobs/helpers/stemcells_to_delete_picker.rb +30 -0
  150. data/lib/bosh/director/jobs/helpers/template_deleter.rb +20 -0
  151. data/lib/bosh/director/jobs/release/release_job.rb +18 -7
  152. data/lib/bosh/director/jobs/run_errand.rb +57 -36
  153. data/lib/bosh/director/jobs/scheduled_orphan_cleanup.rb +46 -0
  154. data/lib/bosh/director/jobs/ssh.rb +50 -17
  155. data/lib/bosh/director/jobs/update_deployment.rb +29 -11
  156. data/lib/bosh/director/jobs/update_release.rb +25 -4
  157. data/lib/bosh/director/jobs/vm_state.rb +23 -32
  158. data/lib/bosh/director/lock.rb +13 -8
  159. data/lib/bosh/director/logs_fetcher.rb +1 -1
  160. data/lib/bosh/director/models.rb +3 -0
  161. data/lib/bosh/director/models/compiled_package.rb +3 -3
  162. data/lib/bosh/director/models/deployment.rb +10 -0
  163. data/lib/bosh/director/models/instance.rb +77 -1
  164. data/lib/bosh/director/models/ip_address.rb +26 -0
  165. data/lib/bosh/director/models/orphan_disk.rb +23 -0
  166. data/lib/bosh/director/models/orphan_snapshot.rb +14 -0
  167. data/lib/bosh/director/models/template.rb +32 -9
  168. data/lib/bosh/director/models/vm.rb +5 -8
  169. data/lib/bosh/director/network_reservation.rb +69 -99
  170. data/lib/bosh/director/problem_handlers/inactive_disk.rb +5 -20
  171. data/lib/bosh/director/problem_handlers/missing_disk.rb +2 -13
  172. data/lib/bosh/director/problem_resolver.rb +2 -2
  173. data/lib/bosh/director/problem_scanner/vm_scan_stage.rb +2 -21
  174. data/lib/bosh/director/scheduler.rb +23 -6
  175. data/lib/bosh/director/{instance_updater/stopper.rb → stopper.rb} +24 -18
  176. data/lib/bosh/director/tagged_logger.rb +30 -0
  177. data/lib/bosh/director/transactor.rb +9 -0
  178. data/lib/bosh/director/version.rb +1 -1
  179. data/lib/bosh/director/vm_creator.rb +91 -19
  180. data/lib/bosh/director/vm_deleter.rb +25 -0
  181. data/lib/bosh/director/vm_recreator.rb +15 -0
  182. data/lib/cloud/dummy.rb +381 -94
  183. metadata +110 -30
  184. data/lib/bosh/director/deployment_plan/dns_binder.rb +0 -45
  185. data/lib/bosh/director/deployment_plan/instance_vm_binder.rb +0 -37
  186. data/lib/bosh/director/deployment_plan/network_subnet.rb +0 -166
  187. data/lib/bosh/director/deployment_plan/resource_pools.rb +0 -68
  188. data/lib/bosh/director/dns_helper.rb +0 -223
  189. data/lib/bosh/director/instance_updater/network_updater.rb +0 -110
  190. data/lib/bosh/director/instance_updater/vm_updater.rb +0 -189
  191. data/lib/bosh/director/problem_handlers/out_of_sync_vm.rb +0 -64
  192. data/lib/bosh/director/problem_handlers/unbound_instance_vm.rb +0 -85
  193. data/lib/bosh/director/resource_pool_updater.rb +0 -174
  194. data/lib/bosh/director/vm_data.rb +0 -63
  195. data/lib/bosh/director/vm_reuser.rb +0 -63
@@ -0,0 +1,20 @@
1
+ require 'bosh/director/api/controllers/base_controller'
2
+
3
+ module Bosh::Director
4
+ module Api::Controllers
5
+ class DisksController < BaseController
6
+ get '/' do
7
+ content_type(:json)
8
+ orphan_json = @disk_manager.list_orphan_disks
9
+ json_encode(orphan_json)
10
+ end
11
+
12
+ delete '/:orphan_disk_cid' do
13
+ job_queue = JobQueue.new
14
+ task = Bosh::Director::Jobs::DeleteOrphanDisks.enqueue(current_user, [params[:orphan_disk_cid]], job_queue)
15
+
16
+ redirect "/tasks/#{task.id}"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -17,8 +17,8 @@ module Bosh::Director
17
17
  'user_authentication' => @config.identity_provider.client_info,
18
18
  'features' => {
19
19
  'dns' => {
20
- 'status' => Config.dns_enabled?,
21
- 'extras' => {'domain_name' => dns_domain_name}
20
+ 'status' => @dns_manager.dns_enabled?,
21
+ 'extras' => {'domain_name' => @dns_manager.dns_domain_name}
22
22
  },
23
23
  'compiled_package_cache' => {
24
24
  'status' => Config.use_compiled_package_cache?,
@@ -25,22 +25,7 @@ module Bosh::Director
25
25
  end
26
26
 
27
27
  get '/', scope: :read do
28
- releases = Models::Release.order_by(:name.asc).map do |release|
29
- release_versions = release.versions_dataset.order_by(:version.asc).map do |rv|
30
- {
31
- 'version' => rv.version.to_s,
32
- 'commit_hash' => rv.commit_hash,
33
- 'uncommitted_changes' => rv.uncommitted_changes,
34
- 'currently_deployed' => !rv.deployments.empty?,
35
- 'job_names' => rv.templates.map(&:name),
36
- }
37
- end
38
-
39
- {
40
- 'name' => release.name,
41
- 'release_versions' => release_versions,
42
- }
43
- end
28
+ releases = @release_manager.get_all_releases
44
29
 
45
30
  json_encode(releases)
46
31
  end
@@ -23,15 +23,7 @@ module Bosh::Director
23
23
  end
24
24
 
25
25
  get '/', scope: :read do
26
- stemcells = Models::Stemcell.order_by(:name.asc).map do |stemcell|
27
- {
28
- 'name' => stemcell.name,
29
- 'operating_system' => stemcell.operating_system,
30
- 'version' => stemcell.version,
31
- 'cid' => stemcell.cid,
32
- 'deployments' => stemcell.deployments.map { |d| { name: d.name } }
33
- }
34
- end
26
+ stemcells = @stemcell_manager.find_all_stemcells
35
27
  json_encode(stemcells)
36
28
  end
37
29
 
@@ -48,7 +48,8 @@ module Bosh::Director
48
48
  'agent_id' => vm.agent_id,
49
49
  'cid' => vm.cid,
50
50
  'job' => instance ? instance.job : nil,
51
- 'index' => instance ? instance.index : nil
51
+ 'index' => instance ? instance.index : nil,
52
+ 'id' => instance ? instance.uuid : nil
52
53
  }
53
54
  end
54
55
 
@@ -31,6 +31,23 @@ module Bosh::Director
31
31
  instance
32
32
  end
33
33
 
34
+ def by_uuid(deployment_name, job_name, uuid)
35
+ deployment = DeploymentLookup.new.by_name(deployment_name)
36
+
37
+ filter = {
38
+ deployment_id: deployment.id,
39
+ job: job_name,
40
+ uuid: uuid
41
+ }
42
+
43
+ instance = Models::Instance.find(filter)
44
+ if instance.nil?
45
+ raise InstanceNotFound,
46
+ "`#{deployment_name}/#{job_name}/#{uuid}' doesn't exist"
47
+ end
48
+ instance
49
+ end
50
+
34
51
  def by_filter(filter)
35
52
  instances = Models::Instance.filter(filter).all
36
53
  if instances.empty?
@@ -6,14 +6,19 @@ module Bosh::Director
6
6
  # @raise [InstanceNotFound]
7
7
  def find_instance(instance_id)
8
8
  InstanceLookup.new.by_id(instance_id)
9
- end
9
+ end
10
10
 
11
11
  # @param [String] deployment_name Deployment name
12
12
  # @param [String] job Job name
13
- # @param [String] index Job index
13
+ # @param [String] index_or_id Job index or id
14
14
  # @return [Models::Instance]
15
- def find_by_name(deployment_name, job, index)
16
- InstanceLookup.new.by_attributes(deployment_name, job, index)
15
+ def find_by_name(deployment_name, job, index_or_id)
16
+ # This is for backwards compatibility and can be removed when we move to referencing job by instance id only.
17
+ if index_or_id.to_s =~ /^\d+$/
18
+ InstanceLookup.new.by_attributes(deployment_name, job, index_or_id)
19
+ else
20
+ InstanceLookup.new.by_uuid(deployment_name, job, index_or_id)
21
+ end
17
22
  end
18
23
 
19
24
  # @param [Hash] filter Sequel-style DB record filter
@@ -29,23 +34,28 @@ module Bosh::Director
29
34
  vm = instance.vm
30
35
  if vm.nil?
31
36
  raise InstanceVmMissing,
32
- "`#{instance.job}/#{instance.index}' doesn't reference a VM"
37
+ "`#{instance.job}/#{instance.uuid} (#{instance.index})' doesn't reference a VM"
33
38
  end
34
39
 
35
40
  if vm.agent_id.nil?
36
41
  raise VmAgentIdMissing, "VM `#{vm.cid}' doesn't have an agent id"
37
42
  end
38
43
 
39
- AgentClient.with_defaults(vm.agent_id)
44
+ AgentClient.with_vm(vm)
40
45
  end
41
46
 
42
- def fetch_logs(username, deployment_name, job, index, options = {})
43
- if deployment_name.nil? || job.nil? || index.nil?
47
+ def fetch_logs(username, deployment_name, job, index_or_id, options = {})
48
+ if deployment_name.nil? || job.nil? || index_or_id.nil?
44
49
  raise DirectorError,
45
- 'deployment, job and index parameters are required'
50
+ 'deployment, job and index/id parameters are required'
46
51
  end
47
52
 
48
- instance = find_by_name(deployment_name, job, index)
53
+ # This is for backwards compatibility and can be removed when we move to referencing job by instance id only.
54
+ if index_or_id.to_s =~ /^\d+$/
55
+ instance = find_by_name(deployment_name, job, index_or_id)
56
+ else
57
+ instance = filter_by(uuid: index_or_id).first
58
+ end
49
59
 
50
60
  JobQueue.new.enqueue(username, Jobs::FetchLogs, 'fetch logs', [instance.id, options])
51
61
  end
@@ -3,10 +3,34 @@ module Bosh::Director
3
3
  class ReleaseManager
4
4
  include ApiHelper
5
5
 
6
- # Finds release by name
7
- # @param [String] name Release name
8
- # @return [Models::Release]
9
- # @raise [ReleaseNotFound]
6
+ def get_all_releases
7
+ releases = Models::Release.order_by(:name.asc).map do |release|
8
+ sorted_version_tuples = release.versions_dataset.all.map do |version|
9
+ {
10
+ provided: version,
11
+ parsed: Bosh::Common::Version::ReleaseVersion.parse(version.values[:version])
12
+ }
13
+ end.sort_by { |rv| rv[:parsed] }
14
+ release_versions = sorted_version_tuples.map do |version|
15
+ provided = version[:provided]
16
+ {
17
+ 'version' => provided.version.to_s,
18
+ 'commit_hash' => provided.commit_hash,
19
+ 'uncommitted_changes' => provided.uncommitted_changes,
20
+ 'currently_deployed' => !provided.deployments.empty?,
21
+ 'job_names' => provided.templates.map(&:name),
22
+ }
23
+ end
24
+
25
+ {
26
+ 'name' => release.name,
27
+ 'release_versions' => release_versions
28
+ }
29
+ end
30
+
31
+ releases
32
+ end
33
+
10
34
  def find_by_name(name)
11
35
  release = Models::Release[:name => name]
12
36
  if release.nil?
@@ -15,10 +39,6 @@ module Bosh::Director
15
39
  release
16
40
  end
17
41
 
18
- # @param [Models::Release] release Release model
19
- # @param [String] version Release version
20
- # @return [Models::ReleaseVersion] Release version model
21
- # @raise [ReleaseVersionInvalid, ReleaseVersionNotFound]
22
42
  def find_version(release, version)
23
43
  dataset = release.versions_dataset
24
44
 
@@ -1,8 +1,15 @@
1
1
  module Bosh::Director
2
2
  module Api
3
3
  class ResurrectorManager
4
- def set_pause_for_instance(deployment_name, job_name, job_index, desired_state)
5
- instance = InstanceLookup.new.by_attributes(deployment_name, job_name, job_index)
4
+ def set_pause_for_instance(deployment_name, job_name, index_or_id, desired_state)
5
+
6
+ # This is for backwards compatibility and can be removed when we move to referencing job by instance id only.
7
+ if index_or_id.to_s =~ /^\d+$/
8
+ instance = InstanceLookup.new.by_attributes(deployment_name, job_name, index_or_id)
9
+ else
10
+ instance = InstanceLookup.new.by_uuid(deployment_name, job_name, index_or_id)
11
+ end
12
+
6
13
  instance.resurrection_paused = desired_state
7
14
  instance.save
8
15
  end
@@ -11,8 +11,10 @@ module Bosh
11
11
  director_app = Bosh::Director::App.new(@config)
12
12
  controllers = {}
13
13
  controllers['/backups'] = Bosh::Director::Api::Controllers::BackupsController.new(@config)
14
+ controllers['/cleanup'] = Bosh::Director::Api::Controllers::CleanupController.new(@config)
14
15
  controllers['/cloud_configs'] = Bosh::Director::Api::Controllers::CloudConfigsController.new(@config)
15
16
  controllers['/deployments'] = Bosh::Director::Api::Controllers::DeploymentsController.new(@config)
17
+ controllers['/disks'] = Bosh::Director::Api::Controllers::DisksController.new(@config)
16
18
  controllers['/info'] = Bosh::Director::Api::Controllers::InfoController.new(@config)
17
19
  controllers['/locks'] = Bosh::Director::Api::Controllers::LocksController.new(@config)
18
20
  controllers['/packages'] = Bosh::Director::Api::Controllers::PackagesController.new(@config)
@@ -26,11 +26,13 @@ module Bosh::Director
26
26
  snapshot
27
27
  end
28
28
 
29
- def snapshots(deployment, job=nil, index=nil)
29
+ def snapshots(deployment, job=nil, index_or_id=nil)
30
30
  filter = { deployment: deployment }
31
31
  filter[:job] = job if job
32
- filter[:index] = index if index
33
-
32
+ if index_or_id
33
+ filter_key = index_or_id.to_s =~ /^\d+$/ ? :index : :uuid
34
+ filter[filter_key] = index_or_id
35
+ end
34
36
  result = []
35
37
  instances = Models::Instance.filter(filter).all
36
38
 
@@ -40,6 +42,7 @@ module Bosh::Director
40
42
  result << {
41
43
  'job' => instance.job,
42
44
  'index' => instance.index,
45
+ 'uuid' => instance.uuid,
43
46
  'snapshot_cid' => snapshot.snapshot_cid,
44
47
  'created_at' => snapshot.created_at.to_s,
45
48
  'clean' => snapshot.clean
@@ -51,9 +54,10 @@ module Bosh::Director
51
54
  result
52
55
  end
53
56
 
54
- def self.delete_snapshots(snapshots)
57
+ def self.delete_snapshots(snapshots, options={})
58
+ keep_snapshots_in_the_cloud = options.fetch(:keep_snapshots_in_the_cloud, false)
55
59
  snapshots.each do |snapshot|
56
- Config.cloud.delete_snapshot(snapshot.snapshot_cid)
60
+ Config.cloud.delete_snapshot(snapshot.snapshot_cid) unless keep_snapshots_in_the_cloud
57
61
  snapshot.delete
58
62
  end
59
63
  end
@@ -1,4 +1,5 @@
1
1
  require 'securerandom'
2
+ require 'common/version/stemcell_version_list'
2
3
 
3
4
  module Bosh::Director
4
5
  module Api
@@ -14,6 +15,40 @@ module Bosh::Director
14
15
  stemcell
15
16
  end
16
17
 
18
+ def find_all_stemcells
19
+ Models::Stemcell.order_by(:name.asc).map do |stemcell|
20
+ {
21
+ 'name' => stemcell.name,
22
+ 'operating_system' => stemcell.operating_system,
23
+ 'version' => stemcell.version,
24
+ 'cid' => stemcell.cid,
25
+ 'deployments' => stemcell.deployments.map { |d| { name: d.name } }
26
+ }
27
+ end
28
+ end
29
+
30
+ def latest_by_os(os)
31
+ stemcells = Bosh::Director::Models::Stemcell.where(:operating_system => os)
32
+
33
+ if stemcells.nil? || stemcells.empty?
34
+ raise StemcellNotFound,
35
+ "Stemcell with Operating System `#{os}' doesn't exist"
36
+ end
37
+
38
+ find_latest(stemcells)
39
+ end
40
+
41
+ def latest_by_name(name)
42
+ stemcells = Bosh::Director::Models::Stemcell.where(:name => name)
43
+
44
+ if stemcells.nil? || stemcells.empty?
45
+ raise StemcellNotFound,
46
+ "Stemcell `#{name}' doesn't exist"
47
+ end
48
+
49
+ find_latest(stemcells)
50
+ end
51
+
17
52
  def find_by_os_and_version(os, version)
18
53
  stemcell = Bosh::Director::Models::Stemcell.
19
54
  dataset.order(:name)[:operating_system => os, :version => version]
@@ -49,6 +84,21 @@ module Bosh::Director
49
84
 
50
85
  JobQueue.new.enqueue(username, Jobs::DeleteStemcell, description, [stemcell.name, stemcell.version, options])
51
86
  end
87
+
88
+ private
89
+
90
+ def find_latest(stemcells)
91
+ versions = stemcells.map(&:version)
92
+
93
+ latest_version = Bosh::Common::Version::StemcellVersionList.parse(versions).latest.to_s
94
+
95
+ latest_stemcell = stemcells.find do |stemcell|
96
+ parsed_version = Bosh::Common::Version::StemcellVersion.parse(stemcell.version).to_s
97
+ parsed_version == latest_version
98
+ end
99
+
100
+ latest_stemcell
101
+ end
52
102
  end
53
103
  end
54
104
  end
@@ -9,7 +9,7 @@ module Bosh::Director
9
9
  class App
10
10
 
11
11
  class << self
12
- # Some places (ie, resque jobs) need to reference the authoriative app instance
12
+ # Some places (ie, resque jobs) need to reference the authoritative app instance
13
13
  # from class methods.
14
14
  def instance
15
15
  @@instance
@@ -13,46 +13,14 @@ module Bosh::Director
13
13
  # still be pretty generous interval for agent to respond.
14
14
  DEFAULT_AGENT_TIMEOUT = 10
15
15
 
16
- def cloud
17
- Bosh::Director::Config.cloud
18
- end
19
-
20
- def handler_error(message)
21
- raise Bosh::Director::ProblemHandlerError, message
22
- end
23
-
24
- def instance_name(vm)
25
- instance = vm.instance
26
- return "Unknown VM" if instance.nil?
27
-
28
- job = instance.job || "unknown job"
29
- index = instance.index || "unknown index"
30
- "#{job}/#{index}"
31
- end
32
-
33
- def agent_client(vm, timeout = DEFAULT_AGENT_TIMEOUT, retries = 0)
34
- options = {
35
- :timeout => timeout,
36
- :retry_methods => { :get_state => retries }
37
- }
38
- @clients ||= {}
39
- @clients[vm.agent_id] ||= AgentClient.with_defaults(vm.agent_id, options)
40
- end
41
-
42
- def agent_timeout_guard(vm, &block)
43
- yield agent_client(vm)
44
- rescue Bosh::Director::RpcTimeout
45
- handler_error("VM `#{vm.cid}' is not responding")
46
- end
47
-
48
16
  def reboot_vm(vm)
49
17
  cloud.reboot_vm(vm.cid)
50
18
  begin
51
19
  agent_client(vm).wait_until_ready
52
20
  rescue Bosh::Director::RpcTimeout
53
- handler_error("Agent still unresponsive after reboot")
21
+ handler_error('Agent still unresponsive after reboot')
54
22
  rescue Bosh::Director::TaskCancelled
55
- handler_error("Task was cancelled")
23
+ handler_error('Task was cancelled')
56
24
  end
57
25
  end
58
26
 
@@ -60,151 +28,170 @@ module Bosh::Director
60
28
  # Paranoia: don't blindly delete VMs with persistent disk
61
29
  disk_list = agent_timeout_guard(vm) { |agent| agent.list_disk }
62
30
  if disk_list.size != 0
63
- handler_error("VM has persistent disk attached")
31
+ handler_error('VM has persistent disk attached')
64
32
  end
65
33
 
66
- cloud.delete_vm(vm.cid)
67
- vm.db.transaction do
68
- vm.instance.update(:vm => nil) if vm.instance
69
- vm.destroy
70
- end
34
+ vm_deleter.delete_vm(vm)
71
35
  end
72
36
 
73
37
  def delete_vm_reference(vm, options={})
74
38
  if vm.cid && !options[:skip_cid_check]
75
- handler_error("VM has a CID")
39
+ handler_error('VM has a CID')
76
40
  end
77
41
 
78
- vm.db.transaction do
79
- vm.instance.update(:vm => nil) if vm.instance
80
- vm.destroy
81
- end
42
+ vm.destroy
82
43
  end
83
44
 
84
45
  def recreate_vm(vm)
85
- # Best we can do without any feedback from the agent
86
- # is to use the spec persisted in the DB at the time
87
- # of last apply call.
88
- # This method is somewhat similar in its nature to what
89
- # InstanceUpdater is doing in case of the stemcell update,
90
- # however we don't need to handle some advanced scenarios
91
- # such as disk migration.
46
+ @logger.debug("Recreating Vm: #{vm.inspect}")
47
+ unless vm.instance
48
+ handler_error('VM does not have an associated instance')
49
+ end
50
+ instance_model = vm.instance
51
+ vm_env = vm.env
92
52
 
93
- spec = validate_spec(vm)
94
- env = validate_env(vm)
53
+ handler_error("VM doesn't belong to any deployment") unless vm.deployment
54
+ handler_error('Failed to recreate VM without instance') unless vm.instance
95
55
 
96
- resource_pool_spec = spec.fetch("resource_pool", {})
97
- stemcell = find_stemcell(resource_pool_spec.fetch("stemcell", {}))
56
+ validate_spec(vm.instance.spec)
57
+ validate_env(vm.env)
98
58
 
99
- deployment = vm.deployment
100
- handler_error("VM doesn't belong to any deployment") unless deployment
59
+ instance_plan_to_delete = DeploymentPlan::InstancePlan.new(
60
+ existing_instance: instance_model,
61
+ instance: nil,
62
+ desired_instance: nil,
63
+ network_plans: []
64
+ )
101
65
 
102
- instance = vm.instance
103
- disk_cid = instance ? instance.persistent_disk_cid : nil
104
-
105
- # One situation where this handler is actually useful is when
106
- # VM has already been deleted but something failed after that
107
- # and it is still referenced in DB. In that case it makes sense
108
- # to ignore "VM not found" errors in `delete_vm' and let the method
109
- # proceed creating a new VM. Other errors are not forgiven.
110
66
  begin
111
- cloud.delete_vm(vm.cid)
112
- rescue Bosh::Clouds::VMNotFound => e
113
- @logger.warn("VM '#{vm.cid}' might have already been deleted from the cloud")
114
- end
67
+ vm_deleter.delete_for_instance_plan(instance_plan_to_delete)
68
+ rescue Bosh::Clouds::VMNotFound
69
+ # One situation where this handler is actually useful is when
70
+ # VM has already been deleted but something failed after that
71
+ # and it is still referenced in DB. In that case it makes sense
72
+ # to ignore "VM not found" errors in `delete_vm' and let the method
73
+ # proceed creating a new VM. Other errors are not forgiven.
115
74
 
116
- vm.db.transaction do
117
- instance.update(:vm => nil) if instance
118
- vm.destroy
75
+ @logger.warn("VM '#{vm.cid}' might have already been deleted from the cloud")
119
76
  end
120
77
 
121
- cloud_properties = resource_pool_spec.fetch("cloud_properties", {})
122
- networks = spec["networks"]
123
- new_vm = VmCreator.create(deployment, stemcell, cloud_properties, networks, Array(disk_cid), env)
124
- new_vm.apply_spec = spec
125
- new_vm.save
78
+ instance_plan_to_create = create_instance_plan(instance_model, vm_env)
126
79
 
127
- if instance
128
- instance.update(:vm => new_vm)
80
+ vm_creator.create_for_instance_plan(
81
+ instance_plan_to_create,
82
+ Array(instance_model.persistent_disk_cid)
83
+ )
129
84
 
130
- # refresh metadata after new instance has been set
131
- VmMetadataUpdater.build.update(new_vm, {})
132
- end
85
+ dns_manager = DnsManager.create
86
+ dns_names_to_ip = {}
133
87
 
134
- agent_client(new_vm).wait_until_ready
135
-
136
- agent_client(new_vm).update_settings(Bosh::Director::Config.trusted_certs)
137
- new_vm.update(:trusted_certs_sha1 => Digest::SHA1.hexdigest(Bosh::Director::Config.trusted_certs))
138
-
139
- # After this point agent is actually responding to
140
- # pings, so if the rest of this handler fails
141
- # bcck won't find this type of problem again
142
- # but regular deployment will fail with "out-of-sync"
143
- # error (as we now have an instance that points to
144
- # VM that reports empty state). This problem
145
- # should be handled by "out-of-sync VM" problem handler.
146
-
147
- if disk_cid
148
- # N.B. attach_disk might fail if disk image is no longer
149
- # there or for some other reason. Generally it means
150
- # the data has been lost (e.g. someone deleted VM from vCenter
151
- # along with the disk.
152
- cloud.attach_disk(new_vm.cid, disk_cid)
153
- agent_client(new_vm).mount_disk(disk_cid)
88
+ instance_plan_to_create.existing_instance.spec['networks'].each do |network_name, network|
89
+ index_dns_name = dns_manager.dns_record_name(instance_model.index, instance_model.job, network_name, instance_model.deployment.name)
90
+ dns_names_to_ip[index_dns_name] = network['ip']
91
+ id_dns_name = dns_manager.dns_record_name(instance_model.uuid, instance_model.job, network_name, instance_model.deployment.name)
92
+ dns_names_to_ip[id_dns_name] = network['ip']
154
93
  end
155
94
 
156
- agent_client(new_vm).apply(spec)
95
+ @logger.debug("Updating DNS record for instance: #{instance_model.inspect}; to: #{dns_names_to_ip.inspect}")
96
+ dns_manager.update_dns_record_for_instance(instance_model, dns_names_to_ip)
97
+ dns_manager.flush_dns_cache
157
98
 
158
- if instance && instance.state == "started"
159
- agent_client(new_vm).run_script('pre-start', {})
160
- agent_client(new_vm).start
161
- end
99
+ cleaner = RenderedJobTemplatesCleaner.new(instance_model, App.instance.blobstores.blobstore, @logger)
100
+ InstanceUpdater::StateApplier.new(instance_plan_to_create, agent_client(instance_model.vm), cleaner).apply
162
101
  end
163
102
 
164
103
  private
165
104
 
166
- def validate_spec(vm)
167
- handler_error("Unable to look up VM apply spec") unless vm.apply_spec
105
+ def create_instance_plan(instance_model, vm_env)
106
+ vm_type = DeploymentPlan::VmType.new(instance_model.spec['vm_type'])
107
+ env = DeploymentPlan::Env.new(vm_env)
108
+ stemcell = DeploymentPlan::Stemcell.new(instance_model.spec['stemcell'])
109
+ stemcell.add_stemcell_model
110
+ availability_zone = DeploymentPlan::AvailabilityZone.new(instance_model.availability_zone, instance_model.cloud_properties_hash)
111
+
112
+ instance_from_model = DeploymentPlan::Instance.new(
113
+ instance_model.job,
114
+ instance_model.index,
115
+ instance_model.state,
116
+ vm_type,
117
+ stemcell,
118
+ env,
119
+ false,
120
+ instance_model.deployment,
121
+ instance_model.spec,
122
+ availability_zone,
123
+ @logger
124
+ )
125
+ instance_from_model.bind_existing_instance_model(instance_model)
126
+
127
+ DeploymentPlan::ResurrectionInstancePlan.new(
128
+ existing_instance: instance_model,
129
+ instance: instance_from_model,
130
+ desired_instance: DeploymentPlan::DesiredInstance.new,
131
+ recreate_deployment: true
132
+ )
133
+ end
168
134
 
169
- spec = vm.apply_spec
135
+ def cloud
136
+ Bosh::Director::Config.cloud
137
+ end
170
138
 
171
- unless spec.kind_of?(Hash)
172
- handler_error("Invalid apply spec format")
173
- end
139
+ def handler_error(message)
140
+ raise Bosh::Director::ProblemHandlerError, message
141
+ end
142
+
143
+ def instance_name(vm)
144
+ instance = vm.instance
145
+ return "Unknown VM" if instance.nil?
174
146
 
175
- spec
147
+ job = instance.job || "unknown job"
148
+ index = instance.index || "unknown index"
149
+ "#{job}/#{index}"
176
150
  end
177
151
 
178
- def validate_env(vm)
179
- handler_error("Unable to look up VM environment") unless vm.env
152
+ def agent_client(vm, timeout = DEFAULT_AGENT_TIMEOUT, retries = 0)
153
+ options = {
154
+ :timeout => timeout,
155
+ :retry_methods => { :get_state => retries }
156
+ }
157
+ @clients ||= {}
158
+ @clients[vm.agent_id] ||= AgentClient.with_vm(vm, options)
159
+ end
180
160
 
181
- env = vm.env
161
+ def agent_timeout_guard(vm, &block)
162
+ yield agent_client(vm)
163
+ rescue Bosh::Director::RpcTimeout
164
+ handler_error("VM `#{vm.cid}' is not responding")
165
+ end
182
166
 
183
- unless env.kind_of?(Hash)
184
- handler_error("Invalid VM environment format")
185
- end
167
+ def vm_deleter
168
+ @vm_deleter ||= VmDeleter.new(cloud, @logger)
169
+ end
186
170
 
187
- env
171
+ def vm_creator
172
+ disk_manager = DiskManager.new(cloud, @logger)
173
+ job_renderer = JobRenderer.create
174
+ @vm_creator ||= VmCreator.new(cloud, @logger, vm_deleter, disk_manager, job_renderer)
188
175
  end
189
176
 
190
- def find_stemcell(stemcell_spec)
191
- stemcell_name = stemcell_spec['name']
192
- stemcell_version = stemcell_spec['version']
177
+ def validate_spec(spec)
178
+ handler_error('Unable to look up VM apply spec') unless spec
193
179
 
194
- unless stemcell_name && stemcell_version
195
- handler_error('Unknown stemcell name and/or version')
180
+ unless spec.kind_of?(Hash)
181
+ handler_error('Invalid apply spec format')
196
182
  end
183
+ end
197
184
 
198
- stemcell = Models::Stemcell.find(:name => stemcell_name, :version => stemcell_version)
199
-
200
- handler_error("Unable to find stemcell '#{stemcell_name} #{stemcell_version}'") unless stemcell
185
+ def validate_env(env)
186
+ handler_error('Unable to look up VM environment') unless env
201
187
 
202
- stemcell
188
+ unless env.kind_of?(Hash)
189
+ handler_error('Invalid VM environment format')
190
+ end
203
191
  end
204
192
 
205
193
  def generate_agent_id
206
194
  SecureRandom.uuid
207
195
  end
208
-
209
196
  end
210
197
  end