Skip to content

Commit

Permalink
(MODULES-4594) vmpooler hypervisor: add disks
Browse files Browse the repository at this point in the history
In order to set up a test environment for Red Hat Satellite, we need a
disk that's larger than the default vmpooler allotment (about 5 GB free
vs the 1.5GB that are free on a redhat host after all is said and done).
This adds a step to the provision function in the vmpooler hypervisor to
add a disk/s, x GB in size, to any host in the host configuration file. It is
then up to the tests to partition, mount, expand, or whatever they
decide to do with it/them.
  • Loading branch information
eputnam authored and kevpl committed Apr 17, 2017
1 parent 8f66071 commit 309f7d6
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 1 deletion.
19 changes: 18 additions & 1 deletion docs/how_to/hypervisors/vmpooler.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,24 @@ An example of a `.fog` file with just the vmpooler details is below:
:default:
:vmpooler_token: 'randomtokentext'
```
# Additional Disks
Using the vmpooler API, Beaker enables you to attach additional storage disks in the host configuration file. The disks are added at the time the VM is created. Logic for using the disk must go into your tests.
Simply add the `disks` key and a list containing the sizes(in GB) of the disks you want to create and attach to that host.
For example, to create 2 disks sized 8GB and 16GB to example-box:

```yaml
example-box:
disks:
- 8
- 16
roles:
- satellite
platform: el-7-x86_64
hypervisor: vmpooler
template: redhat-7-x86_64
```

Users with Puppet credentials can follow our instructions for getting & using
vmpooler tokens in our
[internal documentation](https://confluence.puppetlabs.com/pages/viewpage.action?spaceKey=SRE&title=Generating+and+using+vmpooler+tokens).
[internal documentation](https://confluence.puppetlabs.com/pages/viewpage.action?spaceKey=SRE&title=Generating+and+using+vmpooler+tokens).
104 changes: 104 additions & 0 deletions lib/beaker/hypervisor/vmpooler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,33 @@ def provision
end

@logger.notify 'Spent %.2f seconds tagging VMs' % (Time.now - start)

# add additional disks to vm
@logger.debug 'Looking for disks to add...'

@hosts.each do |h|
hostname = h['vmhostname'].split(".")[0]

if h['disks']
@logger.debug "Found disks for #{hostname}!"
disks = h['disks']

disks.each_with_index do |disk_size, index|
start = Time.now

add_disk(hostname, disk_size)

done = wait_for_disk(hostname, disk_size, index)
if done
@logger.notify "Spent %.2f seconds adding disk #{index}. " % (Time.now - start)
else
raise "Could not verify disk was added after %.2f seconds" % (Time.now - start)
end
end
else
@logger.debug "No disks to add for #{hostname}"
end
end
end

def cleanup
Expand Down Expand Up @@ -246,5 +273,82 @@ def cleanup
@logger.notify "Spent %.2f seconds cleaning up" % (Time.now - start)
end

def add_disk(hostname, disk_size)
@logger.notify "Requesting an additional disk of size #{disk_size}GB for #{hostname}"

if !disk_size.to_s.match /[0123456789]/ || size <= '0'
raise NameError.new "Disk size must be an integer greater than zero!"
end

begin
uri = URI.parse(@options[:pooling_api] + '/api/v1/vm/' + hostname + '/disk/' + disk_size.to_s)

http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request['X-AUTH-TOKEN'] = @credentials[:vmpooler_token]

response = http.request(request)

parsed = parse_response(response)

raise "Response from #{hostname} indicates disk was not added" if !parsed['ok']

rescue NameError, RuntimeError, Errno::EINVAL, Errno::ECONNRESET, EOFError,
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, *SSH_EXCEPTIONS => e
report_and_raise(@logger, e, 'Vmpooler.add_disk')
end
end

def parse_response(response)
parsed_response = JSON.parse(response.body)
end

def disk_added?(host, disk_size, index)
if host['disk'].nil?
false
else
host['disk'][index] == "+#{disk_size}gb"
end
end

def get_vm(hostname)
begin
uri = URI.parse(@options[:pooling_api] + '/vm/' + hostname)

http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)

response = http.request(request)
rescue RuntimeError, Errno::EINVAL, Errno::ECONNRESET, EOFError,
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, *SSH_EXCEPTIONS => e
@logger.notify "Failed to connect to vmpooler while getting VM information!"
end
end

def wait_for_disk(hostname, disk_size, index)
response = get_vm(hostname)
parsed = parse_response(response)

@logger.notify "Waiting for disk"

attempts = 0

while (!disk_added?(parsed[hostname], disk_size, index) && attempts < 20)
sleep 10
begin
response = get_vm(hostname)
parsed = parse_response(response)
rescue RuntimeError, Errno::EINVAL, Errno::ECONNRESET, EOFError,
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, *SSH_EXCEPTIONS => e
report_and_raise(@logger, e, "Vmpooler.wait_for_disk")
end
print "."
attempts += 1
end

puts " "

disk_added?(parsed[hostname], disk_size, index)
end
end
end
36 changes: 36 additions & 0 deletions spec/beaker/hypervisor/vmpooler_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,42 @@ module Beaker
end
end

describe '#disk_added?' do
let(:vmpooler) { Beaker::Vmpooler.new(make_hosts, make_opts) }
let(:response_hash_no_disk) {
{
"ok" => "true",
"hostname" => {
"template"=>"redhat-7-x86_64",
"domain"=>"delivery.puppetlabs.net"
}
}
}
let(:response_hash_disk) {
{
"ok" => "true",
"hostname" => {
"disk" => [
'+16gb',
'+8gb'
],
"template"=>"redhat-7-x86_64",
"domain"=>"delivery.puppetlabs.net"
}
}
}
it 'returns false when there is no disk' do
host = response_hash_no_disk['hostname']
expect(vmpooler.disk_added?(host, "8", 0)).to be(false)
end

it 'returns true when there is a disk' do
host = response_hash_disk["hostname"]
expect(vmpooler.disk_added?(host, "16", 0)).to be(true)
expect(vmpooler.disk_added?(host, "8", 1)).to be(true)
end
end

describe "#provision" do

it 'provisions hosts from the pool' do
Expand Down

0 comments on commit 309f7d6

Please sign in to comment.