Class: Bosh::Director::DeploymentPlan::Job
- Includes:
- Template::PropertyHelper
- Defined in:
- lib/bosh/director/deployment_plan/job.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.
- #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_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) ⇒ 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.
- #can_run_as_errand? ⇒ Boolean
- #compilation? ⇒ Boolean
-
#initialize(logger) ⇒ Job
constructor
A new instance of Job.
- #instance(index) ⇒ Object
- #instance_plans_with_missing_vms ⇒ Object
- #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.
- #starts_on_deploy? ⇒ Boolean
-
#state_for_instance(instance_model) ⇒ String?
Returns the state state of job instance by its index.
-
#use_compiled_package(compiled_package_model) ⇒ void
Registers compiled package with this job.
- #validate_package_names_do_not_collide! ⇒ Object
Constructor Details
#initialize(logger) ⇒ Job
Returns a new instance of Job.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 88 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 = [] end |
Instance Attribute Details
#all_properties ⇒ Object
Returns the value of attribute all_properties.
73 74 75 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 73 def all_properties @all_properties end |
#availability_zones ⇒ Object
Returns the value of attribute availability_zones.
71 72 73 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 71 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/job.rb', line 26 def canonical_name @canonical_name end |
#default_network ⇒ Object
Returns the value of attribute default_network.
43 44 45 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 43 def default_network @default_network end |
#desired_instances ⇒ Object
Returns the value of attribute desired_instances.
79 80 81 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 79 def desired_instances @desired_instances end |
#env ⇒ DeploymentPlan::Env
41 42 43 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 41 def env @env end |
#instance_states ⇒ Hash<Integer, String>
Returns Individual instance expected states.
69 70 71 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 69 def instance_states @instance_states end |
#instances ⇒ Object
to preserve interface for UpdateStep – switch to instance_plans eventually
59 60 61 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 59 def instances @instances end |
#lifecycle ⇒ String
Returns Lifecycle profile.
23 24 25 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 23 def lifecycle @lifecycle end |
#link_paths ⇒ Object (readonly)
Returns the value of attribute link_paths.
81 82 83 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 81 def link_paths @link_paths end |
#migrated_from ⇒ Object
Returns the value of attribute migrated_from.
77 78 79 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 77 def migrated_from @migrated_from end |
#name ⇒ String
Returns Job name.
20 21 22 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 20 def name @name end |
#networks ⇒ Object
Returns the value of attribute networks.
75 76 77 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 75 def networks @networks end |
#packages ⇒ Hash<String, DeploymentPlan::Package] Packages included into this job
Returns Hash<String, DeploymentPlan::Package] Packages included into this job.
53 54 55 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 53 def packages @packages end |
#persistent_disk_type ⇒ DiskType
Returns Persistent disk type (or nil).
29 30 31 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 29 def persistent_disk_type @persistent_disk_type end |
#properties ⇒ Hash
Returns Job properties.
49 50 51 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 49 def properties @properties end |
#release ⇒ DeploymentPlan::ReleaseVersion
Returns Release this job belongs to.
32 33 34 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 32 def release @release end |
#state ⇒ String
Returns Expected job state.
66 67 68 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 66 def state @state end |
#stemcell ⇒ DeploymentPlan::Stemcell
35 36 37 |
# File 'lib/bosh/director/deployment_plan/job.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.
46 47 48 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 46 def templates @templates end |
#unneeded_instances ⇒ Array<Models::Instance>
Returns List of excess instance models that are not needed for current deployment.
63 64 65 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 63 def unneeded_instances @unneeded_instances end |
#update ⇒ DeploymentPlan::UpdateConfig
Returns Job update settings.
56 57 58 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 56 def update @update end |
#vm_type ⇒ DeploymentPlan::VmType
38 39 40 |
# File 'lib/bosh/director/deployment_plan/job.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.
131 132 133 134 135 136 137 138 139 140 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 131 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"] } job_spec["templates"] = [template] end |
.is_legacy_spec?(job_spec) ⇒ Boolean
111 112 113 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 111 def self.is_legacy_spec?(job_spec) !job_spec.has_key?("templates") end |
.parse(plan, job_spec, event_log, logger) ⇒ Object
83 84 85 86 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 83 def self.parse(plan, job_spec, event_log, logger) parser = JobSpecParser.new(plan, event_log, logger) parser.parse(job_spec) end |
Instance Method Details
#add_instance_plans(instance_plans) ⇒ Object
115 116 117 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 115 def add_instance_plans(instance_plans) @instance_plans = instance_plans end |
#add_link_path(template_name, link_name, link_path) ⇒ Object
307 308 309 310 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 307 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
295 296 297 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 295 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?
265 266 267 268 269 270 271 272 273 274 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 265 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
259 260 261 262 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 259 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).
229 230 231 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 229 def bind_properties @properties = filter_properties(@all_properties) end |
#can_run_as_errand? ⇒ Boolean
280 281 282 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 280 def can_run_as_errand? @lifecycle == 'errand' end |
#compilation? ⇒ Boolean
312 313 314 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 312 def compilation? false end |
#instance(index) ⇒ Object
206 207 208 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 206 def instance(index) @instances[index] end |
#instance_plans_with_missing_vms ⇒ Object
289 290 291 292 293 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 289 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 |
#link_path(template_name, link_name) ⇒ Object
303 304 305 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 303 def link_path(template_name, link_name) @link_paths.fetch(template_name, {})[link_name] end |
#link_spec ⇒ Object
299 300 301 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 299 def link_spec @resolved_links end |
#needed_instance_plans ⇒ Object
151 152 153 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 151 def needed_instance_plans sorted_instance_plans end |
#obsolete_instance_plans ⇒ Object
143 144 145 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 143 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.
197 198 199 200 201 202 203 204 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 197 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
285 286 287 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 285 def persistent_disk=(disk_size) @persistent_disk_type = DiskType.new(SecureRandom.uuid, disk_size, {}) end |
#sorted_instance_plans ⇒ Object
119 120 121 122 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 119 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.
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 162 def spec 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 |
#starts_on_deploy? ⇒ Boolean
276 277 278 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 276 def starts_on_deploy? @lifecycle == 'service' end |
#state_for_instance(instance_model) ⇒ String?
Returns the state state of job instance by its index
213 214 215 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 213 def state_for_instance(instance_model) @instance_states[instance_model.uuid] || @instance_states[instance_model.index.to_s] || @state end |
#use_compiled_package(compiled_package_model) ⇒ void
This method returns an undefined value.
Registers compiled package with this job.
220 221 222 223 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 220 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
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 233 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 job `#{@name}': "\ "template `#{release1.name}/#{offending_template1.name}' depends on package `#{release1.name}/#{package_name}', "\ "template `#{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 |