Class: Bosh::Director::DeploymentPlan::Job
- Includes:
- Common::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.
-
#canonical_name ⇒ String
Job canonical name (mostly for DNS).
-
#default_network ⇒ DeploymentPlan::Network
Job default network.
-
#deployment ⇒ DeploymentPlan
Current deployment plan.
-
#halt_exception ⇒ Exception
Exception that requires job update process to be interrupted.
-
#instance_states ⇒ Hash<Integer, String>
Individual instance expected states.
-
#instances ⇒ Array<DeploymentPlan::Instance>
All job instances.
-
#lifecycle ⇒ String
Lifecycle profile.
-
#name ⇒ String
Job name.
-
#packages ⇒ Hash<String, DeploymentPlan::Package] Packages included into this job
Hash<String, DeploymentPlan::Package] Packages included into this job.
-
#persistent_disk ⇒ Integer
Persistent disk size (no disk if zero).
-
#properties ⇒ Hash
Job properties.
-
#release ⇒ DeploymentPlan::ReleaseVersion
Release this job belongs to.
-
#resource_pool ⇒ DeploymentPlan::ResourcePool
Resource pool this job should be run in.
-
#state ⇒ String
Expected job state.
-
#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.
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(deployment, job_spec, event_log) ⇒ Bosh::Director::DeploymentPlan::Job
Instance Method Summary collapse
- #bind_instance_networks ⇒ Object
-
#bind_properties ⇒ Object
Extracts only the properties needed by this job.
- #bind_unallocated_vms ⇒ Object
- #can_run_as_errand? ⇒ Boolean
-
#initialize(deployment) ⇒ Job
constructor
A new instance of Job.
-
#instance(index) ⇒ DeploymentPlan::Instance
Returns job instance by index.
-
#instance_state(index) ⇒ String?
Returns the state state of job instance by its index.
-
#package_spec ⇒ Hash<String, Hash>
Returns package specs for all packages in the job indexed by package name.
- #record_update_error(error, options = {}) ⇒ Object
- #should_halt? ⇒ Boolean
-
#spec ⇒ Hash
Returns job spec as a Hash.
- #starts_on_deploy? ⇒ Boolean
-
#use_compiled_package(compiled_package_model) ⇒ void
Registers compiled package with this job.
- #validate_package_names_do_not_collide! ⇒ Object
Constructor Details
#initialize(deployment) ⇒ Job
Returns a new instance of Job.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 85 def initialize(deployment) @deployment = deployment @release = nil @templates = [] @all_properties = nil # All properties available to job @properties = nil # Actual job properties @instances = [] @unneeded_instances = [] @instance_states = {} @error_mutex = Mutex.new @packages = {} @halt = false 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 |
#canonical_name ⇒ String
Returns Job canonical name (mostly for DNS).
25 26 27 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 25 def canonical_name @canonical_name end |
#default_network ⇒ DeploymentPlan::Network
Returns Job default network.
41 42 43 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 41 def default_network @default_network end |
#deployment ⇒ DeploymentPlan
Returns Current deployment plan.
31 32 33 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 31 def deployment @deployment end |
#halt_exception ⇒ Exception
Returns Exception that requires job update process to be interrupted.
71 72 73 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 71 def halt_exception @halt_exception end |
#instance_states ⇒ Hash<Integer, String>
Returns Individual instance expected states.
67 68 69 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 67 def instance_states @instance_states end |
#instances ⇒ Array<DeploymentPlan::Instance>
Returns All job instances.
57 58 59 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 57 def instances @instances end |
#lifecycle ⇒ String
Returns Lifecycle profile.
22 23 24 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 22 def lifecycle @lifecycle end |
#name ⇒ String
Returns Job name.
19 20 21 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 19 def name @name end |
#packages ⇒ Hash<String, DeploymentPlan::Package] Packages included into this job
Returns Hash<String, DeploymentPlan::Package] Packages included into this job.
51 52 53 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 51 def packages @packages end |
#persistent_disk ⇒ Integer
Returns Persistent disk size (no disk if zero).
28 29 30 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 28 def persistent_disk @persistent_disk end |
#properties ⇒ Hash
Returns Job properties.
47 48 49 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 47 def properties @properties end |
#release ⇒ DeploymentPlan::ReleaseVersion
Returns Release this job belongs to.
34 35 36 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 34 def release @release end |
#resource_pool ⇒ DeploymentPlan::ResourcePool
Returns Resource pool this job should be run in.
38 39 40 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 38 def resource_pool @resource_pool end |
#state ⇒ String
Returns Expected job state.
64 65 66 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 64 def state @state end |
#templates ⇒ Array<DeploymentPlan::Template] Templates included into the job
Returns Array<DeploymentPlan::Template] Templates included into the job.
44 45 46 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 44 def templates @templates end |
#unneeded_instances ⇒ Array<Models::Instance>
Returns List of excess instance models that are not needed for current deployment.
61 62 63 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 61 def unneeded_instances @unneeded_instances end |
#update ⇒ DeploymentPlan::UpdateConfig
Returns Job update settings.
54 55 56 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 54 def update @update 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.
113 114 115 116 117 118 119 120 121 122 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 113 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
102 103 104 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 102 def self.is_legacy_spec?(job_spec) !job_spec.has_key?("templates") end |
.parse(deployment, job_spec, event_log) ⇒ Bosh::Director::DeploymentPlan::Job
79 80 81 82 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 79 def self.parse(deployment, job_spec, event_log) parser = JobSpecParser.new(deployment, event_log) parser.parse(job_spec) end |
Instance Method Details
#bind_instance_networks ⇒ Object
248 249 250 251 252 253 254 255 256 257 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 248 def bind_instance_networks instances.each do |instance| instance.network_reservations.each do |net_name, reservation| unless reservation.reserved? network = @deployment.network(net_name) network.reserve!(reservation, "`#{name}/#{instance.index}'") end end end 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).
208 209 210 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 208 def bind_properties @properties = filter_properties(@all_properties) end |
#bind_unallocated_vms ⇒ Object
238 239 240 241 242 243 244 245 246 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 238 def bind_unallocated_vms instances.each do |instance| instance.bind_unallocated_vm # Now that we know every VM has been allocated and # instance models are bound, we can sync the state. instance.sync_state_with_db end end |
#can_run_as_errand? ⇒ Boolean
263 264 265 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 263 def can_run_as_errand? @lifecycle == 'errand' end |
#instance(index) ⇒ DeploymentPlan::Instance
Returns job instance by index
174 175 176 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 174 def instance(index) @instances[index] end |
#instance_state(index) ⇒ String?
Returns the state state of job instance by its index
181 182 183 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 181 def instance_state(index) @instance_states[index] || @state 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.
162 163 164 165 166 167 168 169 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 162 def package_spec result = {} @packages.each do |name, package| result[name] = package.spec end result.select { |name, _| run_time_dependencies.include? name } end |
#record_update_error(error, options = {}) ⇒ Object
197 198 199 200 201 202 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 197 def record_update_error(error, = {}) @error_mutex.synchronize do @halt = true @halt_exception = error end end |
#should_halt? ⇒ Boolean
193 194 195 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 193 def should_halt? @halt end |
#spec ⇒ Hash
Returns job spec as a Hash. To be used by all instances of the job to populate agent state.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 127 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
259 260 261 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 259 def starts_on_deploy? @lifecycle == 'service' end |
#use_compiled_package(compiled_package_model) ⇒ void
This method returns an undefined value.
Registers compiled package with this job.
188 189 190 191 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 188 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
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/bosh/director/deployment_plan/job.rb', line 212 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 |