(QENG-3376) Allow lifetime to be set per-pool

At current vm_lifetime and vm_lifetime_auth are configured globally only.  This change allows that value to be set/overridden per pool.
This commit is contained in:
Rick Sherman 2016-07-20 17:11:35 -05:00
parent 063d45c60b
commit 8a22434629
4 changed files with 84 additions and 8 deletions

View file

@ -66,8 +66,9 @@ module Vmpooler
backend.hget('vmpooler__token__' + request.env['HTTP_X_AUTH_TOKEN'], 'user') backend.hget('vmpooler__token__' + request.env['HTTP_X_AUTH_TOKEN'], 'user')
) )
if config['vm_lifetime_auth'].to_i > 0 pool_lifetime_auth = pools.find {|p| p["name"] == template }['vm_lifetime_auth']
backend.hset('vmpooler__vm__' + vm, 'lifetime', config['vm_lifetime_auth'].to_i) if (pool_lifetime_auth || config['vm_lifetime_auth']).to_i > 0
backend.hset('vmpooler__vm__' + vm, 'lifetime', (pool_lifetime_auth || config['vm_lifetime_auth']).to_i)
end end
end end
end end
@ -455,13 +456,14 @@ module Vmpooler
result[params[:hostname]] = {} result[params[:hostname]] = {}
result[params[:hostname]]['template'] = rdata['template'] result[params[:hostname]]['template'] = rdata['template']
result[params[:hostname]]['lifetime'] = (rdata['lifetime'] || config['vm_lifetime']).to_i pool_auth = pools.find {|p| p["name"] == rdata['template'] }['vm_lifetime']
result[params[:hostname]]['lifetime'] = (rdata['lifetime'] || pool_auth || config['vm_lifetime']).to_i
if rdata['destroy'] if rdata['destroy']
result[params[:hostname]]['running'] = ((Time.parse(rdata['destroy']) - Time.parse(rdata['checkout'])) / 60 / 60).round(2) result[params[:hostname]]['running'] = ((Time.parse(rdata['destroy']) - Time.parse(rdata['checkout'])) / 60 / 60).round(2).to_f
result[params[:hostname]]['state'] = 'destroyed' result[params[:hostname]]['state'] = 'destroyed'
elsif rdata['checkout'] elsif rdata['checkout']
result[params[:hostname]]['running'] = ((Time.now - Time.parse(rdata['checkout'])) / 60 / 60).round(2) result[params[:hostname]]['running'] = ((Time.now - Time.parse(rdata['checkout'])) / 60 / 60).round(2).to_f
result[params[:hostname]]['state'] = 'running' result[params[:hostname]]['state'] = 'running'
elsif rdata['check'] elsif rdata['check']
result[params[:hostname]]['state'] = 'ready' result[params[:hostname]]['state'] = 'ready'

View file

@ -36,7 +36,7 @@ def create_ready_vm(template, name, token = nil)
create_vm(name, token) create_vm(name, token)
redis.sadd("vmpooler__ready__#{template}", name) redis.sadd("vmpooler__ready__#{template}", name)
# REMIND: should be __vm__? # REMIND: should be __vm__?
redis.hset("vmpooler_vm_#{name}", "template", template) redis.hset("vmpooler__vm__#{name}", "template", template)
end end
def create_running_vm(template, name, token = nil) def create_running_vm(template, name, token = nil)

View file

@ -26,10 +26,11 @@ describe Vmpooler::API::V1 do
config: { config: {
'site_name' => 'test pooler', 'site_name' => 'test pooler',
'vm_lifetime_auth' => 2, 'vm_lifetime_auth' => 2,
'vm_lifetime' => 12,
}, },
pools: [ pools: [
{'name' => 'pool1', 'size' => 5}, {'name' => 'pool1', 'size' => 5},
{'name' => 'pool2', 'size' => 10} {'name' => 'pool2', 'size' => 10, 'vm_lifetime' => 1, 'vm_lifetime_auth' => 4}
], ],
statsd: { 'prefix' => 'stats_prefix'}, statsd: { 'prefix' => 'stats_prefix'},
alias: { 'poolone' => 'pool1' }, alias: { 'poolone' => 'pool1' },
@ -283,7 +284,29 @@ describe Vmpooler::API::V1 do
end end
context '(auth configured)' do context '(auth configured)' do
it 'extends VM lifetime if auth token is provided' do it 'extends VM lifetime to pool value if auth token is provided' do
app.settings.set :config, auth: true
create_ready_vm 'pool2', 'qrstuvwxyz012345'
post "#{prefix}/vm", '{"pool2":"1"}', {
'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345'
}
expect_json(ok = true, http = 200)
expected = {
ok: true,
pool2: {
hostname: 'qrstuvwxyz012345'
}
}
expect(last_response.body).to eq(JSON.pretty_generate(expected))
vm = fetch_vm('qrstuvwxyz012345')
expect(vm['lifetime'].to_i).to eq(4)
end
it 'extends VM lifetime to global value if auth token is provided' do
app.settings.set :config, auth: true app.settings.set :config, auth: true
create_ready_vm 'pool1', 'abcdefghijklmnop' create_ready_vm 'pool1', 'abcdefghijklmnop'
@ -325,5 +348,46 @@ describe Vmpooler::API::V1 do
end end
end end
end end
describe 'GET /vm/:hostname' do
it 'returns a single VM with pool lifetime' do
create_running_vm 'pool2', 'qrstuvwxyz012345'
get "#{prefix}/vm/qrstuvwxyz012345"
expect_json(ok = true, http = 200)
expected = {
ok: true,
qrstuvwxyz012345: {
template: 'pool2',
lifetime: 1,
running: 0.0,
state: 'running',
ip: ''
}
}
expect(last_response.body).to eq(JSON.pretty_generate(expected))
end
it 'returns a single VM with global lifetime' do
create_running_vm 'pool1', 'abcdefghijklmnop'
get "#{prefix}/vm/abcdefghijklmnop"
expect_json(ok = true, http = 200)
expected = {
ok: true,
abcdefghijklmnop: {
template: 'pool1',
lifetime: 12,
running: 0.0,
state: 'running',
ip: ''
}
}
expect(last_response.body).to eq(JSON.pretty_generate(expected))
end
end
end end
end end

View file

@ -285,6 +285,14 @@
# - ready_ttl # - ready_ttl
# How long (in minutes) to keep VMs in 'ready' queues before destroying. # How long (in minutes) to keep VMs in 'ready' queues before destroying.
# (optional) # (optional)
#
# - vm_lifetime
# How long (in hours) to keep VMs in 'running' queues before destroying.
# (optional; default: '24')
#
# - vm_lifetime_auth
# Same as vm_lifetime, but applied if a valid authentication token is
# included during the request.
# Example: # Example:
@ -305,3 +313,5 @@
size: 5 size: 5
timeout: 15 timeout: 15
ready_ttl: 1440 ready_ttl: 1440
vm_lifetime: 1
vm_lifetime_auth: 4