Class: Bosh::Director::DeploymentPlan::InstanceGroup
- Includes:
- Template::PropertyHelper
- Defined in:
- lib/bosh/director/deployment_plan/instance_group.rb
Constant Summary collapse
- VALID_LIFECYCLE_PROFILES =
%w(service errand)
- DEFAULT_LIFECYCLE_PROFILE =
'service'
- VALID_JOB_STATES =
started, stopped and detached are real states (persisting in DB and reflecting target instance state) recreate and restart are two virtual states (both set target instance state to “started” and set appropriate instance spec modifiers)
%w(started stopped detached recreate restart)
Instance Attribute Summary collapse
-
#all_properties ⇒ Object
Returns the value of attribute all_properties.
-
#availability_zones ⇒ Object
Returns the value of attribute availability_zones.
-
#canonical_name ⇒ String
Job canonical name (mostly for DNS).
-
#default_network ⇒ Object
Returns the value of attribute default_network.
-
#desired_instances ⇒ Object
Returns the value of attribute desired_instances.
-
#did_change ⇒ Object
Returns the value of attribute did_change.
- #env ⇒ DeploymentPlan::Env
-
#instance_states ⇒ Hash<Integer, String>
Individual instance expected states.
-
#instances ⇒ Object
to preserve interface for UpdateStep – switch to instance_plans eventually.
-
#lifecycle ⇒ String
Lifecycle profile.
-
#link_paths ⇒ Object
readonly
Returns the value of attribute link_paths.
-
#migrated_from ⇒ Object
Returns the value of attribute migrated_from.
-
#name ⇒ String
Job name.
-
#networks ⇒ Object
Returns the value of attribute networks.
-
#packages ⇒ Hash<String, DeploymentPlan::Package] Packages included into this job
Hash<String, DeploymentPlan::Package] Packages included into this job.
-
#persistent_disk_type ⇒ DiskType
Persistent disk type (or nil).
-
#properties ⇒ Hash
Job properties.
-
#release ⇒ DeploymentPlan::ReleaseVersion
Release this job belongs to.
-
#state ⇒ String
Expected job state.
- #stemcell ⇒ DeploymentPlan::Stemcell
-
#templates ⇒ Array<DeploymentPlan::Template] Templates included into the job
Array<DeploymentPlan::Template] Templates included into the job.
-
#unneeded_instances ⇒ Array<Models::Instance>
List of excess instance models that are not needed for current deployment.
-
#update ⇒ DeploymentPlan::UpdateConfig
Job update settings.
- #vm_extensions ⇒ DeploymentPlan::VmExtension
- #vm_type ⇒ DeploymentPlan::VmType
Class Method Summary collapse
-
.convert_from_legacy_spec(job_spec) ⇒ Object
Takes in a job spec and returns a job spec in the new format, if it needs to be modified.
- .is_legacy_spec?(job_spec) ⇒ Boolean
- .parse(plan, job_spec, event_log, logger, parse_options = {}) ⇒ Object
Instance Method Summary collapse
- #add_instance_plans(instance_plans) ⇒ Object
- #add_link_path(template_name, link_name, link_path) ⇒ Object
- #add_resolved_link(link_name, link_spec) ⇒ Object
-
#bind_instance_networks(ip_provider) ⇒ Object
TODO: Job should not be responsible for reserving IPs.
- #bind_instances(ip_provider) ⇒ Object
-
#bind_properties ⇒ Object
Extracts only the properties needed by this job.
- #compilation? ⇒ Boolean
- #has_network?(network_name) ⇒ Boolean
-
#initialize(logger) ⇒ InstanceGroup
constructor
A new instance of InstanceGroup.
- #instance(index) ⇒ Object
- #instance_plans_with_missing_vms ⇒ Object
- #is_errand? ⇒ Boolean
- #is_service? ⇒ Boolean
- #link_path(template_name, link_name) ⇒ Object
- #link_spec ⇒ Object
- #needed_instance_plans ⇒ Object
- #obsolete_instance_plans ⇒ Object
-
#package_spec ⇒ Hash<String, Hash>
Returns package specs for all packages in the job indexed by package name.
-
#persistent_disk=(disk_size) ⇒ Object
reverse compatibility: translate disk size into a disk pool.
- #sorted_instance_plans ⇒ Object
-
#spec ⇒ Hash
Returns job spec as a Hash.
-
#state_for_instance(instance_model) ⇒ String?
Returns the state state of job instance by its index.
- #update_spec ⇒ Object
-
#use_compiled_package(compiled_package_model) ⇒ void
Registers compiled package with this job.
- #validate_package_names_do_not_collide! ⇒ Object
Constructor Details
#initialize(logger) ⇒ InstanceGroup
Returns a new instance of InstanceGroup.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 93 def initialize(logger) @logger = logger @release = nil @templates = [] @all_properties = nil # All properties available to job @properties = nil # Actual job properties @instances = [] @desired_instances = [] @unneeded_instances = [] @instance_states = {} @default_network = {} @packages = {} @link_paths = {} @resolved_links = {} @migrated_from = [] @availability_zones = [] @instance_plans = [] @did_change = false end |
Instance Attribute Details
#all_properties ⇒ Object
Returns the value of attribute all_properties.
76 77 78 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 76 def all_properties @all_properties end |
#availability_zones ⇒ Object
Returns the value of attribute availability_zones.
74 75 76 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 74 def availability_zones @availability_zones end |
#canonical_name ⇒ String
Returns Job canonical name (mostly for DNS).
26 27 28 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 26 def canonical_name @canonical_name end |
#default_network ⇒ Object
Returns the value of attribute default_network.
46 47 48 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 46 def default_network @default_network end |
#desired_instances ⇒ Object
Returns the value of attribute desired_instances.
82 83 84 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 82 def desired_instances @desired_instances end |
#did_change ⇒ Object
Returns the value of attribute did_change.
86 87 88 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 86 def did_change @did_change end |
#env ⇒ DeploymentPlan::Env
44 45 46 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 44 def env @env end |
#instance_states ⇒ Hash<Integer, String>
Returns Individual instance expected states.
72 73 74 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 72 def instance_states @instance_states end |
#instances ⇒ Object
to preserve interface for UpdateStep – switch to instance_plans eventually
62 63 64 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 62 def instances @instances end |
#lifecycle ⇒ String
Returns Lifecycle profile.
23 24 25 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 23 def lifecycle @lifecycle end |
#link_paths ⇒ Object (readonly)
Returns the value of attribute link_paths.
84 85 86 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 84 def link_paths @link_paths end |
#migrated_from ⇒ Object
Returns the value of attribute migrated_from.
80 81 82 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 80 def migrated_from @migrated_from end |
#name ⇒ String
Returns Job name.
20 21 22 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 20 def name @name end |
#networks ⇒ Object
Returns the value of attribute networks.
78 79 80 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 78 def networks @networks end |
#packages ⇒ Hash<String, DeploymentPlan::Package] Packages included into this job
Returns Hash<String, DeploymentPlan::Package] Packages included into this job.
56 57 58 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 56 def packages @packages end |
#persistent_disk_type ⇒ DiskType
Returns Persistent disk type (or nil).
29 30 31 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 29 def persistent_disk_type @persistent_disk_type end |
#properties ⇒ Hash
Returns Job properties.
52 53 54 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 52 def properties @properties end |
#release ⇒ DeploymentPlan::ReleaseVersion
Returns Release this job belongs to.
32 33 34 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 32 def release @release end |
#state ⇒ String
Returns Expected job state.
69 70 71 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 69 def state @state end |
#stemcell ⇒ DeploymentPlan::Stemcell
35 36 37 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 35 def stemcell @stemcell end |
#templates ⇒ Array<DeploymentPlan::Template] Templates included into the job
Returns Array<DeploymentPlan::Template] Templates included into the job.
49 50 51 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 49 def templates @templates end |
#unneeded_instances ⇒ Array<Models::Instance>
Returns List of excess instance models that are not needed for current deployment.
66 67 68 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 66 def unneeded_instances @unneeded_instances end |
#update ⇒ DeploymentPlan::UpdateConfig
Returns Job update settings.
59 60 61 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 59 def update @update end |
#vm_extensions ⇒ DeploymentPlan::VmExtension
41 42 43 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 41 def vm_extensions @vm_extensions end |
#vm_type ⇒ DeploymentPlan::VmType
38 39 40 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 38 def vm_type @vm_type end |
Class Method Details
.convert_from_legacy_spec(job_spec) ⇒ Object
Takes in a job spec and returns a job spec in the new format, if it needs to be modified. The new format has “templates” key, which is an array with each template’s data. This is used for job collocation, specifically for the agent’s current job spec when compared to the director’s. We only convert their template to a single array entry because it should be impossible for the agent to have a job spec with multiple templates in legacy form.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 138 def self.convert_from_legacy_spec(job_spec) return job_spec if !self.is_legacy_spec?(job_spec) template = { "name" => job_spec["template"], "version" => job_spec["version"], "sha1" => job_spec["sha1"], "blobstore_id" => job_spec["blobstore_id"] } # Supporting 'template_scoped_properties' for legacy spec is going to be messy. # So we will support this feature if a user want to use legacy spec. If they # want to use properties per template, let them use the regular way of defining # templates, i.e. by using the 'templates' key job_spec['templates'] = [template] end |
.is_legacy_spec?(job_spec) ⇒ Boolean
118 119 120 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 118 def self.is_legacy_spec?(job_spec) !job_spec.has_key?("templates") end |
.parse(plan, job_spec, event_log, logger, parse_options = {}) ⇒ Object
88 89 90 91 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 88 def self.parse(plan, job_spec, event_log, logger, = {}) parser = InstanceGroupSpecParser.new(plan, event_log, logger) parser.parse(job_spec, ) end |
Instance Method Details
#add_instance_plans(instance_plans) ⇒ Object
122 123 124 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 122 def add_instance_plans(instance_plans) @instance_plans = instance_plans end |
#add_link_path(template_name, link_name, link_path) ⇒ Object
332 333 334 335 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 332 def add_link_path(template_name, link_name, link_path) @link_paths[template_name] ||= {} @link_paths[template_name][link_name] = link_path end |
#add_resolved_link(link_name, link_spec) ⇒ Object
320 321 322 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 320 def add_resolved_link(link_name, link_spec) @resolved_links[link_name] = link_spec end |
#bind_instance_networks(ip_provider) ⇒ Object
TODO: Job should not be responsible for reserving IPs. Consider moving this somewhere else? Maybe in the consumer?
284 285 286 287 288 289 290 291 292 293 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 284 def bind_instance_networks(ip_provider) needed_instance_plans .flat_map(&:network_plans) .reject(&:obsolete?) .reject(&:existing?) .each do |network_plan| reservation = network_plan.reservation ip_provider.reserve(reservation) end end |
#bind_instances(ip_provider) ⇒ Object
278 279 280 281 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 278 def bind_instances(ip_provider) instances.each(&:ensure_model_bound) bind_instance_networks(ip_provider) end |
#bind_properties ⇒ Object
Extracts only the properties needed by this job. This is decoupled from parsing properties because templates need to be bound to their models before ‘bind_properties’ is being called (as we persist job template property definitions in DB).
248 249 250 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 248 def bind_properties @properties = filter_properties(@all_properties) end |
#compilation? ⇒ Boolean
337 338 339 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 337 def compilation? false end |
#has_network?(network_name) ⇒ Boolean
295 296 297 298 299 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 295 def has_network?(network_name) networks.any? do |network| network.name == network_name end end |
#instance(index) ⇒ Object
225 226 227 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 225 def instance(index) @instances[index] end |
#instance_plans_with_missing_vms ⇒ Object
314 315 316 317 318 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 314 def instance_plans_with_missing_vms needed_instance_plans.reject do |instance_plan| instance_plan.instance.vm_created? || instance_plan.instance.state == 'detached' end end |
#is_errand? ⇒ Boolean
305 306 307 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 305 def is_errand? @lifecycle == 'errand' end |
#is_service? ⇒ Boolean
301 302 303 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 301 def is_service? @lifecycle == 'service' end |
#link_path(template_name, link_name) ⇒ Object
328 329 330 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 328 def link_path(template_name, link_name) @link_paths.fetch(template_name, {})[link_name] end |
#link_spec ⇒ Object
324 325 326 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 324 def link_spec @resolved_links end |
#needed_instance_plans ⇒ Object
163 164 165 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 163 def needed_instance_plans sorted_instance_plans end |
#obsolete_instance_plans ⇒ Object
155 156 157 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 155 def obsolete_instance_plans @instance_plans.select(&:obsolete?) end |
#package_spec ⇒ Hash<String, Hash>
Returns package specs for all packages in the job indexed by package name. To be used by all instances of the job to populate agent state.
216 217 218 219 220 221 222 223 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 216 def package_spec result = {} @packages.each do |name, package| result[name] = package.spec end result.select { |name, _| run_time_dependencies.include? name } end |
#persistent_disk=(disk_size) ⇒ Object
reverse compatibility: translate disk size into a disk pool
310 311 312 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 310 def persistent_disk=(disk_size) @persistent_disk_type = DiskType.new(SecureRandom.uuid, disk_size, {}) end |
#sorted_instance_plans ⇒ Object
126 127 128 129 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 126 def sorted_instance_plans @sorted_instance_plans ||= InstancePlanSorter.new(@logger) .sort(@instance_plans.reject(&:obsolete?)) end |
#spec ⇒ Hash
Returns job spec as a Hash. To be used by all instances of the job to populate agent state.
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 174 def spec if @templates.size >= 1 first_template = @templates[0] result = { "name" => @name, "templates" => [], # --- Legacy --- "template" => first_template.name, "version" => first_template.version, "sha1" => first_template.sha1, "blobstore_id" => first_template.blobstore_id } if first_template.logs result["logs"] = first_template.logs end # --- /Legacy --- @templates.each do |template| template_entry = { "name" => template.name, "version" => template.version, "sha1" => template.sha1, "blobstore_id" => template.blobstore_id } if template.logs template_entry["logs"] = template.logs end result["templates"] << template_entry end result end end |
#state_for_instance(instance_model) ⇒ String?
Returns the state state of job instance by its index
232 233 234 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 232 def state_for_instance(instance_model) @instance_states[instance_model.uuid] || @instance_states[instance_model.index.to_s] || @state end |
#update_spec ⇒ Object
209 210 211 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 209 def update_spec update.to_hash end |
#use_compiled_package(compiled_package_model) ⇒ void
This method returns an undefined value.
Registers compiled package with this job.
239 240 241 242 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 239 def use_compiled_package(compiled_package_model) compiled_package = CompiledPackage.new(compiled_package_model) @packages[compiled_package.name] = compiled_package end |
#validate_package_names_do_not_collide! ⇒ Object
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/bosh/director/deployment_plan/instance_group.rb', line 252 def validate_package_names_do_not_collide! releases_by_package_names = templates .reduce([]) { |memo, t| memo + t.model.package_names.product([t.release]) } .reduce({}) { |memo, package_name_and_release_version| package_name = package_name_and_release_version.first release_version = package_name_and_release_version.last memo[package_name] ||= Set.new memo[package_name] << release_version memo } releases_by_package_names.each do |package_name, releases| if releases.size > 1 release1, release2 = releases.to_a[0..1] offending_template1 = templates.find { |t| t.release == release1 } offending_template2 = templates.find { |t| t.release == release2 } raise JobPackageCollision, "Package name collision detected in instance group '#{@name}': "\ "job '#{release1.name}/#{offending_template1.name}' depends on package '#{release1.name}/#{package_name}', "\ "job '#{release2.name}/#{offending_template2.name}' depends on '#{release2.name}/#{package_name}'. " + 'BOSH cannot currently collocate two packages with identical names from separate releases.' end end end |