Class: Bosh::WardenCloud::Cloud

Inherits:
Cloud
  • Object
show all
Includes:
Helpers
Defined in:
lib/cloud/warden/cloud.rb

Constant Summary collapse

DEFAULT_STEMCELL_ROOT =
'/var/vcap/stemcell'
DEFAULT_DISK_ROOT =
'/var/vcap/store/disk'
DEFAULT_FS_TYPE =
'ext4'
DEFAULT_WARDEN_DEV_ROOT =
'/warden-cpi-dev'
DEFAULT_WARDEN_SOCK =
'/tmp/warden.sock'

Constants included from Helpers

Helpers::DEFAULT_SETTINGS_FILE

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helpers

#agent_settings_file, #cloud_error, #generate_agent_env, #get_agent_env, #set_agent_env, #sh, #start_agent, #sudo, #uuid, #with_warden

Constructor Details

#initialize(options) ⇒ Cloud

Initialize BOSH Warden CPI

Parameters:

  • options (Hash)

    CPI options



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/cloud/warden/cloud.rb', line 18

def initialize(options)
  @logger = Bosh::Clouds::Config.logger

  @agent_properties = options.fetch('agent', {})
  @warden_properties = options.fetch('warden', {})
  @stemcell_properties = options.fetch('stemcell', {})
  @disk_properties = options.fetch('disk', {})

  setup_path
  @disk_utils = DiskUtils.new(@disk_root, @stemcell_root, @fs_type)
end

Instance Attribute Details

#loggerObject

Returns the value of attribute logger.



12
13
14
# File 'lib/cloud/warden/cloud.rb', line 12

def logger
  @logger
end

Instance Method Details

#attach_disk(vm_id, disk_id) ⇒ Object

Attach a disk to a VM

Parameters:

  • vm (String)

    vm id that was once returned by #create_vm

  • disk (String)

    disk id that was once returned by #create_disk

Returns:

  • nil



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/cloud/warden/cloud.rb', line 191

def attach_disk(vm_id, disk_id)
  with_thread_name("attach_disk(#{vm_id}, #{disk_id})") do
    cloud_error("Cannot find vm #{vm_id}") unless has_vm?(vm_id)
    cloud_error("Cannot find disk #{disk_id}") unless has_disk?(disk_id)

    vm_bind_mount = File.join(@bind_mount_points, vm_id)
    disk_dir = File.join(vm_bind_mount, disk_id)

    @disk_utils.mount_disk(disk_dir, disk_id)
    # Save device path into agent env settings
    env = get_agent_env(vm_id)
    env['disks']['persistent'][disk_id] = File.join(@warden_dev_root, disk_id)
    set_agent_env(vm_id, env)

    nil
  end
end

#configure_networks(vm_id, networks) ⇒ Object



152
153
154
# File 'lib/cloud/warden/cloud.rb', line 152

def configure_networks(vm_id, networks)
  # no-op
end

#create_disk(size, cloud_properties, vm_locality = nil) ⇒ String

Create a disk

Parameters:

  • size (Integer)

    disk size in MB

  • vm_locality (String) (defaults to: nil)

    vm id if known of the VM that this disk will be attached to

Returns:

  • (String)

    disk id



163
164
165
166
167
168
169
170
# File 'lib/cloud/warden/cloud.rb', line 163

def create_disk(size, cloud_properties, vm_locality = nil)
  not_used(vm_locality)
  with_thread_name("create_disk(#{size}, _)") do
    disk_id = uuid('disk')
    @disk_utils.create_disk(disk_id, size)
    disk_id
  end
end

#create_stemcell(image_path, cloud_properties) ⇒ Object

Create a stemcell using stemcell image return [String] stemcell id

Parameters:

  • image_path (String)

    local path to a stemcell image

  • cloud_properties (Hash)

    not used



35
36
37
38
39
40
41
42
43
# File 'lib/cloud/warden/cloud.rb', line 35

def create_stemcell(image_path, cloud_properties)
  not_used(cloud_properties)
  stemcell_id = uuid('stemcell')
  with_thread_name("create_stemcell(#{image_path}, _)") do
    @logger.info("Extracting stemcell from #{image_path} for #{stemcell_id}")
    @disk_utils.stemcell_unpack(image_path, stemcell_id)
    stemcell_id
  end
end

#create_vm(agent_id, stemcell_id, resource_pool, networks, disk_locality = nil, environment = nil) ⇒ String

Create a container in warden

Limitaion: We don’t support creating VM with multiple network nics.

Parameters:

  • agent_id (String)

    UUID for bosh agent

  • stemcell_id (String)

    stemcell id

  • resource_pool (Hash)

    not used

  • networks (Hash)

    list of networks and their settings needed for this VM

  • disk_locality (optional, String, Array) (defaults to: nil)

    not used

  • env (optional, Hash)

    environment that will be passed to this vm

Returns:

  • (String)

    vm_id



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/cloud/warden/cloud.rb', line 68

def create_vm(agent_id, stemcell_id, resource_pool,
              networks, disk_locality = nil, environment = nil)
  not_used(resource_pool)
  not_used(disk_locality)

  vm_handle = nil
  with_thread_name("create_vm(#{agent_id}, #{stemcell_id}, #{networks})") do
    stemcell_path = @disk_utils.stemcell_path(stemcell_id)
    vm_id = uuid('vm')

    raise ArgumentError, 'Not support more than 1 nics' if networks.size > 1
    cloud_error("Cannot find Stemcell(#{stemcell_id})") unless Dir.exist?(stemcell_path)

    # Create Container
    vm_handle = with_warden do |client|
      request = Warden::Protocol::CreateRequest.new
      request.handle = vm_id
      request.rootfs = stemcell_path
      if networks.first[1]['type'] != 'dynamic'
        request.network = networks.first[1]['ip']
      end
      request.bind_mounts = bind_mount_prepare(vm_id)
      response = client.call(request)
      response.handle
    end
    cloud_error("Cannot create vm with given handle #{vm_id}") unless vm_handle == vm_id

    # Agent settings
    env = generate_agent_env(vm_id, agent_id, networks, environment)
    set_agent_env(vm_id, env)
    start_agent(vm_id)
    vm_id
  end
rescue => e
  destroy_container(vm_handle) if vm_handle
  raise e
end

#delete_disk(disk_id) ⇒ void

This method returns an undefined value.

Delete a disk

Parameters:

  • disk (String)

    id



177
178
179
180
181
182
183
# File 'lib/cloud/warden/cloud.rb', line 177

def delete_disk(disk_id)
  with_thread_name("delete_disk(#{disk_id})") do
    cloud_error("Cannot find disk #{disk_id}") unless has_disk?(disk_id)
    @disk_utils.delete_disk(disk_id)
    nil
  end
end

#delete_stemcell(stemcell_id) ⇒ void

This method returns an undefined value.

Delete the stemcell

Parameters:

  • id (String)

    of the stemcell to be deleted



49
50
51
52
53
54
# File 'lib/cloud/warden/cloud.rb', line 49

def delete_stemcell(stemcell_id)
  with_thread_name("delete_stemcell(#{stemcell_id}, _)") do
    @disk_utils.stemcell_delete(stemcell_id)
    nil
  end
end

#delete_vm(vm_id) ⇒ void

This method returns an undefined value.

Deletes a VM

Parameters:

  • vm_id (String)

    vm id



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/cloud/warden/cloud.rb', line 111

def delete_vm(vm_id)
  with_thread_name("delete_vm(#{vm_id})") do
    if has_vm?(vm_id)
      destroy_container(vm_id)
      vm_bind_mount = File.join(@bind_mount_points, vm_id)
      sudo "umount #{vm_bind_mount}"
    end

    ephemeral_mount = File.join(@ephemeral_mount_points, vm_id)
    sudo "rm -rf #{ephemeral_mount}"
    vm_bind_mount = File.join(@bind_mount_points, vm_id)
    sudo "rm -rf #{vm_bind_mount}"
    nil
  end
end

#detach_disk(vm_id, disk_id) ⇒ Object

Detach a disk from a VM

Parameters:

  • vm (String)

    vm id that was once returned by #create_vm

  • disk (String)

    disk id that was once returned by #create_disk

Returns:

  • nil



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/cloud/warden/cloud.rb', line 215

def detach_disk(vm_id, disk_id)
  with_thread_name("detach_disk(#{vm_id}, #{disk_id})") do

    cloud_error("Cannot find vm #{vm_id}") unless has_vm?(vm_id)
    cloud_error("Cannot find disk #{disk_id}") unless has_disk?(disk_id)

    vm_bind_mount = File.join(@bind_mount_points, vm_id)
    device_path = File.join(vm_bind_mount, disk_id)

    # umount the image file
    @disk_utils.umount_disk(device_path)
    # Save device path into agent env settings
    env = get_agent_env(vm_id)
    env['disks']['persistent'][disk_id] = nil
    set_agent_env(vm_id, env)

    nil
  end
end

#has_vm?(vm_id) ⇒ Boolean

Checks if a VM exists

Parameters:

  • vm_id (String)

    vm id

Returns:

  • (Boolean)

    True if the vm exists



133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/cloud/warden/cloud.rb', line 133

def has_vm?(vm_id)
  with_thread_name("has_vm(#{vm_id})") do
    result = false
    handles = with_warden do |client|
      request = Warden::Protocol::ListRequest.new
      response = client.call(request)
      response.handles
    end
    unless handles.nil?
      result = handles.include?(vm_id)
    end
    result
  end
end

#reboot_vm(vm_id) ⇒ Object



148
149
150
# File 'lib/cloud/warden/cloud.rb', line 148

def reboot_vm(vm_id)
  # no-op
end