diff --git a/README.md b/README.md index 8a2c64d..3eded4d 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ At [Puppet Labs](http://puppetlabs.com) we run acceptance tests on hundreds of d vmpooler requires the following Ruby gems be installed: - [json](http://rubygems.org/gems/json) +- [net/scp](http://rubygems.org/gems/net-scp) - [rbvmomi](http://rubygems.org/gems/rbvmomi) - [redis](http://rubygems.org/gems/redis) - [sinatra](http://rubygems.org/gems/sinatra) diff --git a/lib/vmpooler.rb b/lib/vmpooler.rb index ef820da..5f0aa2c 100644 --- a/lib/vmpooler.rb +++ b/lib/vmpooler.rb @@ -2,10 +2,12 @@ require 'rubygems' unless defined?(Gem) module Vmpooler require 'json' + require 'net/scp' require 'open-uri' require 'rbvmomi' require 'redis' require 'sinatra/base' + require 'stringio' require 'time' require 'timeout' require 'yaml' diff --git a/lib/vmpooler/api.rb b/lib/vmpooler/api.rb index 40c9156..360c664 100644 --- a/lib/vmpooler/api.rb +++ b/lib/vmpooler/api.rb @@ -189,8 +189,12 @@ module Vmpooler jdata = JSON.parse(request.body.read) - jdata.each do |template, count| - if ( $redis.scard('vmpooler__ready__'+template) < count.to_i ) + jdata.each do |key, val| + if (key == 'key') + result['key'] = val + end + + if ( $redis.scard('vmpooler__ready__'+key) < val.to_i ) available = 0 end end @@ -198,30 +202,41 @@ module Vmpooler if ( available == 1 ) result['ok'] = true - jdata.each do |template, count| - result[template] ||= {} + jdata.each do |key, val| + if (key == 'key') + next + end - result[template]['ok'] = true ## + result[key] ||= {} - count.to_i.times do |i| - vm = $redis.spop('vmpooler__ready__'+template) + result[key]['ok'] = true ## + + val.to_i.times do |i| + vm = $redis.spop('vmpooler__ready__'+key) unless (vm.nil?) - $redis.sadd('vmpooler__running__'+template, vm) - $redis.hset('vmpooler__active__'+template, vm, Time.now) + $redis.sadd('vmpooler__running__'+key, vm) + $redis.hset('vmpooler__active__'+key, vm, Time.now) - result[template] ||= {} + result[key] ||= {} - result[template]['ok'] = true ## + result[key]['ok'] = true ## - if ( result[template]['hostname'] ) - result[template]['hostname'] = [result[template]['hostname']] if ! result[template]['hostname'].is_a?(Array) - result[template]['hostname'].push(vm) + if ( result['key'] and $config[:config]['ssh_key'] ) + Net::SCP.upload!( + vm, 'root', StringIO.new(result['key']), '/root/.ssh/authorized_keys', + :ssh => { :keys => [ $config[:config]['ssh_key'] ] } + ) + end + + if ( result[key]['hostname'] ) + result[key]['hostname'] = [result[key]['hostname']] if ! result[key]['hostname'].is_a?(Array) + result[key]['hostname'].push(vm) else - result[template]['hostname'] = vm + result[key]['hostname'] = vm end else - result[template]['ok'] = false ## + result[key]['ok'] = false ## result['ok'] = false end diff --git a/vmpooler.yaml.example b/vmpooler.yaml.example index a8ffc8c..87b2ddc 100644 --- a/vmpooler.yaml.example +++ b/vmpooler.yaml.example @@ -101,6 +101,11 @@ # # - domain # If set, returns a top-level 'domain' JSON key in POST requests +# +# - ssh_key +# The path to a private key able to log into pooled VMs. If set, allows a +# 'key' parameter to be passed in POST requests to '/vm', overriding root's +# default authorized_keys file # Example: @@ -111,6 +116,7 @@ vm_checktime: 15 vm_lifetime: 12 domain: 'company.com' + ssh_key: '/root/.ssh/id_rsa' # :pools: #