Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/bosh-director/lib/bosh/director.rb
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ module Director
require 'bosh/director/jobs/helpers'
require 'bosh/director/jobs/db_job'
require 'bosh/director/jobs/orphan_disk'
require 'bosh/director/jobs/dynamic_disks/create_dynamic_disk'
require 'bosh/director/jobs/dynamic_disks/attach_dynamic_disk'
require 'bosh/director/jobs/dynamic_disks/provide_dynamic_disk'
require 'bosh/director/jobs/dynamic_disks/detach_dynamic_disk'
require 'bosh/director/jobs/dynamic_disks/delete_dynamic_disk'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,57 @@ module Api::Controllers
class DynamicDisksController < BaseController
include ValidationHelper

get '/', scope: :list_dynamic_disks do
disks = Models::DynamicDisk.eager(:deployment, vm: :instance).all.map do |disk|
{
name: disk.name,
disk_cid: disk.disk_cid,
deployment: disk.deployment&.name,
instance: disk.vm&.instance&.name,
availability_zone: disk.availability_zone,
size: disk.size,
cpi: disk.cpi,
}
end
json_encode(disks)
end
Comment thread
coderabbitai[bot] marked this conversation as resolved.

post '/', scope: :create_dynamic_disks, consumes: :json do
request_hash = JSON.parse(request.body.read)

instance_id = safe_property(request_hash, 'instance_id', class: String, min_length: 1)
disk_name = safe_property(request_hash, 'disk_name', class: String, min_length: 1)
disk_pool_name = safe_property(request_hash, 'disk_pool_name', class: String, min_length: 1)
disk_size = safe_property(request_hash, 'disk_size', class: Integer, min: 1)
metadata = safe_property(request_hash, 'metadata', class: Hash, optional: true)

task = JobQueue.new.enqueue(
current_user,
Jobs::DynamicDisks::CreateDynamicDisk,
'create dynamic disk',
[instance_id, disk_name, disk_pool_name, disk_size, metadata],
)

redirect "/tasks/#{task.id}"
end

post '/:disk_name/attach', scope: :attach_dynamic_disks, consumes: :json do
disk_name = safe_property(params, 'disk_name', class: String, min_length: 1)

request_hash = JSON.parse(request.body.read)
instance_id = safe_property(request_hash, 'instance_id', class: String, min_length: 1)
metadata = safe_property(request_hash, 'metadata', class: Hash, optional: true)

task = JobQueue.new.enqueue(
current_user,
Jobs::DynamicDisks::AttachDynamicDisk,
'attach dynamic disk',
[disk_name, instance_id, metadata],
)

redirect "/tasks/#{task.id}"
end

post '/provide', scope: :provide_dynamic_disks, consumes: :json do
request_hash = JSON.parse(request.body.read)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module Bosh::Director
module Jobs::DynamicDisks
class AttachDynamicDisk < Jobs::BaseJob
include Jobs::Helpers::DynamicDiskHelpers
include LockHelper

@queue = :dynamic_disks

def self.job_type
:attach_dynamic_disk
end

def initialize(disk_name, instance_id, metadata = nil)
@disk_name = disk_name
@instance_id = instance_id
@metadata = metadata
end

def perform
disk_model = Models::DynamicDisk.find(name: @disk_name)
raise "disk `#{@disk_name}` not found" if disk_model.nil?

instance = Models::Instance.find(uuid: @instance_id)
raise "instance `#{@instance_id}` not found" if instance.nil?

vm = instance.active_vm
raise "no active vm found for instance `#{@instance_id}`" if vm.nil?

unless disk_model.vm.nil?
return "disk `#{@disk_name}` is already attached to vm `#{disk_model.vm.cid}`" if disk_model.vm.id == vm.id

raise "disk `#{@disk_name}` is already attached to a different vm `#{disk_model.vm.cid}`"
end

cloud = Bosh::Director::CloudFactory.create.get(disk_model.cpi, vm.stemcell_api_version)
disk_hint = with_vm_lock(vm.cid, timeout: VM_LOCK_TIMEOUT) { cloud.attach_disk(vm.cid, disk_model.disk_cid) }
disk_model.update(vm_id: vm.id, availability_zone: vm.instance.availability_zone, disk_hint: disk_hint)

if !@metadata.nil? && disk_model.metadata != @metadata
MetadataUpdater.build.update_dynamic_disk_metadata(cloud, disk_model, @metadata)
disk_model.update(metadata: @metadata)
end

agent_client = AgentClient.with_agent_id(vm.agent_id, instance.name)
agent_client.add_dynamic_disk(disk_model.disk_cid, disk_model.disk_hint)
Comment on lines +56 to +57

"attached disk `#{@disk_name}` to vm `#{vm.cid}` in deployment `#{instance.deployment.name}`"
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
module Bosh::Director
module Jobs::DynamicDisks
class CreateDynamicDisk < Jobs::BaseJob
include Jobs::Helpers::DynamicDiskHelpers

@queue = :dynamic_disks

def self.job_type
:create_dynamic_disk
end

def initialize(instance_id, disk_name, disk_pool_name, disk_size, metadata)
@instance_id = instance_id
@disk_name = disk_name
@disk_pool_name = disk_pool_name
@disk_size = disk_size
@metadata = metadata
end

def perform
disk_model = Models::DynamicDisk.find(name: @disk_name)
raise "disk `#{@disk_name}` already exists" unless disk_model.nil?

instance = Models::Instance.find(uuid: @instance_id)
raise "instance `#{@instance_id}` not found" if instance.nil?

vm = instance.active_vm
raise "no active vm found for instance `#{@instance_id}`" if vm.nil?

cloud_properties = find_disk_cloud_properties(instance, @disk_pool_name)
cloud = Bosh::Director::CloudFactory.create.get(vm.cpi)

cloud_properties['name'] = @disk_name
disk_cid = cloud.create_disk(@disk_size, cloud_properties, vm.cid)
disk_model = Models::DynamicDisk.create(
name: @disk_name,
disk_cid: disk_cid,
deployment_id: instance.deployment.id,
size: @disk_size,
disk_pool_name: @disk_pool_name,
cpi: vm.cpi,
)

if !@metadata.nil? && disk_model.metadata != @metadata
MetadataUpdater.build.update_dynamic_disk_metadata(cloud, disk_model, @metadata)
disk_model.update(metadata: @metadata)
end

disk_info = { disk_cid: disk_model.disk_cid }

task_result.write(JSON.generate(disk_info))
task_result.write("\n")

"created disk `#{@disk_name}` in deployment `#{instance.deployment.name}`"
end
end
end
end
1 change: 1 addition & 0 deletions src/bosh-director/spec/support/test_identity_provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def user_scopes
'dynamic-disks-attacher' => ['bosh.dynamic-disks.attach'],
'dynamic-disks-detacher' => ['bosh.dynamic-disks.detach'],
'dynamic-disks-deleter' => ['bosh.dynamic-disks.delete'],
'dynamic-disks-lister' => ['bosh.dynamic-disks.list'],
'outsider' => ['uaa.admin'],
}
end
Expand Down
Loading
Loading