From 4c4f6370755bac7877893c5c96ad2eba5a881321 Mon Sep 17 00:00:00 2001 From: Scott Schneider Date: Fri, 14 Nov 2014 12:50:19 -0800 Subject: [PATCH 1/3] Allow authorized_keys to be overridden at VM checkout time --- lib/vmpooler.rb | 2 ++ lib/vmpooler/api.rb | 15 +++++++++++++++ vmpooler.yaml.example | 6 ++++++ 3 files changed, 23 insertions(+) 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..4e6d1b9 100644 --- a/lib/vmpooler/api.rb +++ b/lib/vmpooler/api.rb @@ -190,6 +190,10 @@ module Vmpooler jdata = JSON.parse(request.body.read) jdata.each do |template, count| + if (template == 'key') + result['key'] = count + end + if ( $redis.scard('vmpooler__ready__'+template) < count.to_i ) available = 0 end @@ -199,6 +203,10 @@ module Vmpooler result['ok'] = true jdata.each do |template, count| + if (template == 'key') + next + end + result[template] ||= {} result[template]['ok'] = true ## @@ -214,6 +222,13 @@ module Vmpooler result[template]['ok'] = true ## + 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[template]['hostname'] ) result[template]['hostname'] = [result[template]['hostname']] if ! result[template]['hostname'].is_a?(Array) result[template]['hostname'].push(vm) 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: # From 7543d6259a5b98616f1b459fd4d6d19169fb70ab Mon Sep 17 00:00:00 2001 From: Scott Schneider Date: Fri, 14 Nov 2014 13:01:00 -0800 Subject: [PATCH 2/3] Rename 'template' and 'count' to 'key' and 'value' --- lib/vmpooler/api.rb | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/vmpooler/api.rb b/lib/vmpooler/api.rb index 4e6d1b9..360c664 100644 --- a/lib/vmpooler/api.rb +++ b/lib/vmpooler/api.rb @@ -189,12 +189,12 @@ module Vmpooler jdata = JSON.parse(request.body.read) - jdata.each do |template, count| - if (template == 'key') - result['key'] = count + jdata.each do |key, val| + if (key == 'key') + result['key'] = val end - if ( $redis.scard('vmpooler__ready__'+template) < count.to_i ) + if ( $redis.scard('vmpooler__ready__'+key) < val.to_i ) available = 0 end end @@ -202,25 +202,25 @@ module Vmpooler if ( available == 1 ) result['ok'] = true - jdata.each do |template, count| - if (template == 'key') + jdata.each do |key, val| + if (key == 'key') next end - result[template] ||= {} + result[key] ||= {} - result[template]['ok'] = true ## + result[key]['ok'] = true ## - count.to_i.times do |i| - vm = $redis.spop('vmpooler__ready__'+template) + 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['key'] and $config[:config]['ssh_key'] ) Net::SCP.upload!( @@ -229,14 +229,14 @@ module Vmpooler ) end - 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]['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 From 03e379229a03e9a08b41ee434936483a1c6a5ade Mon Sep 17 00:00:00 2001 From: Scott Schneider Date: Fri, 14 Nov 2014 13:02:38 -0800 Subject: [PATCH 3/3] Specifying need for net/scp gem --- README.md | 1 + 1 file changed, 1 insertion(+) 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)