From b3a4f9c0a68195635c2a9a6be8bc2f71b7696fc4 Mon Sep 17 00:00:00 2001 From: Scott Schneider Date: Fri, 6 Feb 2015 11:06:51 -0800 Subject: [PATCH] Rubocop --auto-correct syntax fixups --- lib/vmpooler.rb | 1 - lib/vmpooler/api.rb | 150 ++++++++-------- lib/vmpooler/graphite.rb | 7 +- lib/vmpooler/logger.rb | 3 +- lib/vmpooler/pool_manager.rb | 314 ++++++++++++++++----------------- lib/vmpooler/vsphere_helper.rb | 122 ++++++------- vmpooler | 3 +- 7 files changed, 286 insertions(+), 314 deletions(-) diff --git a/lib/vmpooler.rb b/lib/vmpooler.rb index 81fcd12..97831de 100644 --- a/lib/vmpooler.rb +++ b/lib/vmpooler.rb @@ -19,4 +19,3 @@ module Vmpooler end end end - diff --git a/lib/vmpooler/api.rb b/lib/vmpooler/api.rb index 6b8c173..ae85360 100644 --- a/lib/vmpooler/api.rb +++ b/lib/vmpooler/api.rb @@ -8,25 +8,24 @@ module Vmpooler $config[:uptime] = Time.now # Set some defaults - $config[:redis] ||= Hash.new + $config[:redis] ||= {} $config[:redis]['server'] ||= 'localhost' - if ($config[:graphite]['server']) + if $config[:graphite]['server'] $config[:graphite]['prefix'] ||= 'vmpooler' end # Connect to Redis - $redis = Redis.new(:host => $config[:redis]['server']) + $redis = Redis.new(host: $config[:redis]['server']) end def execute! - my_app = Sinatra.new { - + my_app = Sinatra.new do set :environment, 'production' helpers do - def hostname_shorten hostname - if ( $config[:config]['domain'] and hostname =~ /^\w+\.#{$config[:config]['domain']}$/ ) + def hostname_shorten(hostname) + if $config[:config]['domain'] && hostname =~ /^\w+\.#{$config[:config]['domain']}$/ hostname = hostname[/[^\.]+/] end @@ -36,7 +35,7 @@ module Vmpooler get '/' do erb :dashboard, locals: { - site_name: $config[:config]['site_name'] || 'vmpooler', + site_name: $config[:config]['site_name'] || 'vmpooler' } end @@ -50,13 +49,13 @@ module Vmpooler result['completed'] = 0 $config[:pools].each do |pool| - result['pending'] += $redis.scard( 'vmpooler__pending__' + pool['name'] ) - result['ready'] += $redis.scard( 'vmpooler__ready__' + pool['name'] ) - result['running'] += $redis.scard( 'vmpooler__running__' + pool['name'] ) - result['completed'] += $redis.scard( 'vmpooler__completed__' + pool['name'] ) + result['pending'] += $redis.scard('vmpooler__pending__' + pool['name']) + result['ready'] += $redis.scard('vmpooler__ready__' + pool['name']) + result['running'] += $redis.scard('vmpooler__running__' + pool['name']) + result['completed'] += $redis.scard('vmpooler__completed__' + pool['name']) end - result['cloning'] = $redis.get( 'vmpooler__tasks__clone' ) + result['cloning'] = $redis.get('vmpooler__tasks__clone') result['booting'] = result['pending'].to_i - result['cloning'].to_i result['booting'] = 0 if result['booting'] < 0 result['total'] = result['pending'].to_i + result['ready'].to_i + result['running'].to_i + result['completed'].to_i @@ -71,34 +70,34 @@ module Vmpooler $config[:pools].each do |pool| result[pool['name']] ||= Hash.new result[pool['name']]['size'] = pool['size'] - result[pool['name']]['ready'] = $redis.scard( 'vmpooler__ready__' + pool['name'] ) + result[pool['name']]['ready'] = $redis.scard('vmpooler__ready__' + pool['name']) end - if ( params[:history] ) - if ( $config[:graphite]['server'] ) + if params[:history] + if $config[:graphite]['server'] history ||= Hash.new begin buffer = open( - 'http://'+$config[:graphite]['server']+'/render?target='+$config[:graphite]['prefix']+'.ready.*&from=-1hour&format=json' + 'http://' + $config[:graphite]['server'] + '/render?target=' + $config[:graphite]['prefix'] + '.ready.*&from=-1hour&format=json' ).read - history = JSON.parse( buffer ) + history = JSON.parse(buffer) history.each do |pool| if pool['target'] =~ /.*\.(.*)$/ - pool['name'] = $1 + pool['name'] = Regexp.last_match[1] - if ( result[pool['name']] ) + if result[pool['name']] pool['last'] = result[pool['name']]['size'] result[pool['name']]['history'] ||= Array.new pool['datapoints'].each do |metric| - 8.times do |n| - if ( metric[0] ) + 8.times do |_n| + if metric[0] pool['last'] = metric[0].to_i - result[pool['name']]['history'].push( metric[0].to_i ) + result[pool['name']]['history'].push(metric[0].to_i) else - result[pool['name']]['history'].push( pool['last'] ) + result[pool['name']]['history'].push(pool['last']) end end end @@ -110,7 +109,7 @@ module Vmpooler else $config[:pools].each do |pool| result[pool['name']] ||= Hash.new - result[pool['name']]['history'] = [ $redis.scard( 'vmpooler__ready__' + pool['name'] ) ] + result[pool['name']]['history'] = [$redis.scard('vmpooler__ready__' + pool['name'])] end end end @@ -123,33 +122,33 @@ module Vmpooler result = Hash.new $config[:pools].each do |pool| - running = $redis.scard( 'vmpooler__running__' + pool['name'] ) - pool['major'] = $1 if pool['name'] =~ /^(\w+)\-/ + running = $redis.scard('vmpooler__running__' + pool['name']) + pool['major'] = Regexp.last_match[1] if pool['name'] =~ /^(\w+)\-/ result[pool['major']] ||= Hash.new result[pool['major']]['running'] = result[pool['major']]['running'].to_i + running.to_i end - if ( params[:history] ) - if ( $config[:graphite]['server'] ) + if params[:history] + if $config[:graphite]['server'] begin buffer = open( - 'http://'+$config[:graphite]['server']+'/render?target='+$config[:graphite]['prefix']+'.running.*&from=-1hour&format=json' + 'http://' + $config[:graphite]['server'] + '/render?target=' + $config[:graphite]['prefix'] + '.running.*&from=-1hour&format=json' ).read - JSON.parse( buffer ).each do |pool| + JSON.parse(buffer).each do |pool| if pool['target'] =~ /.*\.(.*)$/ - pool['name'] = $1 + pool['name'] = Regexp.last_match[1] - pool['major'] = $1 if pool['name'] =~ /^(\w+)\-/ + pool['major'] = Regexp.last_match[1] if pool['name'] =~ /^(\w+)\-/ result[pool['major']]['history'] ||= Array.new for i in 0..pool['datapoints'].length - if ( - pool['datapoints'][i] and + if + pool['datapoints'][i] && pool['datapoints'][i][0] - ) + pool['last'] = pool['datapoints'][i][0] result[pool['major']]['history'][i] ||= 0 @@ -181,31 +180,31 @@ module Vmpooler result['status'] = 1 $config[:pools].each do |pool| - pool['capacity_current'] = $redis.scard( 'vmpooler__ready__' + pool['name'] ).to_i + pool['capacity_current'] = $redis.scard('vmpooler__ready__' + pool['name']).to_i result['capacity_current'] += pool['capacity_current'] result['capacity_total'] += pool['size'].to_i - if ( pool['capacity_current'] == 0 ) + if (pool['capacity_current'] == 0) result['empty'] ||= [] - result['empty'].push( pool['name'] ) + result['empty'].push(pool['name']) end end - if ( result['empty'] ) + if result['empty'] result['status'] = 0 end - result['capacity_perecent'] = ( result['capacity_current'].to_f / result['capacity_total'].to_f ) * 100.0 + result['capacity_perecent'] = (result['capacity_current'].to_f / result['capacity_total'].to_f) * 100.0 - result['clone_total'] = $redis.hlen('vmpooler__clone__'+Date.today.to_s) - if ( result['clone_total'] > 0 ) - result['clone_average'] = $redis.hvals('vmpooler__clone__'+Date.today.to_s).map( &:to_f ).reduce( :+ ) / result['clone_total'] + result['clone_total'] = $redis.hlen('vmpooler__clone__' + Date.today.to_s) + if result['clone_total'] > 0 + result['clone_average'] = $redis.hvals('vmpooler__clone__' + Date.today.to_s).map(&:to_f).reduce(:+) / result['clone_total'] end result['uptime'] = Time.now - $config[:uptime] - JSON.pretty_generate(Hash[result.sort_by{|k,v| k}]) + JSON.pretty_generate(Hash[result.sort_by { |k, _v| k }]) end get '/vm/?' do @@ -230,12 +229,12 @@ module Vmpooler jdata = JSON.parse(request.body.read) jdata.each do |key, val| - if ( $redis.scard('vmpooler__ready__'+key) < val.to_i ) + if $redis.scard('vmpooler__ready__' + key) < val.to_i available = 0 end end - if ( available == 1 ) + if (available == 1) result['ok'] = true jdata.each do |key, val| @@ -243,19 +242,19 @@ module Vmpooler result[key]['ok'] = true ## - val.to_i.times do |i| - vm = $redis.spop('vmpooler__ready__'+key) + val.to_i.times do |_i| + vm = $redis.spop('vmpooler__ready__' + key) - unless (vm.nil?) - $redis.sadd('vmpooler__running__'+key, vm) - $redis.hset('vmpooler__active__'+key, vm, Time.now) + unless vm.nil? + $redis.sadd('vmpooler__running__' + key, vm) + $redis.hset('vmpooler__active__' + key, vm, Time.now) result[key] ||= {} result[key]['ok'] = true ## - if ( result[key]['hostname'] ) - result[key]['hostname'] = [result[key]['hostname']] if ! result[key]['hostname'].is_a?(Array) + if result[key]['hostname'] + result[key]['hostname'] = [result[key]['hostname']] unless result[key]['hostname'].is_a?(Array) result[key]['hostname'].push(vm) else result[key]['hostname'] = vm @@ -271,7 +270,7 @@ module Vmpooler result['ok'] = false end - if ( result['ok'] and $config[:config]['domain'] ) + if result['ok'] && $config[:config]['domain'] result['domain'] = $config[:config]['domain'] end @@ -292,12 +291,12 @@ module Vmpooler available = 1 request.keys.each do |template| - if ( $redis.scard('vmpooler__ready__'+template) < request[template] ) + if $redis.scard('vmpooler__ready__' + template) < request[template] available = 0 end end - if ( available == 1 ) + if (available == 1) result['ok'] = true params[:template].split('+').each do |template| @@ -305,16 +304,16 @@ module Vmpooler result[template]['ok'] = true ## - vm = $redis.spop('vmpooler__ready__'+template) + vm = $redis.spop('vmpooler__ready__' + template) - unless (vm.nil?) - $redis.sadd('vmpooler__running__'+template, vm) - $redis.hset('vmpooler__active__'+template, vm, Time.now) + unless vm.nil? + $redis.sadd('vmpooler__running__' + template, vm) + $redis.hset('vmpooler__active__' + template, vm, Time.now) result[template] ||= {} - if ( result[template]['hostname'] ) - result[template]['hostname'] = [result[template]['hostname']] if ! result[template]['hostname'].is_a?(Array) + if result[template]['hostname'] + result[template]['hostname'] = [result[template]['hostname']] unless result[template]['hostname'].is_a?(Array) result[template]['hostname'].push(vm) else result[template]['hostname'] = vm @@ -329,7 +328,7 @@ module Vmpooler result['ok'] = false end - if ( result['ok'] and $config[:config]['domain'] ) + if result['ok'] && $config[:config]['domain'] result['domain'] = $config[:config]['domain'] end @@ -345,16 +344,16 @@ module Vmpooler params[:hostname] = hostname_shorten(params[:hostname]) - if $redis.exists('vmpooler__vm__'+params[:hostname]) + if $redis.exists('vmpooler__vm__' + params[:hostname]) result['ok'] = true result[params[:hostname]] = {} - result[params[:hostname]]['template'] = $redis.hget('vmpooler__vm__'+params[:hostname], 'template') - result[params[:hostname]]['lifetime'] = $redis.hget('vmpooler__vm__'+params[:hostname], 'lifetime') || $config[:config]['vm_lifetime'] - result[params[:hostname]]['running'] = ((Time.now - Time.parse($redis.hget('vmpooler__active__'+result[params[:hostname]]['template'], params[:hostname])))/60/60).round(2) + result[params[:hostname]]['template'] = $redis.hget('vmpooler__vm__' + params[:hostname], 'template') + result[params[:hostname]]['lifetime'] = $redis.hget('vmpooler__vm__' + params[:hostname], 'lifetime') || $config[:config]['vm_lifetime'] + result[params[:hostname]]['running'] = ((Time.now - Time.parse($redis.hget('vmpooler__active__' + result[params[:hostname]]['template'], params[:hostname]))) / 60 / 60).round(2) - if ( $config[:config]['domain'] ) + if $config[:config]['domain'] result[params[:hostname]]['domain'] = $config[:config]['domain'] end end @@ -372,9 +371,9 @@ module Vmpooler params[:hostname] = hostname_shorten(params[:hostname]) $config[:pools].each do |pool| - if $redis.sismember('vmpooler__running__'+pool['name'], params[:hostname]) - $redis.srem('vmpooler__running__'+pool['name'], params[:hostname]) - $redis.sadd('vmpooler__completed__'+pool['name'], params[:hostname]) + if $redis.sismember('vmpooler__running__' + pool['name'], params[:hostname]) + $redis.srem('vmpooler__running__' + pool['name'], params[:hostname]) + $redis.sadd('vmpooler__completed__' + pool['name'], params[:hostname]) result['ok'] = true end end @@ -391,7 +390,7 @@ module Vmpooler params[:hostname] = hostname_shorten(params[:hostname]) - if $redis.exists('vmpooler__vm__'+params[:hostname]) + if $redis.exists('vmpooler__vm__' + params[:hostname]) jdata = JSON.parse(request.body.read) jdata.each do |param, arg| @@ -400,7 +399,7 @@ module Vmpooler arg = arg.to_i if arg > 0 - $redis.hset('vmpooler__vm__'+params[:hostname], param, arg) + $redis.hset('vmpooler__vm__' + params[:hostname], param, arg) result['ok'] = true end end @@ -409,10 +408,9 @@ module Vmpooler JSON.pretty_generate(result) end - } + end my_app.run! end end end - diff --git a/lib/vmpooler/graphite.rb b/lib/vmpooler/graphite.rb index ecdb8ea..128d07b 100644 --- a/lib/vmpooler/graphite.rb +++ b/lib/vmpooler/graphite.rb @@ -8,13 +8,12 @@ module Vmpooler @server = s end - def log path, value - Thread.new { + def log(path, value) + Thread.new do socket = TCPSocket.new(@server, 2003) socket.puts "#{path} #{value} #{Time.now.to_i}" socket.close - } + end end end end - diff --git a/lib/vmpooler/logger.rb b/lib/vmpooler/logger.rb index de97481..2c70756 100644 --- a/lib/vmpooler/logger.rb +++ b/lib/vmpooler/logger.rb @@ -8,7 +8,7 @@ module Vmpooler @file = f end - def log level, string + def log(_level, string) time = Time.new stamp = time.strftime('%Y-%m-%d %H:%M:%S') @@ -18,4 +18,3 @@ module Vmpooler end end end - diff --git a/lib/vmpooler/pool_manager.rb b/lib/vmpooler/pool_manager.rb index 5f73c5f..b6c9ed2 100644 --- a/lib/vmpooler/pool_manager.rb +++ b/lib/vmpooler/pool_manager.rb @@ -11,20 +11,20 @@ module Vmpooler $config[:config]['task_limit'] ||= 10 $config[:config]['vm_checktime'] ||= 15 $config[:config]['vm_lifetime'] ||= 24 - $config[:redis] ||= Hash.new + $config[:redis] ||= {} $config[:redis]['server'] ||= 'localhost' # Load logger library $logger = Vmpooler::Logger.new $config[:config]['logfile'] # Load Graphite helper library (if configured) - if (defined? $config[:graphite]['server']) + if defined? $config[:graphite]['server'] $config[:graphite]['prefix'] ||= 'vmpooler' $graphite = Vmpooler::Graphite.new $config[:graphite]['server'] end # Connect to Redis - $redis = Redis.new(:host => $config[:redis]['server']) + $redis = Redis.new(host: $config[:redis]['server']) # vSphere object $vsphere = {} @@ -33,133 +33,132 @@ module Vmpooler $threads = {} end - # Check the state of a VM - def check_pending_vm vm, pool, timeout - Thread.new { + def check_pending_vm(vm, pool, timeout) + Thread.new do host = $vsphere[pool].find_vm(vm) - if (host) - if ( - (host.summary) and - (host.summary.guest) and - (host.summary.guest.hostName) and + if host + if + (host.summary) && + (host.summary.guest) && + (host.summary.guest.hostName) && (host.summary.guest.hostName == vm) - ) + begin Socket.getaddrinfo(vm, nil) rescue end - $redis.smove('vmpooler__pending__'+pool, 'vmpooler__ready__'+pool, vm) + $redis.smove('vmpooler__pending__' + pool, 'vmpooler__ready__' + pool, vm) $logger.log('s', "[>] [#{pool}] '#{vm}' moved to 'ready' queue") end else - clone_stamp = $redis.hget('vmpooler__vm__'+vm, 'clone') + clone_stamp = $redis.hget('vmpooler__vm__' + vm, 'clone') - if ( - (clone_stamp) and - (((Time.now - Time.parse(clone_stamp))/60) > timeout) - ) - $redis.smove('vmpooler__pending__'+pool, 'vmpooler__completed__'+pool, vm) + if + (clone_stamp) && + (((Time.now - Time.parse(clone_stamp)) / 60) > timeout) + + $redis.smove('vmpooler__pending__' + pool, 'vmpooler__completed__' + pool, vm) $logger.log('d', "[!] [#{pool}] '#{vm}' marked as 'failed' after #{timeout} minutes") end end - } + end end - def check_ready_vm vm, pool, ttl - Thread.new { - if (ttl > 0) - if ((((Time.now - host.runtime.bootTime)/60).to_s[/^\d+\.\d{1}/].to_f) > ttl) - $redis.smove('vmpooler__ready__'+pool, 'vmpooler__completed__'+pool, vm) + def check_ready_vm(vm, pool, ttl) + Thread.new do + if ttl > 0 + if (((Time.now - host.runtime.bootTime) / 60).to_s[/^\d+\.\d{1}/].to_f) > ttl + $redis.smove('vmpooler__ready__' + pool, 'vmpooler__completed__' + pool, vm) $logger.log('d', "[!] [#{pool}] '#{vm}' reached end of TTL after #{ttl} minutes, removed from 'ready' queue") end end - check_stamp = $redis.hget('vmpooler__vm__'+vm, 'check') + check_stamp = $redis.hget('vmpooler__vm__' + vm, 'check') - if ( - (! check_stamp) or - (((Time.now - Time.parse(check_stamp))/60) > $config[:config]['vm_checktime']) - ) - $redis.hset('vmpooler__vm__'+vm, 'check', Time.now) + if + (!check_stamp) || + (((Time.now - Time.parse(check_stamp)) / 60) > $config[:config]['vm_checktime']) + + $redis.hset('vmpooler__vm__' + vm, 'check', Time.now) host = $vsphere[pool].find_vm(vm) || $vsphere[pool].find_vm_heavy(vm)[vm] - if (host) - if ( - (host.runtime) and - (host.runtime.powerState) and + if host + if + (host.runtime) && + (host.runtime.powerState) && (host.runtime.powerState != 'poweredOn') - ) - $redis.smove('vmpooler__ready__'+pool, 'vmpooler__completed__'+pool, vm) + + $redis.smove('vmpooler__ready__' + pool, 'vmpooler__completed__' + pool, vm) $logger.log('d', "[!] [#{pool}] '#{vm}' appears to be powered off, removed from 'ready' queue") end - if ( - (host.summary.guest) and - (host.summary.guest.hostName) and + if + (host.summary.guest) && + (host.summary.guest.hostName) && (host.summary.guest.hostName != vm) - ) - $redis.smove('vmpooler__ready__'+pool, 'vmpooler__completed__'+pool, vm) + + $redis.smove('vmpooler__ready__' + pool, 'vmpooler__completed__' + pool, vm) $logger.log('d', "[!] [#{pool}] '#{vm}' has mismatched hostname, removed from 'ready' queue") end else - $redis.srem('vmpooler__ready__'+pool, vm) + $redis.srem('vmpooler__ready__' + pool, vm) $logger.log('s', "[!] [#{pool}] '#{vm}' not found in vCenter inventory, removed from 'ready' queue") end begin - Timeout::timeout(5) { + Timeout.timeout(5) do TCPSocket.new vm, 22 - } + end rescue - if ($redis.smove('vmpooler__ready__'+pool, 'vmpooler__completed__'+pool, vm)) + if $redis.smove('vmpooler__ready__' + pool, 'vmpooler__completed__' + pool, vm) $logger.log('d', "[!] [#{pool}] '#{vm}' is unreachable, removed from 'ready' queue") end end end - } + end end - def check_running_vm vm, pool, ttl - Thread.new { + def check_running_vm(vm, pool, ttl) + Thread.new do host = $vsphere[pool].find_vm(vm) - if (host) - if ( - (host.runtime) and + if host + if + (host.runtime) && (host.runtime.powerState != 'poweredOn') - ) - $redis.smove('vmpooler__running__'+pool, 'vmpooler__completed__'+pool, vm) + + $redis.smove('vmpooler__running__' + pool, 'vmpooler__completed__' + pool, vm) $logger.log('d', "[!] [#{pool}] '#{vm}' appears to be powered off or dead") else - if ( - (host.runtime) and + if + (host.runtime) && (host.runtime.bootTime) - ((((Time.now - host.runtime.bootTime)/60).to_s[/^\d+\.\d{1}/].to_f) > ttl) - ) - $redis.smove('vmpooler__running__'+pool, 'vmpooler__completed__'+pool, vm) + ((((Time.now - host.runtime.bootTime) / 60).to_s[/^\d+\.\d{1}/].to_f) > ttl) + + $redis.smove('vmpooler__running__' + pool, 'vmpooler__completed__' + pool, vm) $logger.log('d', "[!] [#{pool}] '#{vm}' reached end of TTL after #{ttl} minutes") end end end - } + end end # Clone a VM - def clone_vm template, folder, datastore, target - Thread.new { + def clone_vm(template, folder, datastore, target) + Thread.new do vm = {} if template =~ /\// @@ -170,52 +169,52 @@ module Vmpooler if templatefolders vm[vm['template']] = $vsphere[vm['template']].find_folder(templatefolders.join('/')).find(vm['template']) else - raise "Please provide a full path to the template" + fail 'Please provide a full path to the template' end if vm['template'].length == 0 - raise "Unable to find template '#{vm['template']}'!" + fail "Unable to find template '#{vm['template']}'!" end # Generate a randomized hostname - o = [('a'..'z'),('0'..'9')].map{|r| r.to_a}.flatten - vm['hostname'] = o[rand(25)]+(0...14).map{o[rand(o.length)]}.join + o = [('a'..'z'), ('0'..'9')].map(&:to_a).flatten + vm['hostname'] = o[rand(25)] + (0...14).map { o[rand(o.length)] }.join # Add VM to Redis inventory ('pending' pool) - $redis.sadd('vmpooler__pending__'+vm['template'], vm['hostname']) - $redis.hset('vmpooler__vm__'+vm['hostname'], 'clone', Time.now) - $redis.hset('vmpooler__vm__'+vm['hostname'], 'template', vm['template']) + $redis.sadd('vmpooler__pending__' + vm['template'], vm['hostname']) + $redis.hset('vmpooler__vm__' + vm['hostname'], 'clone', Time.now) + $redis.hset('vmpooler__vm__' + vm['hostname'], 'template', vm['template']) # Annotate with creation time, origin template, etc. configSpec = RbVmomi::VIM.VirtualMachineConfigSpec( - :annotation => JSON.pretty_generate({ + annotation: JSON.pretty_generate( name: vm['hostname'], created_by: $config[:vsphere]['username'], base_template: vm['template'], creation_timestamp: Time.now.utc - }) + ) ) # Choose a clone target - if (target) + if target $clone_target = $vsphere[vm['template']].find_least_used_host(target) - elsif ($config[:config]['clone_target']) + elsif $config[:config]['clone_target'] $clone_target = $vsphere[vm['template']].find_least_used_host($config[:config]['clone_target']) end # Put the VM in the specified folder and resource pool relocateSpec = RbVmomi::VIM.VirtualMachineRelocateSpec( - :datastore => $vsphere[vm['template']].find_datastore(datastore), - :host => $clone_target, - :diskMoveType => :moveChildMostDiskBacking + datastore: $vsphere[vm['template']].find_datastore(datastore), + host: $clone_target, + diskMoveType: :moveChildMostDiskBacking ) # Create a clone spec spec = RbVmomi::VIM.VirtualMachineCloneSpec( - :location => relocateSpec, - :config => configSpec, - :powerOn => true, - :template => false + location: relocateSpec, + config: configSpec, + powerOn: true, + template: false ) # Clone the VM @@ -224,66 +223,66 @@ module Vmpooler begin start = Time.now vm[vm['template']].CloneVM_Task( - :folder => $vsphere[vm['template']].find_folder(folder), - :name => vm['hostname'], - :spec => spec + folder: $vsphere[vm['template']].find_folder(folder), + name: vm['hostname'], + spec: spec ).wait_for_completion - finish = '%.2f' % (Time.now-start) + finish = '%.2f' % (Time.now - start) - $redis.hset('vmpooler__clone__'+Date.today.to_s, vm['hostname'], finish) - $redis.hset('vmpooler__vm__'+vm['hostname'], 'clone_time', finish) + $redis.hset('vmpooler__clone__' + Date.today.to_s, vm['hostname'], finish) + $redis.hset('vmpooler__vm__' + vm['hostname'], 'clone_time', finish) $logger.log('s', "[+] [#{vm['template']}] '#{vm['hostname']}' cloned from '#{vm['template']}' in #{finish} seconds") rescue $logger.log('s', "[!] [#{vm['template']}] '#{vm['hostname']}' clone appears to have failed") - $redis.srem('vmpooler__pending__'+vm['template'], vm['hostname']) + $redis.srem('vmpooler__pending__' + vm['template'], vm['hostname']) end $redis.decr('vmpooler__tasks__clone') begin - $graphite.log($config[:graphite]['prefix']+".clone.#{vm['template']}", finish) if defined? $graphite + $graphite.log($config[:graphite]['prefix'] + ".clone.#{vm['template']}", finish) if defined? $graphite rescue end - } + end end # Destroy a VM - def destroy_vm vm, pool - Thread.new { - $redis.srem('vmpooler__completed__'+pool, vm) - $redis.hdel('vmpooler__active__'+pool, vm) - $redis.del('vmpooler__vm__'+vm) + def destroy_vm(vm, pool) + Thread.new do + $redis.srem('vmpooler__completed__' + pool, vm) + $redis.hdel('vmpooler__active__' + pool, vm) + $redis.del('vmpooler__vm__' + vm) host = $vsphere[pool].find_vm(vm) || $vsphere[pool].find_vm_heavy(vm)[vm] - if (host) + if host start = Time.now - if ( - (host.runtime) and - (host.runtime.powerState) and + if + (host.runtime) && + (host.runtime.powerState) && (host.runtime.powerState == 'poweredOn') - ) + $logger.log('d', "[ ] [#{pool}] '#{vm}' is being shut down") host.PowerOffVM_Task.wait_for_completion end host.Destroy_Task.wait_for_completion - finish = '%.2f' % (Time.now-start) + finish = '%.2f' % (Time.now - start) $logger.log('s', "[-] [#{pool}] '#{vm}' destroyed in #{finish} seconds") - $graphite.log($config[:graphite]['prefix']+".destroy.#{pool}", finish) if defined? $graphite + $graphite.log($config[:graphite]['prefix'] + ".destroy.#{pool}", finish) if defined? $graphite end - } + end end - def check_pool pool + def check_pool(pool) $logger.log('d', "[*] [#{pool['name']}] starting worker thread") - $threads[pool['name']] = Thread.new { + $threads[pool['name']] = Thread.new do $vsphere[pool['name']] ||= Vmpooler::VsphereHelper.new loop do @@ -293,14 +292,14 @@ module Vmpooler base = $vsphere[pool['name']].find_folder(pool['folder']) base.childEntity.each do |vm| - if ( - (! $redis.sismember('vmpooler__running__'+pool['name'], vm['name'])) and - (! $redis.sismember('vmpooler__ready__'+pool['name'], vm['name'])) and - (! $redis.sismember('vmpooler__pending__'+pool['name'], vm['name'])) and - (! $redis.sismember('vmpooler__completed__'+pool['name'], vm['name'])) and - (! $redis.sismember('vmpooler__discovered__'+pool['name'], vm['name'])) - ) - $redis.sadd('vmpooler__discovered__'+pool['name'], vm['name']) + if + (! $redis.sismember('vmpooler__running__' + pool['name'], vm['name'])) && + (! $redis.sismember('vmpooler__ready__' + pool['name'], vm['name'])) && + (! $redis.sismember('vmpooler__pending__' + pool['name'], vm['name'])) && + (! $redis.sismember('vmpooler__completed__' + pool['name'], vm['name'])) && + (! $redis.sismember('vmpooler__discovered__' + pool['name'], vm['name'])) + + $redis.sadd('vmpooler__discovered__' + pool['name'], vm['name']) $logger.log('s', "[?] [#{pool['name']}] '#{vm['name']}' added to 'discovered' queue") end @@ -311,9 +310,9 @@ module Vmpooler end # RUNNING - $redis.smembers('vmpooler__running__'+pool['name']).each do |vm| - if (inventory[vm]) - if (pool['running_ttl']) + $redis.smembers('vmpooler__running__' + pool['name']).each do |vm| + if inventory[vm] + if pool['running_ttl'] begin check_running_vm(vm, pool['name'], pool['running_ttl']) rescue @@ -328,8 +327,8 @@ module Vmpooler end # READY - $redis.smembers('vmpooler__ready__'+pool['name']).each do |vm| - if (inventory[vm]) + $redis.smembers('vmpooler__ready__' + pool['name']).each do |vm| + if inventory[vm] begin check_ready_vm(vm, pool['name'], pool['ready_ttl'] || 0) rescue @@ -338,16 +337,16 @@ module Vmpooler end # PENDING - $redis.smembers('vmpooler__pending__'+pool['name']).each do |vm| - unless (pool['timeout']) - if ($config[:config]['timeout']) + $redis.smembers('vmpooler__pending__' + pool['name']).each do |vm| + unless pool['timeout'] + if $config[:config]['timeout'] pool['timeout'] = $config[:config]['timeout'] else pool['timeout'] = 15 end end - if (inventory[vm]) + if inventory[vm] begin check_pending_vm(vm, pool['name'], pool['timeout']) rescue @@ -356,49 +355,49 @@ module Vmpooler end # COMPLETED - $redis.smembers('vmpooler__completed__'+pool['name']).each do |vm| - if (inventory[vm]) + $redis.smembers('vmpooler__completed__' + pool['name']).each do |vm| + if inventory[vm] begin destroy_vm(vm, pool['name']) rescue $logger.log('s', "[!] [#{pool['name']}] '#{vm}' destroy appears to have failed") - $redis.srem('vmpooler__completed__'+pool['name'], vm) - $redis.hdel('vmpooler__active__'+pool['name'], vm) - $redis.del('vmpooler__vm__'+vm) + $redis.srem('vmpooler__completed__' + pool['name'], vm) + $redis.hdel('vmpooler__active__' + pool['name'], vm) + $redis.del('vmpooler__vm__' + vm) end else $logger.log('s', "[!] [#{pool['name']}] '#{vm}' not found in inventory, removed from 'completed' queue") - $redis.srem('vmpooler__completed__'+pool['name'], vm) - $redis.hdel('vmpooler__active__'+pool['name'], vm) - $redis.del('vmpooler__vm__'+vm) + $redis.srem('vmpooler__completed__' + pool['name'], vm) + $redis.hdel('vmpooler__active__' + pool['name'], vm) + $redis.del('vmpooler__vm__' + vm) end end # DISCOVERED - $redis.smembers('vmpooler__discovered__'+pool['name']).each do |vm| - ['pending', 'ready', 'running', 'completed'].each do |queue| - if ($redis.sismember('vmpooler__'+queue+'__'+pool['name'], vm)) + $redis.smembers('vmpooler__discovered__' + pool['name']).each do |vm| + %w(pending ready running completed).each do |queue| + if $redis.sismember('vmpooler__' + queue + '__' + pool['name'], vm) $logger.log('d', "[!] [#{pool['name']}] '#{vm}' found in '#{queue}', removed from 'discovered' queue") - $redis.srem('vmpooler__discovered__'+pool['name'], vm) + $redis.srem('vmpooler__discovered__' + pool['name'], vm) end end - if ($redis.sismember('vmpooler__discovered__'+pool['name'], vm)) - $redis.smove('vmpooler__discovered__'+pool['name'], 'vmpooler__completed__'+pool['name'], vm) + if $redis.sismember('vmpooler__discovered__' + pool['name'], vm) + $redis.smove('vmpooler__discovered__' + pool['name'], 'vmpooler__completed__' + pool['name'], vm) end end # LONG-RUNNING - $redis.smembers('vmpooler__running__'+pool['name']).each do |vm| - if ($redis.hget('vmpooler__active__'+pool['name'], vm)) - running = (Time.now - Time.parse($redis.hget('vmpooler__active__'+pool['name'], vm)))/60/60 - lifetime = $redis.hget('vmpooler__vm__'+vm, 'lifetime') || $config[:config]['vm_lifetime'] + $redis.smembers('vmpooler__running__' + pool['name']).each do |vm| + if $redis.hget('vmpooler__active__' + pool['name'], vm) + running = (Time.now - Time.parse($redis.hget('vmpooler__active__' + pool['name'], vm))) / 60 / 60 + lifetime = $redis.hget('vmpooler__vm__' + vm, 'lifetime') || $config[:config]['vm_lifetime'] - if ( - (lifetime.to_i > 0) and + if + (lifetime.to_i > 0) && (running.to_i > lifetime.to_i) - ) - $redis.smove('vmpooler__running__'+pool['name'], 'vmpooler__completed__'+pool['name'], vm) + + $redis.smove('vmpooler__running__' + pool['name'], 'vmpooler__completed__' + pool['name'], vm) $logger.log('d', "[!] [#{pool['name']}] '#{vm}' reached end of TTL after #{lifetime} hours") end @@ -406,21 +405,20 @@ module Vmpooler end # REPOPULATE - total = $redis.scard('vmpooler__ready__'+pool['name']) + - $redis.scard('vmpooler__pending__'+pool['name']) + total = $redis.scard('vmpooler__ready__' + pool['name']) + + $redis.scard('vmpooler__pending__' + pool['name']) begin - if (defined? $graphite) - $graphite.log($config[:graphite]['prefix']+'.ready.'+pool['name'], $redis.scard('vmpooler__ready__'+pool['name'])) - $graphite.log($config[:graphite]['prefix']+'.running.'+pool['name'], $redis.scard('vmpooler__running__'+pool['name'])) + if defined? $graphite + $graphite.log($config[:graphite]['prefix'] + '.ready.' + pool['name'], $redis.scard('vmpooler__ready__' + pool['name'])) + $graphite.log($config[:graphite]['prefix'] + '.running.' + pool['name'], $redis.scard('vmpooler__running__' + pool['name'])) end rescue end - if (total < pool['size']) - (1..(pool['size'] - total)).each { |i| - - if ($redis.get('vmpooler__tasks__clone').to_i < $config[:config]['task_limit']) + if total < pool['size'] + (1..(pool['size'] - total)).each do |_i| + if $redis.get('vmpooler__tasks__clone').to_i < $config[:config]['task_limit'] begin $redis.incr('vmpooler__tasks__clone') @@ -435,26 +433,26 @@ module Vmpooler $redis.decr('vmpooler__tasks__clone') end end - } + end end sleep(5) end - } + end end def execute! - $logger.log('d', "starting vmpooler") + $logger.log('d', 'starting vmpooler') # Clear out the tasks manager, as we don't know about any tasks at this point $redis.set('vmpooler__tasks__clone', 0) loop do $pools.each do |pool| - if (! $threads[pool['name']]) + if ! $threads[pool['name']] check_pool(pool) else - if (! $threads[pool['name']].alive?) + unless $threads[pool['name']].alive? $logger.log('d', "[!] [#{pool['name']}] worker thread died, restarting") check_pool(pool) end @@ -464,7 +462,5 @@ module Vmpooler sleep(1) end end - end end - diff --git a/lib/vmpooler/vsphere_helper.rb b/lib/vmpooler/vsphere_helper.rb index 480a7c8..68509b3 100644 --- a/lib/vmpooler/vsphere_helper.rb +++ b/lib/vmpooler/vsphere_helper.rb @@ -2,36 +2,32 @@ require 'rubygems' unless defined?(Gem) module Vmpooler class VsphereHelper - def initialize vInfo = {} + def initialize(_vInfo = {}) config_file = File.expand_path('vmpooler.yaml') vsphere = YAML.load_file(config_file)[:vsphere] - @connection = RbVmomi::VIM.connect :host => vsphere['server'], - :user => vsphere['username'], - :password => vsphere['password'], - :insecure => true + @connection = RbVmomi::VIM.connect host: vsphere['server'], + user: vsphere['username'], + password: vsphere['password'], + insecure: true end - - - def find_datastore datastorename + def find_datastore(datastorename) begin @connection.serviceInstance.CurrentTime rescue - initialize() + initialize end datacenter = @connection.serviceInstance.find_datacenter datacenter.find_datastore(datastorename) end - - - def find_folder foldername + def find_folder(foldername) begin @connection.serviceInstance.CurrentTime rescue - initialize() + initialize end datacenter = @connection.serviceInstance.find_datacenter @@ -49,42 +45,38 @@ module Vmpooler base end - - - def find_least_used_host cluster + def find_least_used_host(cluster) begin @connection.serviceInstance.CurrentTime rescue - initialize() + initialize end - hosts = Hash.new - hosts_sort = Hash.new + hosts = {} + hosts_sort = {} datacenter = @connection.serviceInstance.find_datacenter datacenter.hostFolder.children.each do |folder| next unless folder.name == cluster folder.host.each do |host| - if ( - (host.overallStatus == 'green') and - (! host.runtime.inMaintenanceMode) - ) + if + (host.overallStatus == 'green') && + (!host.runtime.inMaintenanceMode) + hosts[host.name] = host hosts_sort[host.name] = host.vm.length end end end - hosts[hosts_sort.sort_by { |k,v| v }[0][0]] + hosts[hosts_sort.sort_by { |_k, v| v }[0][0]] end - - - def find_pool poolname + def find_pool(poolname) begin @connection.serviceInstance.CurrentTime rescue - initialize() + initialize end datacenter = @connection.serviceInstance.find_datacenter @@ -103,58 +95,54 @@ module Vmpooler end end - base = base.resourcePool unless base.is_a?(RbVmomi::VIM::ResourcePool) and base.respond_to?(:resourcePool) + base = base.resourcePool unless base.is_a?(RbVmomi::VIM::ResourcePool) && base.respond_to?(:resourcePool) base end - - - def find_vm vmname + def find_vm(vmname) begin @connection.serviceInstance.CurrentTime rescue - initialize() + initialize end - @connection.searchIndex.FindByDnsName(:vmSearch => true, :dnsName => vmname) + @connection.searchIndex.FindByDnsName(vmSearch: true, dnsName: vmname) end - - - def find_vm_heavy vmname + def find_vm_heavy(vmname) begin @connection.serviceInstance.CurrentTime rescue - initialize() + initialize end - vmname = vmname.is_a?(Array) ? vmname : [ vmname ] + vmname = vmname.is_a?(Array) ? vmname : [vmname] containerView = get_base_vm_container_from @connection propertyCollector = @connection.propertyCollector objectSet = [{ - :obj => containerView, - :skip => true, - :selectSet => [ RbVmomi::VIM::TraversalSpec.new({ - :name => 'gettingTheVMs', - :path => 'view', - :skip => false, - :type => 'ContainerView' - }) ] + obj: containerView, + skip: true, + selectSet: [RbVmomi::VIM::TraversalSpec.new( + name: 'gettingTheVMs', + path: 'view', + skip: false, + type: 'ContainerView' + )] }] propSet = [{ - :pathSet => [ 'name' ], - :type => 'VirtualMachine' + pathSet: ['name'], + type: 'VirtualMachine' }] - results = propertyCollector.RetrievePropertiesEx({ - :specSet => [{ - :objectSet => objectSet, - :propSet => propSet + results = propertyCollector.RetrievePropertiesEx( + specSet: [{ + objectSet: objectSet, + propSet: propSet }], - :options => { :maxObjects => nil } - }) + options: { maxObjects: nil } + ) vms = {} results.objects.each do |result| @@ -163,8 +151,8 @@ module Vmpooler vms[name] = result.obj end - while results.token do - results = propertyCollector.ContinueRetrievePropertiesEx({:token => results.token}) + while results.token + results = propertyCollector.ContinueRetrievePropertiesEx(token: results.token) results.objects.each do |result| name = result.propSet.first.val next unless vmname.include? name @@ -175,29 +163,23 @@ module Vmpooler vms end - - - def get_base_vm_container_from connection + def get_base_vm_container_from(connection) begin connection.serviceInstance.CurrentTime rescue - initialize() + initialize end viewManager = connection.serviceContent.viewManager - viewManager.CreateContainerView({ - :container => connection.serviceContent.rootFolder, - :recursive => true, - :type => [ 'VirtualMachine' ] - }) + viewManager.CreateContainerView( + container: connection.serviceContent.rootFolder, + recursive: true, + type: ['VirtualMachine'] + ) end - - def close @connection.close end - end end - diff --git a/vmpooler b/vmpooler index 0ffc1d7..f4acf78 100755 --- a/vmpooler +++ b/vmpooler @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -$:.unshift(File.dirname(__FILE__)) +$LOAD_PATH.unshift(File.dirname(__FILE__)) require 'rubygems' unless defined?(Gem) require 'lib/vmpooler' @@ -11,4 +11,3 @@ Thread.new { Vmpooler::PoolManager.new.execute! } loop do sleep(10) end -