bosh-director 1.5.0.pre.1113
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +34 -0
- data/bin/bosh-director +36 -0
- data/bin/bosh-director-console +84 -0
- data/bin/bosh-director-drain-workers +42 -0
- data/bin/bosh-director-migrate +58 -0
- data/bin/bosh-director-scheduler +27 -0
- data/bin/bosh-director-worker +76 -0
- data/db/migrations/README +1 -0
- data/db/migrations/director/20110209010747_initial.rb +118 -0
- data/db/migrations/director/20110406055800_add_task_user.rb +9 -0
- data/db/migrations/director/20110518225809_remove_cid_constrain.rb +13 -0
- data/db/migrations/director/20110617211923_add_deployments_release_versions.rb +32 -0
- data/db/migrations/director/20110622212607_add_task_checkpoint_timestamp.rb +9 -0
- data/db/migrations/director/20110628023039_add_state_to_instances.rb +21 -0
- data/db/migrations/director/20110709012332_add_disk_size_to_instances.rb +9 -0
- data/db/migrations/director/20110906183441_add_log_bundles.rb +11 -0
- data/db/migrations/director/20110907194830_add_logs_json_to_templates.rb +9 -0
- data/db/migrations/director/20110915205610_add_persistent_disks.rb +51 -0
- data/db/migrations/director/20111005180929_add_properties.rb +14 -0
- data/db/migrations/director/20111110024617_add_deployment_problems.rb +24 -0
- data/db/migrations/director/20111216214145_recreate_support_for_vms.rb +9 -0
- data/db/migrations/director/20120102084027_add_credentials_to_vms.rb +7 -0
- data/db/migrations/director/20120427235217_allow_multiple_releases_per_deployment.rb +36 -0
- data/db/migrations/director/20120524175805_add_task_type.rb +44 -0
- data/db/migrations/director/20120614001930_delete_redundant_deployment_release_relation.rb +34 -0
- data/db/migrations/director/20120822004528_add_fingerprint_to_templates_and_packages.rb +17 -0
- data/db/migrations/director/20120830191244_add_properties_to_templates.rb +9 -0
- data/db/migrations/director/20121106190739_persist_vm_env.rb +9 -0
- data/db/migrations/director/20130222232131_add_sha1_to_stemcells.rb +9 -0
- data/db/migrations/director/20130312211407_add_commit_hash_to_release_versions.rb +19 -0
- data/db/migrations/director/20130409235338_snapshot.rb +15 -0
- data/db/migrations/director/20130530164918_add_paused_flag_to_instance.rb +14 -0
- data/db/migrations/director/20130531172604_add_director_attributes.rb +13 -0
- data/db/migrations/dns/20120123234908_initial.rb +27 -0
- data/lib/bosh/director.rb +133 -0
- data/lib/bosh/director/agent_client.rb +78 -0
- data/lib/bosh/director/api.rb +29 -0
- data/lib/bosh/director/api/api_helper.rb +81 -0
- data/lib/bosh/director/api/backup_manager.rb +15 -0
- data/lib/bosh/director/api/controller.rb +639 -0
- data/lib/bosh/director/api/controller_helpers.rb +34 -0
- data/lib/bosh/director/api/deployment_lookup.rb +13 -0
- data/lib/bosh/director/api/deployment_manager.rb +60 -0
- data/lib/bosh/director/api/http_constants.rb +16 -0
- data/lib/bosh/director/api/instance_lookup.rb +44 -0
- data/lib/bosh/director/api/instance_manager.rb +63 -0
- data/lib/bosh/director/api/problem_manager.rb +40 -0
- data/lib/bosh/director/api/property_manager.rb +69 -0
- data/lib/bosh/director/api/release_manager.rb +59 -0
- data/lib/bosh/director/api/resource_manager.rb +69 -0
- data/lib/bosh/director/api/resurrector_manager.rb +15 -0
- data/lib/bosh/director/api/snapshot_manager.rb +94 -0
- data/lib/bosh/director/api/stemcell_manager.rb +50 -0
- data/lib/bosh/director/api/task_helper.rb +46 -0
- data/lib/bosh/director/api/task_manager.rb +64 -0
- data/lib/bosh/director/api/user_manager.rb +72 -0
- data/lib/bosh/director/api/vm_state_manager.rb +11 -0
- data/lib/bosh/director/app.rb +35 -0
- data/lib/bosh/director/blob_util.rb +87 -0
- data/lib/bosh/director/blobstores.rb +29 -0
- data/lib/bosh/director/client.rb +156 -0
- data/lib/bosh/director/cloudcheck_helper.rb +204 -0
- data/lib/bosh/director/compile_task.rb +157 -0
- data/lib/bosh/director/config.rb +370 -0
- data/lib/bosh/director/configuration_hasher.rb +114 -0
- data/lib/bosh/director/cycle_helper.rb +36 -0
- data/lib/bosh/director/db_backup.rb +22 -0
- data/lib/bosh/director/db_backup/adapter.rb +3 -0
- data/lib/bosh/director/db_backup/adapter/mysql2.rb +27 -0
- data/lib/bosh/director/db_backup/adapter/postgres.rb +36 -0
- data/lib/bosh/director/db_backup/adapter/sqlite.rb +17 -0
- data/lib/bosh/director/db_backup/error.rb +10 -0
- data/lib/bosh/director/deployment_plan.rb +26 -0
- data/lib/bosh/director/deployment_plan/assembler.rb +430 -0
- data/lib/bosh/director/deployment_plan/compilation_config.rb +54 -0
- data/lib/bosh/director/deployment_plan/compiled_package.rb +35 -0
- data/lib/bosh/director/deployment_plan/dynamic_network.rb +91 -0
- data/lib/bosh/director/deployment_plan/idle_vm.rb +109 -0
- data/lib/bosh/director/deployment_plan/instance.rb +413 -0
- data/lib/bosh/director/deployment_plan/job.rb +470 -0
- data/lib/bosh/director/deployment_plan/manual_network.rb +137 -0
- data/lib/bosh/director/deployment_plan/network.rb +74 -0
- data/lib/bosh/director/deployment_plan/network_subnet.rb +167 -0
- data/lib/bosh/director/deployment_plan/planner.rb +288 -0
- data/lib/bosh/director/deployment_plan/preparer.rb +52 -0
- data/lib/bosh/director/deployment_plan/release.rb +126 -0
- data/lib/bosh/director/deployment_plan/resource_pool.rb +143 -0
- data/lib/bosh/director/deployment_plan/resource_pools.rb +68 -0
- data/lib/bosh/director/deployment_plan/stemcell.rb +56 -0
- data/lib/bosh/director/deployment_plan/template.rb +94 -0
- data/lib/bosh/director/deployment_plan/update_config.rb +80 -0
- data/lib/bosh/director/deployment_plan/updater.rb +55 -0
- data/lib/bosh/director/deployment_plan/vip_network.rb +79 -0
- data/lib/bosh/director/dns_helper.rb +204 -0
- data/lib/bosh/director/download_helper.rb +44 -0
- data/lib/bosh/director/duration.rb +36 -0
- data/lib/bosh/director/encryption_helper.rb +10 -0
- data/lib/bosh/director/errors.rb +198 -0
- data/lib/bosh/director/event_log.rb +136 -0
- data/lib/bosh/director/ext.rb +64 -0
- data/lib/bosh/director/hash_string_vals.rb +13 -0
- data/lib/bosh/director/instance_deleter.rb +109 -0
- data/lib/bosh/director/instance_updater.rb +506 -0
- data/lib/bosh/director/ip_util.rb +67 -0
- data/lib/bosh/director/job_queue.rb +16 -0
- data/lib/bosh/director/job_runner.rb +162 -0
- data/lib/bosh/director/job_updater.rb +121 -0
- data/lib/bosh/director/jobs/backup.rb +86 -0
- data/lib/bosh/director/jobs/base_job.rb +66 -0
- data/lib/bosh/director/jobs/cloud_check/apply_resolutions.rb +46 -0
- data/lib/bosh/director/jobs/cloud_check/scan.rb +38 -0
- data/lib/bosh/director/jobs/cloud_check/scan_and_fix.rb +73 -0
- data/lib/bosh/director/jobs/create_snapshot.rb +23 -0
- data/lib/bosh/director/jobs/delete_deployment.rb +183 -0
- data/lib/bosh/director/jobs/delete_deployment_snapshots.rb +34 -0
- data/lib/bosh/director/jobs/delete_release.rb +219 -0
- data/lib/bosh/director/jobs/delete_snapshots.rb +23 -0
- data/lib/bosh/director/jobs/delete_stemcell.rb +102 -0
- data/lib/bosh/director/jobs/fetch_logs.rb +99 -0
- data/lib/bosh/director/jobs/scheduled_backup.rb +38 -0
- data/lib/bosh/director/jobs/snapshot_deployment.rb +61 -0
- data/lib/bosh/director/jobs/snapshot_deployments.rb +23 -0
- data/lib/bosh/director/jobs/snapshot_self.rb +43 -0
- data/lib/bosh/director/jobs/ssh.rb +59 -0
- data/lib/bosh/director/jobs/update_deployment.rb +110 -0
- data/lib/bosh/director/jobs/update_release.rb +672 -0
- data/lib/bosh/director/jobs/update_stemcell.rb +109 -0
- data/lib/bosh/director/jobs/vm_state.rb +89 -0
- data/lib/bosh/director/lock.rb +133 -0
- data/lib/bosh/director/lock_helper.rb +92 -0
- data/lib/bosh/director/models.rb +29 -0
- data/lib/bosh/director/models/compiled_package.rb +33 -0
- data/lib/bosh/director/models/deployment.rb +22 -0
- data/lib/bosh/director/models/deployment_problem.rb +49 -0
- data/lib/bosh/director/models/deployment_property.rb +21 -0
- data/lib/bosh/director/models/director_attribute.rb +9 -0
- data/lib/bosh/director/models/dns.rb +9 -0
- data/lib/bosh/director/models/dns/domain.rb +9 -0
- data/lib/bosh/director/models/dns/record.rb +7 -0
- data/lib/bosh/director/models/helpers/model_helper.rb +7 -0
- data/lib/bosh/director/models/instance.rb +28 -0
- data/lib/bosh/director/models/log_bundle.rb +10 -0
- data/lib/bosh/director/models/package.rb +30 -0
- data/lib/bosh/director/models/persistent_disk.rb +13 -0
- data/lib/bosh/director/models/release.rb +17 -0
- data/lib/bosh/director/models/release_version.rb +16 -0
- data/lib/bosh/director/models/snapshot.rb +13 -0
- data/lib/bosh/director/models/stemcell.rb +18 -0
- data/lib/bosh/director/models/task.rb +10 -0
- data/lib/bosh/director/models/template.rb +44 -0
- data/lib/bosh/director/models/user.rb +11 -0
- data/lib/bosh/director/models/vm.rb +42 -0
- data/lib/bosh/director/nats_rpc.rb +54 -0
- data/lib/bosh/director/network_reservation.rb +121 -0
- data/lib/bosh/director/next_rebase_version.rb +20 -0
- data/lib/bosh/director/package_compiler.rb +423 -0
- data/lib/bosh/director/problem_handlers/base.rb +153 -0
- data/lib/bosh/director/problem_handlers/inactive_disk.rb +112 -0
- data/lib/bosh/director/problem_handlers/invalid_problem.rb +28 -0
- data/lib/bosh/director/problem_handlers/missing_vm.rb +34 -0
- data/lib/bosh/director/problem_handlers/mount_info_mismatch.rb +62 -0
- data/lib/bosh/director/problem_handlers/out_of_sync_vm.rb +64 -0
- data/lib/bosh/director/problem_handlers/unbound_instance_vm.rb +85 -0
- data/lib/bosh/director/problem_handlers/unresponsive_agent.rb +78 -0
- data/lib/bosh/director/problem_resolver.rb +103 -0
- data/lib/bosh/director/problem_scanner.rb +268 -0
- data/lib/bosh/director/resource_pool_updater.rb +216 -0
- data/lib/bosh/director/scheduler.rb +57 -0
- data/lib/bosh/director/sequel.rb +13 -0
- data/lib/bosh/director/tar_gzipper.rb +47 -0
- data/lib/bosh/director/task_result_file.rb +19 -0
- data/lib/bosh/director/thread_pool.rb +8 -0
- data/lib/bosh/director/validation_helper.rb +55 -0
- data/lib/bosh/director/version.rb +7 -0
- data/lib/bosh/director/vm_creator.rb +80 -0
- data/lib/bosh/director/vm_data.rb +63 -0
- data/lib/bosh/director/vm_metadata_updater.rb +29 -0
- data/lib/bosh/director/vm_reuser.rb +63 -0
- data/lib/cloud/dummy.rb +149 -0
- metadata +664 -0
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
|
2
|
+
|
|
3
|
+
require 'common/deep_copy'
|
|
4
|
+
|
|
5
|
+
module Bosh::Director
|
|
6
|
+
module DeploymentPlan
|
|
7
|
+
class Job
|
|
8
|
+
include Bosh::Common::PropertyHelper
|
|
9
|
+
|
|
10
|
+
include IpUtil
|
|
11
|
+
include DnsHelper
|
|
12
|
+
include ValidationHelper
|
|
13
|
+
|
|
14
|
+
# started, stopped and detached are real states
|
|
15
|
+
# (persisting in DB and reflecting target instance state)
|
|
16
|
+
# recreate and restart are two virtual states
|
|
17
|
+
# (both set target instance state to "started" and set
|
|
18
|
+
# appropriate instance spec modifiers)
|
|
19
|
+
VALID_JOB_STATES = %w(started stopped detached recreate restart)
|
|
20
|
+
|
|
21
|
+
# @return [String] Job name
|
|
22
|
+
attr_accessor :name
|
|
23
|
+
|
|
24
|
+
# @return [String] Job canonical name (mostly for DNS)
|
|
25
|
+
attr_accessor :canonical_name
|
|
26
|
+
|
|
27
|
+
# @return [Integer] Persistent disk size (no disk if zero)
|
|
28
|
+
attr_accessor :persistent_disk
|
|
29
|
+
|
|
30
|
+
# @return [DeploymentPlan] Current deployment plan
|
|
31
|
+
attr_accessor :deployment
|
|
32
|
+
|
|
33
|
+
# @return [DeploymentPlan::Release] Release this job belongs to
|
|
34
|
+
attr_accessor :release
|
|
35
|
+
|
|
36
|
+
# @return [DeploymentPlan::ResourcePool] Resource pool this job should
|
|
37
|
+
# be run in
|
|
38
|
+
attr_accessor :resource_pool
|
|
39
|
+
|
|
40
|
+
# @return [DeploymentPlan::Network Job default network
|
|
41
|
+
attr_accessor :default_network
|
|
42
|
+
|
|
43
|
+
# @return [Array<DeploymentPlan::Template] Templates included into the job
|
|
44
|
+
attr_accessor :templates
|
|
45
|
+
|
|
46
|
+
# @return [Hash] Job properties
|
|
47
|
+
attr_accessor :properties
|
|
48
|
+
|
|
49
|
+
# @return [Hash<String, DeploymentPlan::Package] Packages included into
|
|
50
|
+
# this job
|
|
51
|
+
attr_accessor :packages
|
|
52
|
+
|
|
53
|
+
# @return [DeploymentPlan::UpdateConfig] Job update settings
|
|
54
|
+
attr_accessor :update
|
|
55
|
+
|
|
56
|
+
# @return [Array<Models::Instance>] List of excess instance models that
|
|
57
|
+
# are not needed for current deployment
|
|
58
|
+
attr_accessor :unneeded_instances
|
|
59
|
+
|
|
60
|
+
# @return [String] Expected job state
|
|
61
|
+
attr_accessor :state
|
|
62
|
+
|
|
63
|
+
# @return [Hash<Integer, String>] Individual instance expected states
|
|
64
|
+
attr_accessor :instance_states
|
|
65
|
+
|
|
66
|
+
# @return [Exception] Exception that requires job update process to be
|
|
67
|
+
# interrupted
|
|
68
|
+
attr_accessor :halt_exception
|
|
69
|
+
|
|
70
|
+
# @param [Bosh::Director::DeploymentPlan] deployment Deployment plan
|
|
71
|
+
# @param [Hash] job_spec Raw job spec from the deployment manifest
|
|
72
|
+
# @return [Bosh::Director::DeploymentPlan::Job]
|
|
73
|
+
def self.parse(deployment, job_spec)
|
|
74
|
+
job = new(deployment, job_spec)
|
|
75
|
+
job.parse
|
|
76
|
+
job
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# @param [Bosh::Director::DeploymentPlan] deployment Deployment plan
|
|
80
|
+
# @param [Hash] job_spec Raw job spec from the deployment manifest
|
|
81
|
+
def initialize(deployment, job_spec)
|
|
82
|
+
@deployment = deployment
|
|
83
|
+
@job_spec = job_spec
|
|
84
|
+
|
|
85
|
+
@release = nil
|
|
86
|
+
@templates = []
|
|
87
|
+
@all_properties = nil # All properties available to job
|
|
88
|
+
@properties = nil # Actual job properties
|
|
89
|
+
|
|
90
|
+
@error_mutex = Mutex.new
|
|
91
|
+
@packages = {}
|
|
92
|
+
@halt = false
|
|
93
|
+
@unneeded_instances = []
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def parse
|
|
97
|
+
parse_name
|
|
98
|
+
parse_release
|
|
99
|
+
parse_template
|
|
100
|
+
parse_disk
|
|
101
|
+
parse_properties
|
|
102
|
+
parse_resource_pool
|
|
103
|
+
parse_update_config
|
|
104
|
+
parse_instances
|
|
105
|
+
parse_networks
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def self.is_legacy_spec?(job_spec)
|
|
109
|
+
!job_spec.has_key?("templates")
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Takes in a job spec and returns a job spec in the new format, if it
|
|
113
|
+
# needs to be modified. The new format has "templates" key, which is an
|
|
114
|
+
# array with each template's data. This is used for job collocation,
|
|
115
|
+
# specifically for the agent's current job spec when compared to the
|
|
116
|
+
# director's. We only convert their template to a single array entry
|
|
117
|
+
# because it should be impossible for the agent to have a job spec with
|
|
118
|
+
# multiple templates in legacy form.
|
|
119
|
+
def self.convert_from_legacy_spec(job_spec)
|
|
120
|
+
return job_spec if !self.is_legacy_spec?(job_spec)
|
|
121
|
+
template = {
|
|
122
|
+
"name" => job_spec["template"],
|
|
123
|
+
"version" => job_spec["version"],
|
|
124
|
+
"sha1" => job_spec["sha1"],
|
|
125
|
+
"blobstore_id" => job_spec["blobstore_id"]
|
|
126
|
+
}
|
|
127
|
+
job_spec["templates"] = [template]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Returns job spec as a Hash. To be used by all instances of the job to
|
|
131
|
+
# populate agent state.
|
|
132
|
+
# @return [Hash] Hash representation
|
|
133
|
+
def spec
|
|
134
|
+
first_template = @templates[0]
|
|
135
|
+
result = {
|
|
136
|
+
"name" => @name,
|
|
137
|
+
"release" => @release.name,
|
|
138
|
+
"templates" => [],
|
|
139
|
+
# --- Legacy ---
|
|
140
|
+
"template" => first_template.name,
|
|
141
|
+
"version" => first_template.version,
|
|
142
|
+
"sha1" => first_template.sha1,
|
|
143
|
+
"blobstore_id" => first_template.blobstore_id
|
|
144
|
+
}
|
|
145
|
+
if first_template.logs
|
|
146
|
+
result["logs"] = first_template.logs
|
|
147
|
+
end
|
|
148
|
+
# --- /Legacy ---
|
|
149
|
+
|
|
150
|
+
@templates.each do |template|
|
|
151
|
+
template_entry = {
|
|
152
|
+
"name" => template.name,
|
|
153
|
+
"version" => template.version,
|
|
154
|
+
"sha1" => template.sha1,
|
|
155
|
+
"blobstore_id" => template.blobstore_id
|
|
156
|
+
}
|
|
157
|
+
if template.logs
|
|
158
|
+
template_entry["logs"] = template.logs
|
|
159
|
+
end
|
|
160
|
+
result["templates"] << template_entry
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
result
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Returns package specs for all packages in the job indexed by package
|
|
167
|
+
# name. To be used by all instances of the job to populate agent state.
|
|
168
|
+
# @return [Hash<String, Hash>] All package specs indexed by package name
|
|
169
|
+
def package_spec
|
|
170
|
+
result = {}
|
|
171
|
+
@packages.each do |name, package|
|
|
172
|
+
result[name] = package.spec
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
result.select { |name, _| run_time_dependencies.include? name }
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Returns all instances of this job
|
|
179
|
+
# @return [Array<DeploymentPlan::Instance>] All job instances
|
|
180
|
+
def instances
|
|
181
|
+
@instances
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Returns job instance by index
|
|
185
|
+
# @param [Integer] index
|
|
186
|
+
# @return [DeploymentPlan::Instance] index-th instance
|
|
187
|
+
def instance(index)
|
|
188
|
+
@instances[index]
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Returns the state state of job instance by its index
|
|
192
|
+
# @param [Integer] index Instance index
|
|
193
|
+
# @return [String, nil] Instance state (nil if not specified)
|
|
194
|
+
def instance_state(index)
|
|
195
|
+
@instance_states[index] || @state
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Registers compiled package with this job.
|
|
199
|
+
# @param [Models::CompiledPackage] compiled_package_model Compiled package
|
|
200
|
+
# @return [void]
|
|
201
|
+
def use_compiled_package(compiled_package_model)
|
|
202
|
+
compiled_package = CompiledPackage.new(compiled_package_model)
|
|
203
|
+
@packages[compiled_package.name] = compiled_package
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def should_halt?
|
|
207
|
+
@halt
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def record_update_error(error, options = {})
|
|
211
|
+
@error_mutex.synchronize do
|
|
212
|
+
@halt = true
|
|
213
|
+
@halt_exception = error
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def parse_name
|
|
218
|
+
@name = safe_property(@job_spec, "name", :class => String)
|
|
219
|
+
@canonical_name = canonical(@name)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def parse_release
|
|
223
|
+
release_name = safe_property(@job_spec, "release", :class => String,
|
|
224
|
+
:optional => true)
|
|
225
|
+
|
|
226
|
+
if release_name.nil?
|
|
227
|
+
if @deployment.releases.size == 1
|
|
228
|
+
@release = @deployment.releases.first
|
|
229
|
+
else
|
|
230
|
+
raise JobMissingRelease,
|
|
231
|
+
"Cannot tell what release job `#{@name}' supposed to use, please reference an existing release"
|
|
232
|
+
end
|
|
233
|
+
else
|
|
234
|
+
@release = @deployment.release(release_name)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
if @release.nil?
|
|
238
|
+
raise JobUnknownRelease,
|
|
239
|
+
"Job `#{@name}' references an unknown release `#{release_name}'"
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def parse_template
|
|
244
|
+
if @release.nil?
|
|
245
|
+
raise DirectorError, "Cannot parse template before parsing release"
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
template_names = safe_property(@job_spec, "template")
|
|
249
|
+
|
|
250
|
+
if template_names.is_a?(String)
|
|
251
|
+
template_names = Array(template_names)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
unless template_names.is_a?(Array)
|
|
255
|
+
invalid_type("template", "String or Array", template_names)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
template_names.each do |template_name|
|
|
259
|
+
@release.use_template_named(template_name)
|
|
260
|
+
@templates << @release.template(template_name)
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def parse_disk
|
|
265
|
+
@persistent_disk = safe_property(@job_spec, "persistent_disk", :class => Integer, :default => 0)
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def parse_properties
|
|
269
|
+
# Manifest can contain global and per-job properties section
|
|
270
|
+
job_properties = safe_property(@job_spec, "properties", :class => Hash, :optional => true)
|
|
271
|
+
|
|
272
|
+
@all_properties = Bosh::Common::DeepCopy.copy(deployment.properties)
|
|
273
|
+
|
|
274
|
+
if job_properties
|
|
275
|
+
@all_properties.recursive_merge!(job_properties)
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
mappings = safe_property(@job_spec, "property_mappings", :class => Hash, :default => {})
|
|
279
|
+
|
|
280
|
+
mappings.each_pair do |to, from|
|
|
281
|
+
resolved = lookup_property(@all_properties, from)
|
|
282
|
+
|
|
283
|
+
if resolved.nil?
|
|
284
|
+
raise JobInvalidPropertyMapping,
|
|
285
|
+
"Cannot satisfy property mapping `#{to}: #{from}', as `#{from}' is not in deployment properties"
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
@all_properties[to] = resolved
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def parse_resource_pool
|
|
293
|
+
resource_pool_name = safe_property(@job_spec, "resource_pool",
|
|
294
|
+
:class => String)
|
|
295
|
+
@resource_pool = deployment.resource_pool(resource_pool_name)
|
|
296
|
+
if @resource_pool.nil?
|
|
297
|
+
raise JobUnknownResourcePool,
|
|
298
|
+
"Job `#{@name}' references an unknown resource pool `#{resource_pool_name}'"
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def parse_update_config
|
|
303
|
+
update_spec = safe_property(@job_spec, "update",
|
|
304
|
+
:class => Hash, :optional => true)
|
|
305
|
+
@update = UpdateConfig.new(update_spec, @deployment.update)
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def parse_instances
|
|
309
|
+
@instances = []
|
|
310
|
+
@instance_states = {}
|
|
311
|
+
|
|
312
|
+
@state = safe_property(@job_spec, "state",
|
|
313
|
+
:class => String, :optional => true)
|
|
314
|
+
|
|
315
|
+
job_size = safe_property(@job_spec, "instances", :class => Integer)
|
|
316
|
+
|
|
317
|
+
instance_states = safe_property(@job_spec, "instance_states",
|
|
318
|
+
:class => Hash, :default => {})
|
|
319
|
+
|
|
320
|
+
instance_states.each_pair do |index, state|
|
|
321
|
+
begin
|
|
322
|
+
index = Integer(index)
|
|
323
|
+
rescue ArgumentError
|
|
324
|
+
raise JobInvalidInstanceIndex,
|
|
325
|
+
"Invalid job index `#{index}', integer expected"
|
|
326
|
+
end
|
|
327
|
+
unless (0...job_size).include?(index)
|
|
328
|
+
raise JobInvalidInstanceIndex,
|
|
329
|
+
"`#{@name}/#{index}' is outside of (0..#{job_size-1}) range"
|
|
330
|
+
end
|
|
331
|
+
unless VALID_JOB_STATES.include?(state)
|
|
332
|
+
raise JobInvalidInstanceState,
|
|
333
|
+
"Invalid state `#{state}' for `#{@name}/#{index}', valid states are: #{VALID_JOB_STATES.join(", ")}"
|
|
334
|
+
end
|
|
335
|
+
@instance_states[index] = state
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
if @state && !VALID_JOB_STATES.include?(@state)
|
|
339
|
+
raise JobInvalidJobState,
|
|
340
|
+
"Invalid state `#{@state}' for `#{@name}', valid states are: #{VALID_JOB_STATES.join(", ")}"
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
job_size.times do |index|
|
|
344
|
+
@instances[index] = Instance.new(self, index)
|
|
345
|
+
@resource_pool.reserve_capacity(1)
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
def parse_networks
|
|
350
|
+
@default_network = {}
|
|
351
|
+
|
|
352
|
+
network_specs = safe_property(@job_spec, "networks", :class => Array)
|
|
353
|
+
if network_specs.empty?
|
|
354
|
+
raise JobMissingNetwork,
|
|
355
|
+
"Job `#{@name}' must specify at least one network"
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
network_specs.each do |network_spec|
|
|
359
|
+
network_name = safe_property(network_spec, "name", :class => String)
|
|
360
|
+
network = @deployment.network(network_name)
|
|
361
|
+
if network.nil?
|
|
362
|
+
raise JobUnknownNetwork,
|
|
363
|
+
"Job `#{@name}' references an unknown network `#{network_name}'"
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
static_ips = nil
|
|
367
|
+
if network_spec["static_ips"]
|
|
368
|
+
static_ips = []
|
|
369
|
+
each_ip(network_spec["static_ips"]) do |ip|
|
|
370
|
+
static_ips << ip
|
|
371
|
+
end
|
|
372
|
+
if static_ips.size != @instances.size
|
|
373
|
+
raise JobNetworkInstanceIpMismatch,
|
|
374
|
+
"Job `#{@name}' has #{@instances.size} instances but was allocated #{static_ips.size} static IPs"
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
default_network = safe_property(network_spec, "default",
|
|
379
|
+
:class => Array, :optional => true)
|
|
380
|
+
if default_network
|
|
381
|
+
default_network.each do |property|
|
|
382
|
+
unless Network::VALID_DEFAULTS.include?(property)
|
|
383
|
+
raise JobNetworkInvalidDefault,
|
|
384
|
+
"Job `#{@name}' specified an invalid default network property `#{property}', " +
|
|
385
|
+
"valid properties are: " + Network::VALID_DEFAULTS.join(", ")
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
if @default_network[property]
|
|
389
|
+
raise JobNetworkMultipleDefaults,
|
|
390
|
+
"Job `#{@name}' specified more than one network to contain default #{property}"
|
|
391
|
+
else
|
|
392
|
+
@default_network[property] = network_name
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
@instances.each_with_index do |instance, index|
|
|
398
|
+
reservation = NetworkReservation.new
|
|
399
|
+
if static_ips
|
|
400
|
+
reservation.ip = static_ips[index]
|
|
401
|
+
reservation.type = NetworkReservation::STATIC
|
|
402
|
+
else
|
|
403
|
+
reservation.type = NetworkReservation::DYNAMIC
|
|
404
|
+
end
|
|
405
|
+
instance.add_network_reservation(network_name, reservation)
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
if network_specs.size > 1
|
|
410
|
+
missing_default_properties = Network::VALID_DEFAULTS.dup
|
|
411
|
+
@default_network.each_key do |key|
|
|
412
|
+
missing_default_properties.delete(key)
|
|
413
|
+
end
|
|
414
|
+
unless missing_default_properties.empty?
|
|
415
|
+
raise JobNetworkMissingDefault,
|
|
416
|
+
"Job `#{@name}' must specify which network is default for " +
|
|
417
|
+
missing_default_properties.sort.join(", ") + ", since it has more than one network configured"
|
|
418
|
+
end
|
|
419
|
+
else
|
|
420
|
+
# Set the default network to the one and only available network
|
|
421
|
+
# (if not specified already)
|
|
422
|
+
network = safe_property(network_specs[0], "name", :class => String)
|
|
423
|
+
Network::VALID_DEFAULTS.each do |property|
|
|
424
|
+
@default_network[property] ||= network
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
# Extracts only the properties needed by this job. This is decoupled from
|
|
430
|
+
# parsing properties because templates need to be bound to their models
|
|
431
|
+
# before 'bind_properties' is being called (as we persist job template
|
|
432
|
+
# property definitions in DB).
|
|
433
|
+
def bind_properties
|
|
434
|
+
@properties = filter_properties(@all_properties)
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
private
|
|
438
|
+
|
|
439
|
+
# @param [Hash] collection All properties collection
|
|
440
|
+
# @return [Hash] Properties required by templates included in this job
|
|
441
|
+
def filter_properties(collection)
|
|
442
|
+
if @templates.empty?
|
|
443
|
+
raise DirectorError, "Can't extract job properties before parsing job templates"
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
return collection if @templates.none? { |template| template.properties }
|
|
447
|
+
return extract_template_properties(collection) if @templates.all? { |template| template.properties }
|
|
448
|
+
raise JobIncompatibleSpecs, "Job `#{name}' has specs with conflicting property definition styles between" +
|
|
449
|
+
" its job spec templates. This may occur if colocating jobs, one of which has a spec file including" +
|
|
450
|
+
" `properties' and one which doesn't."
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
def extract_template_properties(collection)
|
|
454
|
+
result = {}
|
|
455
|
+
|
|
456
|
+
@templates.each do |template|
|
|
457
|
+
template.properties.each_pair do |name, definition|
|
|
458
|
+
copy_property(result, collection, name, definition["default"])
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
result
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
def run_time_dependencies
|
|
466
|
+
templates.flat_map { |template| template.package_models }.uniq.map(&:name)
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
end
|
|
470
|
+
end
|