bosh-director 1.3184.1.0 → 1.3189.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/bosh/director.rb +1 -0
- data/lib/bosh/director/api/controllers/disks_controller.rb +8 -0
- data/lib/bosh/director/api/controllers/tasks_controller.rb +1 -0
- data/lib/bosh/director/cloudcheck_helper.rb +16 -23
- data/lib/bosh/director/deployment_plan/job_spec_parser.rb +29 -26
- data/lib/bosh/director/disk_manager.rb +42 -32
- data/lib/bosh/director/dns/powerdns.rb +19 -56
- data/lib/bosh/director/errors.rb +4 -1
- data/lib/bosh/director/jobs/attach_disk.rb +47 -0
- data/lib/bosh/director/manifest/diff_lines.rb +6 -1
- data/lib/bosh/director/version.rb +1 -1
- data/lib/cloud/dummy.rb +10 -4
- metadata +27 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 905be5da3a96e10ebf3cfb7db382e8c796aa3bd9
|
4
|
+
data.tar.gz: 21ed2f9157ef126907fd81fb43aec8c53baa287d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23a1227b08905d82d4b7c4e31c88933d9d0c602fccb14494a94e9bd3359f9ed197365396353c789de83a2663bb1ebc86418af2d62962ea5a62cd2a680acb6d93
|
7
|
+
data.tar.gz: 7af6e69ee09250ddb16b2c31cba4e5172f5cb822793a435203a5f55b1ec2e19d3fdb114a4fc44714888c7ce9626f68e933421df2a5d4b8f9bf6453238a8ef932
|
data/lib/bosh/director.rb
CHANGED
@@ -135,6 +135,7 @@ require 'bosh/director/jobs/cloud_check/scan_and_fix'
|
|
135
135
|
require 'bosh/director/jobs/cloud_check/apply_resolutions'
|
136
136
|
require 'bosh/director/jobs/release/release_job'
|
137
137
|
require 'bosh/director/jobs/ssh'
|
138
|
+
require 'bosh/director/jobs/attach_disk'
|
138
139
|
require 'bosh/director/jobs/helpers'
|
139
140
|
|
140
141
|
require 'bosh/director/models/helpers/model_helper'
|
@@ -9,6 +9,14 @@ module Bosh::Director
|
|
9
9
|
json_encode(orphan_json)
|
10
10
|
end
|
11
11
|
|
12
|
+
# PUT /disks/disk_cid/attachments?deployment=foo&job=dea&instance_id=17f01a35-bf9c-4949-bcf2-c07a95e4df33
|
13
|
+
put '/:disk_cid/attachments' do
|
14
|
+
job_queue = JobQueue.new
|
15
|
+
task = Bosh::Director::Jobs::AttachDisk.enqueue(current_user, params[:deployment], params[:job], params[:instance_id], params[:disk_cid], job_queue)
|
16
|
+
|
17
|
+
redirect "/tasks/#{task.id}"
|
18
|
+
end
|
19
|
+
|
12
20
|
delete '/:orphan_disk_cid' do
|
13
21
|
job_queue = JobQueue.new
|
14
22
|
task = Bosh::Director::Jobs::DeleteOrphanDisks.enqueue(current_user, [params[:orphan_disk_cid]], job_queue)
|
@@ -38,22 +38,15 @@ module Bosh::Director
|
|
38
38
|
instance.update(vm_cid: nil, agent_id: nil, trusted_certs_sha1: nil, credentials: nil)
|
39
39
|
end
|
40
40
|
|
41
|
-
def recreate_vm(
|
42
|
-
@logger.debug("Recreating Vm: #{
|
43
|
-
existing_vm_env =
|
44
|
-
|
45
|
-
validate_spec(
|
46
|
-
validate_env(
|
47
|
-
|
48
|
-
instance_plan_to_delete = DeploymentPlan::InstancePlan.new(
|
49
|
-
existing_instance: instance,
|
50
|
-
instance: nil,
|
51
|
-
desired_instance: nil,
|
52
|
-
network_plans: []
|
53
|
-
)
|
41
|
+
def recreate_vm(instance_model)
|
42
|
+
@logger.debug("Recreating Vm: #{instance_model})")
|
43
|
+
existing_vm_env = instance_model.vm_env
|
44
|
+
|
45
|
+
validate_spec(instance_model.spec)
|
46
|
+
validate_env(instance_model.vm_env)
|
54
47
|
|
55
48
|
begin
|
56
|
-
vm_deleter.delete_for_instance(
|
49
|
+
vm_deleter.delete_for_instance(instance_model)
|
57
50
|
rescue Bosh::Clouds::VMNotFound
|
58
51
|
# One situation where this handler is actually useful is when
|
59
52
|
# VM has already been deleted but something failed after that
|
@@ -61,32 +54,32 @@ module Bosh::Director
|
|
61
54
|
# to ignore "VM not found" errors in `delete_vm' and let the method
|
62
55
|
# proceed creating a new VM. Other errors are not forgiven.
|
63
56
|
|
64
|
-
@logger.warn("VM '#{
|
57
|
+
@logger.warn("VM '#{instance_model.vm_cid}' might have already been deleted from the cloud")
|
65
58
|
end
|
66
59
|
|
67
|
-
instance_plan_to_create = create_instance_plan(
|
60
|
+
instance_plan_to_create = create_instance_plan(instance_model, existing_vm_env)
|
68
61
|
|
69
62
|
vm_creator.create_for_instance_plan(
|
70
63
|
instance_plan_to_create,
|
71
|
-
Array(
|
64
|
+
Array(instance_model.persistent_disk_cid)
|
72
65
|
)
|
73
66
|
|
74
67
|
dns_manager = DnsManagerProvider.create
|
75
68
|
dns_names_to_ip = {}
|
76
69
|
|
77
70
|
instance_plan_to_create.existing_instance.spec['networks'].each do |network_name, network|
|
78
|
-
index_dns_name = dns_manager.dns_record_name(
|
71
|
+
index_dns_name = dns_manager.dns_record_name(instance_model.index, instance_model.job, network_name, instance_model.deployment.name)
|
79
72
|
dns_names_to_ip[index_dns_name] = network['ip']
|
80
|
-
id_dns_name = dns_manager.dns_record_name(
|
73
|
+
id_dns_name = dns_manager.dns_record_name(instance_model.uuid, instance_model.job, network_name, instance_model.deployment.name)
|
81
74
|
dns_names_to_ip[id_dns_name] = network['ip']
|
82
75
|
end
|
83
76
|
|
84
|
-
@logger.debug("Updating DNS record for instance: #{
|
85
|
-
dns_manager.update_dns_record_for_instance(
|
77
|
+
@logger.debug("Updating DNS record for instance: #{instance_model.inspect}; to: #{dns_names_to_ip.inspect}")
|
78
|
+
dns_manager.update_dns_record_for_instance(instance_model, dns_names_to_ip)
|
86
79
|
dns_manager.flush_dns_cache
|
87
80
|
|
88
|
-
cleaner = RenderedJobTemplatesCleaner.new(
|
89
|
-
InstanceUpdater::StateApplier.new(instance_plan_to_create, agent_client(
|
81
|
+
cleaner = RenderedJobTemplatesCleaner.new(instance_model, App.instance.blobstores.blobstore, @logger)
|
82
|
+
InstanceUpdater::StateApplier.new(instance_plan_to_create, agent_client(instance_model.credentials, instance_model.agent_id), cleaner, @logger).apply
|
90
83
|
end
|
91
84
|
|
92
85
|
private
|
@@ -171,8 +171,8 @@ module Bosh::Director
|
|
171
171
|
end
|
172
172
|
|
173
173
|
if disk_type_name
|
174
|
-
|
175
|
-
|
174
|
+
disk_name = disk_type_name
|
175
|
+
disk_source = 'type'
|
176
176
|
else
|
177
177
|
disk_name = disk_pool_name
|
178
178
|
disk_source = 'pool'
|
@@ -225,10 +225,9 @@ module Bosh::Director
|
|
225
225
|
end
|
226
226
|
|
227
227
|
def parse_resource_pool
|
228
|
-
|
229
|
-
@job.env = Env.new(job_env_hash)
|
230
|
-
|
228
|
+
env_hash = safe_property(@job_spec, 'env', class: Hash, :default => {})
|
231
229
|
resource_pool_name = safe_property(@job_spec, "resource_pool", class: String, optional: true)
|
230
|
+
|
232
231
|
if resource_pool_name
|
233
232
|
resource_pool = @deployment.resource_pool(resource_pool_name)
|
234
233
|
if resource_pool.nil?
|
@@ -236,36 +235,40 @@ module Bosh::Director
|
|
236
235
|
"Job `#{@job.name}' references an unknown resource pool `#{resource_pool_name}'"
|
237
236
|
end
|
238
237
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
238
|
+
vm_type = VmType.new({
|
239
|
+
'name' => resource_pool.name,
|
240
|
+
'cloud_properties' => resource_pool.cloud_properties
|
241
|
+
})
|
243
242
|
|
244
|
-
|
243
|
+
stemcell = resource_pool.stemcell
|
245
244
|
|
246
|
-
if
|
245
|
+
if !env_hash.empty? && !resource_pool.env.empty?
|
247
246
|
raise JobAmbiguousEnv,
|
248
247
|
"Job '#{@job.name}' and resource pool: '#{resource_pool_name}' both declare env properties"
|
249
248
|
end
|
250
249
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
250
|
+
if env_hash.empty?
|
251
|
+
env_hash = resource_pool.env
|
252
|
+
end
|
253
|
+
else
|
254
|
+
vm_type_name = safe_property(@job_spec, 'vm_type', class: String)
|
255
|
+
vm_type = @deployment.vm_type(vm_type_name)
|
256
|
+
if vm_type.nil?
|
257
|
+
raise JobUnknownVmType,
|
258
|
+
"Job `#{@job.name}' references an unknown vm type `#{vm_type_name}'"
|
259
|
+
end
|
255
260
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
+
stemcell_name = safe_property(@job_spec, 'stemcell', class: String)
|
262
|
+
stemcell = @deployment.stemcell(stemcell_name)
|
263
|
+
if stemcell.nil?
|
264
|
+
raise JobUnknownStemcell,
|
265
|
+
"Job `#{@job.name}' references an unknown stemcell `#{stemcell_name}'"
|
266
|
+
end
|
261
267
|
end
|
262
268
|
|
263
|
-
|
264
|
-
@job.stemcell =
|
265
|
-
|
266
|
-
raise JobUnknownStemcell,
|
267
|
-
"Job `#{@job.name}' references an unknown stemcell `#{stemcell_name}'"
|
268
|
-
end
|
269
|
+
@job.vm_type = vm_type
|
270
|
+
@job.stemcell = stemcell
|
271
|
+
@job.env = Env.new(env_hash)
|
269
272
|
end
|
270
273
|
|
271
274
|
def parse_update_config
|
@@ -27,7 +27,10 @@ module Bosh::Director
|
|
27
27
|
disk.update(:active => true) if disk
|
28
28
|
end
|
29
29
|
|
30
|
-
|
30
|
+
orphan_mounted_persistent_disk(instance, old_disk) if old_disk
|
31
|
+
|
32
|
+
inactive_disks = Models::PersistentDisk.where(active: false, instance: instance.model)
|
33
|
+
inactive_disks.each{|disk| detach_and_orphan_disk(disk, instance.model) }
|
31
34
|
end
|
32
35
|
|
33
36
|
def attach_disks_if_needed(instance_plan)
|
@@ -35,18 +38,7 @@ module Bosh::Director
|
|
35
38
|
@logger.warn('Skipping disk attachment, instance no longer needs disk')
|
36
39
|
return
|
37
40
|
end
|
38
|
-
|
39
|
-
instance = instance_plan.instance
|
40
|
-
disk_cid = instance.model.persistent_disk_cid
|
41
|
-
return @logger.info('Skipping disk attaching') if disk_cid.nil?
|
42
|
-
instance_model = instance.model
|
43
|
-
begin
|
44
|
-
@cloud.attach_disk(instance_model.vm_cid, disk_cid)
|
45
|
-
AgentClient.with_vm_credentials_and_agent_id(instance_model.credentials, instance_model.agent_id).mount_disk(disk_cid)
|
46
|
-
rescue => e
|
47
|
-
@logger.warn("Failed to attach disk to new VM: #{e.inspect}")
|
48
|
-
raise e
|
49
|
-
end
|
41
|
+
attach_disk(instance_plan.instance.model)
|
50
42
|
end
|
51
43
|
|
52
44
|
def delete_persistent_disks(instance_model)
|
@@ -67,8 +59,7 @@ module Bosh::Director
|
|
67
59
|
)
|
68
60
|
|
69
61
|
orphan_snapshots(disk.snapshots, orphan_disk)
|
70
|
-
@logger.info("Orphaning disk: '#{disk.disk_cid}', "
|
71
|
-
"#{disk.active ? "active" : "inactive"}")
|
62
|
+
@logger.info("Orphaning disk: '#{disk.disk_cid}', #{disk.active ? "active" : "inactive"}")
|
72
63
|
|
73
64
|
disk.destroy
|
74
65
|
end
|
@@ -90,7 +81,7 @@ module Bosh::Director
|
|
90
81
|
|
91
82
|
def delete_orphan_disk_by_disk_cid(disk_cid)
|
92
83
|
@logger.info("Deleting orphan disk: #{disk_cid}")
|
93
|
-
orphan_disk =
|
84
|
+
orphan_disk = Models::OrphanDisk.where(disk_cid: disk_cid).first
|
94
85
|
if orphan_disk
|
95
86
|
delete_orphan_disk(orphan_disk)
|
96
87
|
else
|
@@ -120,6 +111,19 @@ module Bosh::Director
|
|
120
111
|
|
121
112
|
private
|
122
113
|
|
114
|
+
def attach_disk(instance_model)
|
115
|
+
disk_cid = instance_model.persistent_disk_cid
|
116
|
+
return @logger.info('Skipping disk attaching') if disk_cid.nil?
|
117
|
+
|
118
|
+
begin
|
119
|
+
@cloud.attach_disk(instance_model.vm_cid, disk_cid)
|
120
|
+
AgentClient.with_vm_credentials_and_agent_id(instance_model.credentials, instance_model.agent_id).mount_disk(disk_cid)
|
121
|
+
rescue => e
|
122
|
+
@logger.warn("Failed to attach disk to new VM: #{e.inspect}")
|
123
|
+
raise e
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
123
127
|
def delete_orphan_snapshot(orphan_snapshot)
|
124
128
|
begin
|
125
129
|
snapshot_cid = orphan_snapshot.snapshot_cid
|
@@ -145,7 +149,7 @@ module Bosh::Director
|
|
145
149
|
end
|
146
150
|
end
|
147
151
|
|
148
|
-
def
|
152
|
+
def orphan_mounted_persistent_disk(instance, disk)
|
149
153
|
unmount(instance, disk)
|
150
154
|
|
151
155
|
disk_cid = disk.disk_cid
|
@@ -154,17 +158,20 @@ module Bosh::Director
|
|
154
158
|
return
|
155
159
|
end
|
156
160
|
|
161
|
+
detach_and_orphan_disk(disk, instance.model)
|
162
|
+
end
|
163
|
+
|
164
|
+
def detach_and_orphan_disk(disk, instance_model)
|
157
165
|
begin
|
158
|
-
@logger.info("Detaching disk #{disk_cid}")
|
159
|
-
@cloud.detach_disk(
|
166
|
+
@logger.info("Detaching disk #{disk.disk_cid}")
|
167
|
+
@cloud.detach_disk(instance_model.vm_cid, disk.disk_cid)
|
160
168
|
rescue Bosh::Clouds::DiskNotAttached
|
161
169
|
if disk.active
|
162
170
|
raise CloudDiskNotAttached,
|
163
|
-
|
164
|
-
|
171
|
+
"`#{instance_model}' VM should have persistent disk attached " +
|
172
|
+
"but it doesn't (according to CPI)"
|
165
173
|
end
|
166
174
|
end
|
167
|
-
|
168
175
|
orphan_disk(disk)
|
169
176
|
end
|
170
177
|
|
@@ -175,11 +182,11 @@ module Bosh::Director
|
|
175
182
|
return
|
176
183
|
end
|
177
184
|
|
178
|
-
if
|
185
|
+
if agent_mounted_disks(instance).include?(disk_cid)
|
179
186
|
@logger.info("Stopping instance '#{instance}' before unmount")
|
180
|
-
|
187
|
+
agent_client(instance).stop
|
181
188
|
@logger.info("Unmounting disk '#{disk_cid}'")
|
182
|
-
|
189
|
+
agent_client(instance).unmount_disk(disk_cid)
|
183
190
|
end
|
184
191
|
end
|
185
192
|
|
@@ -189,7 +196,7 @@ module Bosh::Director
|
|
189
196
|
def check_persistent_disk(instance_plan)
|
190
197
|
instance = instance_plan.instance
|
191
198
|
return if instance.model.persistent_disks.empty?
|
192
|
-
agent_disk_cid =
|
199
|
+
agent_disk_cid = agent_mounted_disks(instance).first
|
193
200
|
|
194
201
|
if agent_disk_cid.nil? && !instance_plan.needs_disk?
|
195
202
|
@logger.debug('Disk is already detached')
|
@@ -207,11 +214,11 @@ module Bosh::Director
|
|
207
214
|
end
|
208
215
|
end
|
209
216
|
|
210
|
-
def
|
211
|
-
|
217
|
+
def agent_mounted_disks(instance)
|
218
|
+
agent_client(instance).list_disk
|
212
219
|
end
|
213
220
|
|
214
|
-
def
|
221
|
+
def agent_client(instance)
|
215
222
|
AgentClient.with_vm_credentials_and_agent_id(instance.model.credentials, instance.model.agent_id)
|
216
223
|
end
|
217
224
|
|
@@ -240,11 +247,14 @@ module Bosh::Director
|
|
240
247
|
end
|
241
248
|
|
242
249
|
def mount_and_migrate_disk(instance, new_disk, old_disk)
|
243
|
-
|
244
|
-
|
250
|
+
agent_client = agent_client(instance)
|
251
|
+
agent_client.mount_disk(new_disk.disk_cid)
|
252
|
+
# Mirgate to and from cids are actually ignored by the agent.
|
253
|
+
# The first mount invocation is the source, and the last mount invocation is the target.
|
254
|
+
agent_client.migrate_disk(old_disk.disk_cid, new_disk.disk_cid) if old_disk
|
245
255
|
rescue => e
|
246
256
|
@logger.debug("Failed to migrate disk, deleting new disk. #{e.inspect}")
|
247
|
-
|
257
|
+
orphan_mounted_persistent_disk(instance, new_disk)
|
248
258
|
raise e
|
249
259
|
end
|
250
260
|
|
@@ -52,16 +52,6 @@ module Bosh::Director
|
|
52
52
|
@logger.info("Deleting DNS record: #{record.name}")
|
53
53
|
record.destroy
|
54
54
|
end
|
55
|
-
|
56
|
-
# see if any of the reverse domains are empty and should be deleted
|
57
|
-
ips.each do |ip|
|
58
|
-
reverse = reverse_domain(ip)
|
59
|
-
rdomain = Models::Dns::Domain.filter(name: reverse,
|
60
|
-
type: 'NATIVE')
|
61
|
-
rdomain.each do |domain|
|
62
|
-
delete_empty_domain(domain)
|
63
|
-
end
|
64
|
-
end
|
65
55
|
end
|
66
56
|
|
67
57
|
private
|
@@ -88,40 +78,31 @@ module Bosh::Director
|
|
88
78
|
reverse_domain = reverse_domain(ip_address)
|
89
79
|
reverse_host = reverse_host(ip_address)
|
90
80
|
|
91
|
-
rdomain = Models::Dns::Domain.safe_find_or_create(name: reverse_domain,
|
92
|
-
|
93
|
-
Models::Dns::Record.find_or_create(
|
81
|
+
rdomain = Models::Dns::Domain.safe_find_or_create(name: reverse_domain, type: 'NATIVE')
|
82
|
+
|
83
|
+
Models::Dns::Record.find_or_create(
|
84
|
+
domain: rdomain,
|
94
85
|
name: reverse_domain,
|
95
86
|
type: 'SOA', content: SOA,
|
96
|
-
ttl: TTL_4H
|
87
|
+
ttl: TTL_4H
|
88
|
+
)
|
97
89
|
|
98
|
-
Models::Dns::Record.find_or_create(
|
90
|
+
Models::Dns::Record.find_or_create(
|
91
|
+
domain: rdomain,
|
99
92
|
name: reverse_domain,
|
100
93
|
type: 'NS', ttl: TTL_4H,
|
101
|
-
content: "ns.#{@domain_name}"
|
102
|
-
|
103
|
-
record = Models::Dns::Record.find(content: record_name, type: 'PTR')
|
104
|
-
|
105
|
-
# delete the record if the IP address changed
|
106
|
-
if record && record.name != reverse_host
|
107
|
-
id = record.domain_id
|
108
|
-
record.destroy
|
109
|
-
record = nil
|
110
|
-
|
111
|
-
# delete the domain if the domain id changed and it's empty
|
112
|
-
if id != rdomain.id
|
113
|
-
delete_empty_domain(Models::Dns::Domain[id])
|
114
|
-
end
|
115
|
-
end
|
94
|
+
content: "ns.#{@domain_name}"
|
95
|
+
)
|
116
96
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
97
|
+
record = Models::Dns::Record.find_or_create(content: record_name, type: 'PTR')
|
98
|
+
record.update(
|
99
|
+
domain: rdomain,
|
100
|
+
name: reverse_host,
|
101
|
+
content: record_name,
|
102
|
+
type: 'PTR',
|
103
|
+
ttl: TTL_5M,
|
104
|
+
change_date: Time.now.to_i
|
105
|
+
)
|
125
106
|
end
|
126
107
|
|
127
108
|
def find_domain_id
|
@@ -148,23 +129,5 @@ module Bosh::Director
|
|
148
129
|
octets = ip.split(/\./)
|
149
130
|
"#{octets[0..(n-1)].reverse.join(".")}.in-addr.arpa"
|
150
131
|
end
|
151
|
-
|
152
|
-
def delete_empty_domain(domain)
|
153
|
-
# If the count is 2, it means we only have the NS & SOA record
|
154
|
-
# and the domain is "empty" and can be deleted
|
155
|
-
if domain.records.size == 2
|
156
|
-
@logger.info("Deleting empty reverse domain #{domain.name}")
|
157
|
-
|
158
|
-
# Since DNS domain can be deleted by multiple threads
|
159
|
-
# it's possible for database to return 0 rows modified result.
|
160
|
-
# In this specific case that's a valid return value
|
161
|
-
# but Sequel usually considers that an error.
|
162
|
-
# ('Attempt to delete object did not result in a single row modification')
|
163
|
-
domain.require_modification = false
|
164
|
-
|
165
|
-
# Cascaded - all records are removed
|
166
|
-
domain.destroy
|
167
|
-
end
|
168
|
-
end
|
169
132
|
end
|
170
133
|
end
|
data/lib/bosh/director/errors.rb
CHANGED
@@ -262,6 +262,9 @@ module Bosh::Director
|
|
262
262
|
# Run errand errors
|
263
263
|
RunErrandError = err(510000)
|
264
264
|
|
265
|
-
#
|
265
|
+
# Disk errors
|
266
266
|
DeletingPersistentDiskError = err(520000)
|
267
|
+
AttachDiskErrorUnknownInstance = err(520001)
|
268
|
+
AttachDiskNoPersistentDisk = err(520002)
|
269
|
+
AttachDiskInvalidInstanceState = err(520003)
|
267
270
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Bosh::Director
|
2
|
+
module Jobs
|
3
|
+
class AttachDisk < BaseJob
|
4
|
+
|
5
|
+
@queue = :normal
|
6
|
+
|
7
|
+
def self.job_type
|
8
|
+
:attach_disk
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.enqueue(username, deployment_name, job_name, instance_id, disk_cid, job_queue)
|
12
|
+
job_queue.enqueue(username, Jobs::AttachDisk, "attach disk '#{disk_cid}' to '#{job_name}/#{instance_id}'", [deployment_name, job_name, instance_id, disk_cid])
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(deployment_name, job_name, instance_id, disk_cid)
|
16
|
+
@deployment_name = deployment_name
|
17
|
+
@job_name = job_name
|
18
|
+
@instance_id = instance_id
|
19
|
+
@disk_cid = disk_cid
|
20
|
+
@transactor = Transactor.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def perform
|
24
|
+
instance = Models::Instance.filter(job: @job_name, uuid: @instance_id).to_a.first
|
25
|
+
|
26
|
+
if instance.nil? || instance.deployment.name != @deployment_name
|
27
|
+
raise AttachDiskErrorUnknownInstance, "Instance '#{@job_name}/#{@instance_id}' in deployment '#{@deployment_name}' was not found"
|
28
|
+
end
|
29
|
+
|
30
|
+
if instance.persistent_disk.nil?
|
31
|
+
raise AttachDiskNoPersistentDisk, "Job '#{@job_name}' is not configured with a persistent disk"
|
32
|
+
end
|
33
|
+
|
34
|
+
if instance.state != 'detached'
|
35
|
+
raise AttachDiskInvalidInstanceState, "Instance '#{@job_name}/#{@instance_id}' in deployment '#{@deployment_name}' must be in 'bosh stopped --hard' state"
|
36
|
+
end
|
37
|
+
|
38
|
+
@transactor.retryable_transaction(instance.db) do
|
39
|
+
instance.persistent_disk.update(active: false)
|
40
|
+
Models::PersistentDisk.create(disk_cid: @disk_cid, instance_id: instance.id, active: true, size: 1, cloud_properties: {})
|
41
|
+
end
|
42
|
+
|
43
|
+
"attached disk '#{@disk_cid}' to '#{@job_name}/#{@instance_id}' in deployment '#{@deployment_name}'"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -28,6 +28,11 @@ module Bosh::Director
|
|
28
28
|
jobs
|
29
29
|
)
|
30
30
|
|
31
|
+
REDACT_KEY_NAMES = %w(
|
32
|
+
properties
|
33
|
+
env
|
34
|
+
)
|
35
|
+
|
31
36
|
def order
|
32
37
|
sections = {}
|
33
38
|
key = nil
|
@@ -63,7 +68,7 @@ module Bosh::Director
|
|
63
68
|
while i < self.size
|
64
69
|
line = self[i]
|
65
70
|
|
66
|
-
if line.text =~ /\
|
71
|
+
if REDACT_KEY_NAMES.any? { |key_name| line.text =~ /\b#{key_name}:/ }
|
67
72
|
properties_indent = line.full_indent
|
68
73
|
i += 1
|
69
74
|
line = self[i]
|
data/lib/cloud/dummy.rb
CHANGED
@@ -308,6 +308,16 @@ module Bosh
|
|
308
308
|
agent_base_dir(agent_id)
|
309
309
|
end
|
310
310
|
|
311
|
+
def disk_attached_to_vm?(vm_cid, disk_id)
|
312
|
+
File.exist?(attachment_file(vm_cid, disk_id))
|
313
|
+
end
|
314
|
+
|
315
|
+
def current_apply_spec_for_vm(vm_cid)
|
316
|
+
agent_base_dir = agent_dir_for_vm_cid(vm_cid)
|
317
|
+
spec_file = File.join(agent_base_dir, 'bosh', 'spec.json')
|
318
|
+
JSON.parse(File.read(spec_file))
|
319
|
+
end
|
320
|
+
|
311
321
|
private
|
312
322
|
|
313
323
|
def spawn_agent_process(agent_id)
|
@@ -419,10 +429,6 @@ module Bosh
|
|
419
429
|
File.exist?(attachment_path(disk_id))
|
420
430
|
end
|
421
431
|
|
422
|
-
def disk_attached_to_vm?(vm_cid, disk_id)
|
423
|
-
File.exist?(attachment_file(vm_cid, disk_id))
|
424
|
-
end
|
425
|
-
|
426
432
|
def detach_disks_attached_to_vm(vm_cid)
|
427
433
|
@logger.info("Detaching disks for vm #{vm_cid}")
|
428
434
|
Dir.glob(attachment_file(vm_cid, '*')) do |file_path|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bosh-director
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3189.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- VMware
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bosh_common
|
@@ -16,154 +16,154 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.3189.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.3189.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bosh_cpi
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.3189.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
40
|
+
version: 1.3189.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bosh-registry
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 1.
|
47
|
+
version: 1.3189.0
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 1.
|
54
|
+
version: 1.3189.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: blobstore_client
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.
|
61
|
+
version: 1.3189.0
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 1.
|
68
|
+
version: 1.3189.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bosh-core
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 1.
|
75
|
+
version: 1.3189.0
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 1.
|
82
|
+
version: 1.3189.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: bosh-director-core
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 1.
|
89
|
+
version: 1.3189.0
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 1.
|
96
|
+
version: 1.3189.0
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: bosh-template
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: 1.
|
103
|
+
version: 1.3189.0
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: 1.
|
110
|
+
version: 1.3189.0
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: bosh_openstack_cpi
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - '='
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 2.1.
|
117
|
+
version: 2.1.1
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - '='
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: 2.1.
|
124
|
+
version: 2.1.1
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: bosh_aws_cpi
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - '='
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: 2.1.
|
131
|
+
version: 2.1.1
|
132
132
|
type: :runtime
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - '='
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: 2.1.
|
138
|
+
version: 2.1.1
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: bosh_vsphere_cpi
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
143
|
- - '='
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: 2.
|
145
|
+
version: 2.1.1
|
146
146
|
type: :runtime
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - '='
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: 2.
|
152
|
+
version: 2.1.1
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: bosh_vcloud_cpi
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
157
|
- - '='
|
158
158
|
- !ruby/object:Gem::Version
|
159
|
-
version: 0.
|
159
|
+
version: 0.12.1
|
160
160
|
type: :runtime
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
164
|
- - '='
|
165
165
|
- !ruby/object:Gem::Version
|
166
|
-
version: 0.
|
166
|
+
version: 0.12.1
|
167
167
|
- !ruby/object:Gem::Dependency
|
168
168
|
name: bcrypt-ruby
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -226,14 +226,14 @@ dependencies:
|
|
226
226
|
requirements:
|
227
227
|
- - '='
|
228
228
|
- !ruby/object:Gem::Version
|
229
|
-
version: 2.
|
229
|
+
version: 2.7.1
|
230
230
|
type: :runtime
|
231
231
|
prerelease: false
|
232
232
|
version_requirements: !ruby/object:Gem::Requirement
|
233
233
|
requirements:
|
234
234
|
- - '='
|
235
235
|
- !ruby/object:Gem::Version
|
236
|
-
version: 2.
|
236
|
+
version: 2.7.1
|
237
237
|
- !ruby/object:Gem::Dependency
|
238
238
|
name: logging
|
239
239
|
requirement: !ruby/object:Gem::Requirement
|
@@ -833,6 +833,7 @@ files:
|
|
833
833
|
- lib/bosh/director/job_runner.rb
|
834
834
|
- lib/bosh/director/job_updater.rb
|
835
835
|
- lib/bosh/director/job_updater_factory.rb
|
836
|
+
- lib/bosh/director/jobs/attach_disk.rb
|
836
837
|
- lib/bosh/director/jobs/backup.rb
|
837
838
|
- lib/bosh/director/jobs/base_job.rb
|
838
839
|
- lib/bosh/director/jobs/cleanup_artifacts.rb
|