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,27 @@
1
+ module Bosh::Director
2
+ module DeploymentPlan
3
+ class AvailabilityZone
4
+ extend ValidationHelper
5
+
6
+ def self.parse(availability_zone_spec)
7
+ name = safe_property(availability_zone_spec, "name", class: String)
8
+
9
+ cloud_properties =
10
+ safe_property(availability_zone_spec, "cloud_properties", class: Hash, default: {})
11
+
12
+ new(name, cloud_properties)
13
+ end
14
+
15
+ def initialize(name, cloud_properties)
16
+ @name = name
17
+ @cloud_properties = cloud_properties
18
+ end
19
+
20
+ attr_reader :name, :cloud_properties
21
+
22
+ def inspect
23
+ "az: #{name}"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -3,72 +3,181 @@ module Bosh::Director
3
3
  class CloudManifestParser
4
4
  include ValidationHelper
5
5
 
6
- def initialize(deployment, logger)
7
- @deployment = deployment
6
+ def initialize(logger)
8
7
  @logger = logger
9
8
  end
10
9
 
11
- def parse(cloud_manifest)
12
- @cloud_manifest = cloud_manifest
10
+ def parse(cloud_manifest, global_network_resolver, ip_provider_factory)
11
+ azs = parse_availability_zones(cloud_manifest)
12
+ az_list = CloudPlanner.index_by_name(azs)
13
+ networks = parse_networks(cloud_manifest, global_network_resolver, azs)
14
+ compilation_config = parse_compilation(cloud_manifest, networks, az_list)
15
+ resource_pools = parse_resource_pools(cloud_manifest)
16
+ vm_types = parse_vm_types(cloud_manifest)
17
+ disk_types = parse_disk_types(cloud_manifest)
13
18
 
14
- parse_networks
15
- parse_compilation
16
- parse_resource_pools
17
- parse_disk_pools
18
-
19
- @deployment
19
+ CloudPlanner.new({
20
+ availability_zones_list: az_list,
21
+ networks: networks,
22
+ global_network_resolver: global_network_resolver,
23
+ ip_provider_factory: ip_provider_factory,
24
+ compilation: compilation_config,
25
+ resource_pools: resource_pools,
26
+ vm_types: vm_types,
27
+ disk_types: disk_types,
28
+ logger: @logger,
29
+ })
20
30
  end
21
31
 
22
32
  private
23
33
 
24
- def parse_networks
25
- networks = safe_property(@cloud_manifest, 'networks', :class => Array)
26
- networks.each do |network_spec|
27
- type = safe_property(network_spec, 'type', :class => String,
28
- :default => 'manual')
34
+ def parse_availability_zones(cloud_manifest)
35
+ availability_zones = safe_property(cloud_manifest, 'azs', :class => Array, :optional => true, :default => [])
36
+ parsed_availability_zones = availability_zones.map do |availability_zone|
37
+ AvailabilityZone.parse(availability_zone)
38
+ end
39
+
40
+ duplicates = detect_duplicates(parsed_availability_zones) { |az| az.name }
41
+ unless duplicates.empty?
42
+ raise DeploymentDuplicateAvailabilityZoneName, "Duplicate az name `#{duplicates.first.name}'"
43
+ end
44
+
45
+ parsed_availability_zones
46
+ end
47
+
48
+ def parse_networks(cloud_manifest, global_network_resolver, availability_zones)
49
+ networks = safe_property(cloud_manifest, 'networks', :class => Array)
50
+ if networks.empty?
51
+ raise DeploymentNoNetworks, 'No networks specified'
52
+ end
53
+
54
+ parsed_networks = networks.map do |network_spec|
55
+ type = safe_property(network_spec, 'type', :class => String, :default => 'manual')
29
56
 
30
57
  case type
31
58
  when 'manual'
32
- network = ManualNetwork.new(@deployment, network_spec)
59
+ ManualNetwork.parse(network_spec, availability_zones, global_network_resolver, @logger)
33
60
  when 'dynamic'
34
- network = DynamicNetwork.new(@deployment, network_spec)
61
+ DynamicNetwork.parse(network_spec, availability_zones, @logger)
35
62
  when 'vip'
36
- network = VipNetwork.new(@deployment, network_spec)
63
+ VipNetwork.new(network_spec, @logger)
37
64
  else
38
65
  raise DeploymentInvalidNetworkType,
39
66
  "Invalid network type `#{type}'"
40
67
  end
41
-
42
- @deployment.add_network(network)
43
68
  end
44
69
 
45
- if @deployment.networks.empty?
46
- raise DeploymentNoNetworks, 'No networks specified'
70
+ duplicates = detect_duplicates(parsed_networks) { |network| network.canonical_name }
71
+ unless duplicates.empty?
72
+ raise DeploymentCanonicalNetworkNameTaken, "Invalid network name `#{duplicates.first.name}', canonical name already taken"
47
73
  end
74
+
75
+ parsed_networks
48
76
  end
49
77
 
50
- def parse_compilation
51
- compilation_spec = safe_property(@cloud_manifest, 'compilation', :class => Hash)
52
- @deployment.compilation = CompilationConfig.new(@deployment, compilation_spec)
78
+ def parse_compilation(cloud_manifest, networks, az_list)
79
+ compilation_spec = safe_property(cloud_manifest, 'compilation', :class => Hash)
80
+ config = CompilationConfig.new(compilation_spec, az_list)
81
+
82
+ compilation_network = networks.find { |network| network.name == config.network_name }
83
+ if compilation_network.nil?
84
+ raise CompilationConfigUnknownNetwork,
85
+ "Compilation config references an unknown " +
86
+ "network `#{config.network_name}'"
87
+ end
88
+
89
+ unless compilation_network.has_azs?([config.availability_zone_name])
90
+ raise JobNetworkMissingRequiredAvailabilityZone,
91
+ "Compilation config refers to az '#{config.availability_zone_name}' but network '#{compilation_network.name}' has no matching subnet(s)."
92
+ end
93
+
94
+ config
53
95
  end
54
96
 
55
- def parse_resource_pools
56
- resource_pools = safe_property(@cloud_manifest, 'resource_pools', :class => Array)
57
- resource_pools.each do |rp_spec|
58
- @deployment.add_resource_pool(ResourcePool.new(@deployment, rp_spec, @logger))
97
+ def parse_resource_pools(cloud_manifest)
98
+ resource_pools = safe_property(cloud_manifest, 'resource_pools', :class => Array, optional: true)
99
+
100
+ if resource_pools.nil?
101
+ return {}
59
102
  end
60
103
 
61
- if @deployment.resource_pools.empty?
104
+ if resource_pools.empty?
62
105
  raise DeploymentNoResourcePools, 'No resource_pools specified'
63
106
  end
107
+
108
+ parsed_resource_pools = resource_pools.map do |rp_spec|
109
+ ResourcePool.new(rp_spec)
110
+ end
111
+
112
+ duplicates = detect_duplicates(parsed_resource_pools) { |rp| rp.name }
113
+ unless duplicates.empty?
114
+ raise DeploymentDuplicateResourcePoolName, "Duplicate resource pool name `#{duplicates.first.name}'"
115
+ end
116
+
117
+ parsed_resource_pools
118
+ end
119
+
120
+ def parse_vm_types(cloud_manifest)
121
+ vm_types = safe_property(cloud_manifest, 'vm_types', :class => Array, :optional => true, :default => [])
122
+
123
+ parsed_vm_types = vm_types.map do |vmt_spec|
124
+ VmType.new(vmt_spec)
125
+ end
126
+
127
+ duplicates = detect_duplicates(parsed_vm_types) { |vmt| vmt.name }
128
+ unless duplicates.empty?
129
+ raise DeploymentDuplicateVmTypeName, "Duplicate vm type name `#{duplicates.first.name}'"
130
+ end
131
+
132
+ parsed_vm_types
133
+ end
134
+
135
+
136
+ def parse_disk_types(cloud_manifest)
137
+ disk_pools = safe_property(cloud_manifest, 'disk_pools', :class => Array, :optional => true, :default => [])
138
+ disk_types = safe_property(cloud_manifest, 'disk_types', :class => Array, :optional => true, :default => [])
139
+
140
+ if disk_pools.any? && disk_types.any?
141
+ raise DeploymentInvalidDiskSpecification, "Both 'disk_types' and 'disk_pools' are specified, only one key is allowed. 'disk_pools' key will be DEPRECATED in the future."
142
+ end
143
+
144
+ disk_names = []
145
+
146
+ if disk_pools.any?
147
+ disk_source = 'pool'
148
+ disk_names = disk_pools
149
+ elsif disk_types.any?
150
+ disk_source = 'type'
151
+ disk_names = disk_types
152
+ end
153
+
154
+ parsed_disk_types = disk_names.map do |dp_spec|
155
+ DiskType.parse(dp_spec)
156
+ end
157
+
158
+
159
+ duplicates = detect_duplicates(parsed_disk_types) { |dp| dp.name }
160
+ unless duplicates.empty?
161
+ raise DeploymentDuplicateDiskTypeName, "Duplicate disk #{disk_source} name `#{duplicates.first.name}'"
162
+ end
163
+
164
+ parsed_disk_types
64
165
  end
65
166
 
66
- def parse_disk_pools
67
- disk_pools = safe_property(@cloud_manifest, 'disk_pools', :class => Array, :optional => true)
68
- return if disk_pools.nil?
69
- disk_pools.each do |dp_spec|
70
- @deployment.add_disk_pool(DiskPool.parse(dp_spec))
167
+ def detect_duplicates(collection, &iteratee)
168
+ transformed_elements = Set.new
169
+ duplicated_elements = Set.new
170
+ collection.each do |element|
171
+ transformed = iteratee.call(element)
172
+
173
+ if transformed_elements.include?(transformed)
174
+ duplicated_elements << element
175
+ else
176
+ transformed_elements << transformed
177
+ end
71
178
  end
179
+
180
+ duplicated_elements
72
181
  end
73
182
  end
74
183
  end
@@ -7,15 +7,9 @@ module Bosh::Director
7
7
  class CompilationConfig
8
8
  include ValidationHelper
9
9
 
10
- # @return [DeploymentPlan] associated deployment
11
- attr_accessor :deployment
12
-
13
10
  # @return [Integer] number of worker VMs to use
14
11
  attr_accessor :workers
15
12
 
16
- # @return [DeploymentPlan::Network] network used by compilation workers
17
- attr_accessor :network
18
-
19
13
  # @return [Hash] cloud properties to use when creating VMs. (optional)
20
14
  attr_accessor :cloud_properties
21
15
 
@@ -25,29 +19,37 @@ module Bosh::Director
25
19
  # @return [Bool] if VMs should be reused for compilation tasks. (optional)
26
20
  attr_accessor :reuse_compilation_vms
27
21
 
22
+ attr_reader :network_name
23
+
24
+ attr_reader :availability_zone
25
+
28
26
  # Creates compilation configuration spec from the deployment manifest.
29
27
  # @param [DeploymentPlan] deployment
30
28
  # @param [Hash] compilation_config parsed compilation config YAML section
31
- def initialize(deployment, compilation_config)
32
- @deployment = deployment
33
- @workers = safe_property(compilation_config, "workers", class: Integer, min: 1)
29
+ def initialize(compilation_config, azs_list = {})
30
+ @workers = safe_property(compilation_config, 'workers', class: Integer, min: 1)
34
31
 
35
- network_name = safe_property(compilation_config, "network", class: String)
32
+ @network_name = safe_property(compilation_config, 'network', class: String)
36
33
 
37
34
  @reuse_compilation_vms = safe_property(compilation_config,
38
- "reuse_compilation_vms",
35
+ 'reuse_compilation_vms',
39
36
  class: :boolean,
40
37
  optional: true)
41
38
 
42
- @network = deployment.network(network_name)
43
- if @network.nil?
44
- raise CompilationConfigUnknownNetwork,
45
- "Compilation config references an unknown " +
46
- "network `#{network_name}'"
47
- end
48
39
  @cloud_properties = safe_property(
49
- compilation_config, "cloud_properties", class: Hash, default: {})
50
- @env = safe_property(compilation_config, "env", class: Hash, optional: true, default: {})
40
+ compilation_config, 'cloud_properties', class: Hash, default: {})
41
+ @env = safe_property(compilation_config, 'env', class: Hash, optional: true, default: {})
42
+
43
+ az_name = safe_property(compilation_config, 'az', class: String, optional: true)
44
+ @availability_zone = azs_list[az_name]
45
+ if az_name && !az_name.empty? && @availability_zone.nil?
46
+ raise Bosh::Director::CompilationConfigInvalidAvailabilityZone,
47
+ "Compilation config references unknown az '#{az_name}'. Known azs are: [#{azs_list.keys.join(', ')}]"
48
+ end
49
+ end
50
+
51
+ def availability_zone_name
52
+ @availability_zone.nil? ? nil : @availability_zone.name
51
53
  end
52
54
  end
53
55
  end
@@ -0,0 +1,169 @@
1
+ module Bosh::Director
2
+ module DeploymentPlan
3
+ class CompilationInstancePool
4
+ def initialize(instance_reuser, vm_creator, deployment_plan, logger, instance_deleter)
5
+ @instance_reuser = instance_reuser
6
+ @vm_creator = vm_creator
7
+ @deployment_plan = deployment_plan
8
+ @logger = logger
9
+ @instance_deleter = instance_deleter
10
+ end
11
+
12
+ def with_reused_vm(stemcell)
13
+ begin
14
+ instance = @instance_reuser.get_instance(stemcell)
15
+ if instance.nil?
16
+ instance_plan, instance = create_instance_plan(stemcell)
17
+ configure_instance_plan(instance_plan)
18
+ @instance_reuser.add_in_use_instance(instance_plan.instance, stemcell)
19
+ else
20
+ @logger.info("Reusing compilation VM `#{instance.vm.model.cid}' for stemcell `#{stemcell.model.desc}'")
21
+ end
22
+
23
+ yield instance
24
+
25
+ @instance_reuser.release_instance(instance)
26
+ rescue => e
27
+ unless instance.nil? || instance_plan.nil?
28
+ @instance_reuser.remove_instance(instance)
29
+ delete_instance(instance_plan)
30
+ end
31
+ raise e
32
+ end
33
+ end
34
+
35
+ def with_single_use_vm(stemcell)
36
+ begin
37
+ instance_plan, instance = create_instance_plan(stemcell)
38
+ configure_instance_plan(instance_plan)
39
+ yield instance
40
+ ensure
41
+ delete_instance(instance_plan) unless instance.nil?
42
+ end
43
+ end
44
+
45
+ def delete_instances(number_of_workers)
46
+ ThreadPool.new(:max_threads => number_of_workers).wrap do |pool|
47
+ @instance_reuser.each do |instance|
48
+ pool.process do
49
+ @instance_reuser.remove_instance(instance)
50
+ instance_plan = DeploymentPlan::InstancePlan.new(
51
+ existing_instance: instance.model,
52
+ instance: instance,
53
+ desired_instance: DeploymentPlan::DesiredInstance.new,
54
+ network_plans: []
55
+ )
56
+ delete_instance(instance_plan)
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def delete_instance(instance_plan)
65
+ @instance_deleter.delete_instance_plan(instance_plan, EventLog::NullStage.new)
66
+ end
67
+
68
+ def create_instance_plan(stemcell)
69
+ vm_type = CompilationVmType.new(@deployment_plan.compilation.cloud_properties)
70
+ env = Env.new(@deployment_plan.compilation.env)
71
+
72
+ @compile_job = CompilationJob.new(vm_type, stemcell, env, @deployment_plan.compilation.network_name)
73
+ availability_zone = @deployment_plan.compilation.availability_zone
74
+ instance = Instance.create_from_job(@compile_job, 0, 'started', @deployment_plan.model, {}, availability_zone, @logger)
75
+ instance.bind_new_instance_model
76
+
77
+ compilation_network = @deployment_plan.network(@deployment_plan.compilation.network_name)
78
+ reservation = DesiredNetworkReservation.new_dynamic(instance, compilation_network)
79
+ desired_instance = DeploymentPlan::DesiredInstance.new(@compile_job, nil)
80
+ instance_plan = DeploymentPlan::InstancePlan.new(
81
+ existing_instance: instance.model,
82
+ instance: instance,
83
+ desired_instance: desired_instance,
84
+ network_plans: [DeploymentPlan::NetworkPlanner::Plan.new(reservation: reservation)]
85
+ )
86
+
87
+ @compile_job.add_instance_plans([instance_plan])
88
+
89
+ return instance_plan, instance
90
+ end
91
+
92
+ def configure_instance_plan(instance_plan)
93
+ instance_plan.instance.bind_unallocated_vm
94
+
95
+ @deployment_plan.ip_provider.reserve(instance_plan.network_plans.first.reservation)
96
+ @vm_creator.create_for_instance_plan(instance_plan, [])
97
+ end
98
+ end
99
+
100
+ private
101
+
102
+ class CompilationVmType
103
+ attr_reader :cloud_properties
104
+
105
+ def initialize(cloud_properties)
106
+ @cloud_properties = cloud_properties
107
+ end
108
+
109
+ def spec
110
+ {}
111
+ end
112
+ end
113
+
114
+ class CompilationJob
115
+ attr_reader :vm_type, :stemcell, :env, :name
116
+ attr_reader :instance_plans
117
+
118
+ def initialize(vm_type, stemcell, env, compilation_network_name)
119
+ @vm_type = vm_type
120
+ @stemcell = stemcell
121
+ @env = env
122
+ @network = compilation_network_name
123
+ @name = "compilation-#{SecureRandom.uuid}"
124
+ @instance_plans = []
125
+ end
126
+
127
+ def default_network
128
+ {
129
+ 'dns' => @network,
130
+ 'gateway' => @network
131
+ }
132
+ end
133
+
134
+ def availability_zones
135
+ nil
136
+ end
137
+
138
+ def add_instance_plans(instance_plans)
139
+ @instance_plans = instance_plans
140
+ end
141
+
142
+ def spec
143
+ {
144
+ 'name' => @name
145
+ }
146
+ end
147
+
148
+ def package_spec
149
+ {}
150
+ end
151
+
152
+ def properties
153
+ {}
154
+ end
155
+
156
+ def link_spec
157
+ {}
158
+ end
159
+
160
+ def persistent_disk_type
161
+ nil
162
+ end
163
+
164
+ def compilation?
165
+ true
166
+ end
167
+ end
168
+ end
169
+ end