class VM

Public Class Methods

alive(host, query = nil) click to toggle source
# File lib/floatyhelper/vm.rb, line 63
def self.alive(host, query = nil)
  query ||= query(host)
  query['ok'] && query[host]['state'] == 'running'
end
destroy(id) click to toggle source

VM Management ###

# File lib/floatyhelper/vm.rb, line 45
def self.destroy(id)
  hosts = Hosts.get_hosts_from_id(id)
  Groups.delete_tag(id) if Groups.tag?(id)
  Groups.delete_all if id == 'all'
  hosts = hosts.select { |host| alive(host) }
  puts Floaty.floaty_cmd("delete #{hosts.join(',')} --service vmpooler") unless hosts.empty?
end
find_pooled_platforms() click to toggle source
# File lib/floatyhelper/vm.rb, line 26
def self.find_pooled_platforms
  begin # rubocop:disable Style/RedundantBegin
    uri = URI.parse('https://vmpooler.delivery.puppetlabs.net/status')
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    result = http.get(uri.request_uri)
    result = JSON.parse(result.body)
    # Techinally, 'max > 0' tells you if it's a pooled platform, but if
    # the pool is empty, we'll want to fall back to ABS anyway.
    result['pools'].select { |_pool, info| info['ready'].positive? }.map { |pool, _info| pool.gsub('-pixa4','') }
  rescue StandardError
    # Not a great practice to swallow all errors, but this list is probably
    # pretty stable, so let's just pass along the default.
    puts 'Error looking up pooled platforms from vmpooler.delivery.puppetlabs.net. Using default pooled platform list instead.'.yellow
    pooled_platforms_default
  end
end
get_current_lifetime(host) click to toggle source
# File lib/floatyhelper/vm.rb, line 58
def self.get_current_lifetime(host)
  status = query(host)
  status['ok'] ? status[host]['lifetime'] : nil
end
get_vm(platform: 'centos-7-x86_64', force_abs: false) click to toggle source

Get a VM from floaty ###

# File lib/floatyhelper/vm.rb, line 162
def self.get_vm(platform: 'centos-7-x86_64', force_abs: false)
  if !find_pooled_platforms.include?(platform.gsub('-pixa4','')) || force_abs
    response = Floaty.floaty_cmd("get #{platform} --service abs --priority 1", use_pty: true)
    vmlinesplit = response.chomp.split('- ')
    # When use_pty is true, we've already printed stderr/stdout, so no need to do so again.
    raise "Error obtaining a VM" if vmlinesplit.count == 1
    vmlinesplit[1].split[0].split('.')[0]
  else
    response = Floaty.floaty_cmd("get #{platform} --service vmpooler")
    raise "Error obtaining a VM: #{response}" if response.include?('error')
    response.split[1].split('.')[0]
  end
end
getsnapshot(id, snaptag) click to toggle source
# File lib/floatyhelper/vm.rb, line 134
def self.getsnapshot(id, snaptag)
  data = Config.load_data
  data['snapshots'][id][snaptag]
end
increaselife(id, amount = nil) click to toggle source
# File lib/floatyhelper/vm.rb, line 68
def self.increaselife(id, amount = nil)
  amount ||= Config.get_config_setting('increaselife').to_i
  return if amount < 1
  hosts = Hosts.get_hosts_from_id(id)
  hosts.each do |host|
    if (lifetime = get_current_lifetime(host))
      lifetime += amount
      output = Floaty.floaty_cmd("modify #{host} --lifetime #{lifetime} --service vmpooler")
      if output =~ /Successfully modified/
        puts "#{host} lifetime set to #{lifetime} hours".green
      else
        puts "Error setting VM lifetime: #{output}".red
      end
    else
      puts "Could not query host #{host}".red
    end
  end
end
pooled_platforms_default() click to toggle source
# File lib/floatyhelper/vm.rb, line 12
def self.pooled_platforms_default
  [
    'centos-7-x86_64',
    'centos-8-x86_64',
    'oracle-7-x86_64',
    'redhat-7-x86_64',
    'redhat-8-x86_64',
    'redhat-fips-7-x86_64',
    'scientific-7-x86_64',
    'sles-12-x86_64',
    'ubuntu-1804-x86_64',
  ]
end
query(host) click to toggle source
# File lib/floatyhelper/vm.rb, line 53
def self.query(host)
  output = Floaty.floaty_cmd("query #{host} --service vmpooler")
  Floaty.parse_floaty_json_output(output)
end
revert(id, snaptag) click to toggle source
# File lib/floatyhelper/vm.rb, line 150
def self.revert(id, snaptag)
  snaptag ||= 'Blank Snaptag'
  shas = VM.getsnapshot(id, snaptag)
  shas.each do |host, sha|
    print "#{host}: #{sha} --- "
    puts Floaty.floaty_cmd("revert #{host} #{sha} --service vmpooler")
  end
  puts 'Waiting 10 seconds for revert to take effect'
  sleep(10)
end
snaplist(tag) click to toggle source
# File lib/floatyhelper/vm.rb, line 144
def self.snaplist(tag)
  data = Config.load_data
  return [] if !data['snapshots'].keys.include?(tag)
  data['snapshots'][tag].keys
end
snapshot(id, snaptag) click to toggle source

Snapshots ###

# File lib/floatyhelper/vm.rb, line 88
def self.snapshot(id, snaptag)
  clr = Config.get_config_setting('vertical_snapshot_status')
  clr = clr.to_s.downcase == 'true'
  snaptag ||= 'Blank Snaptag'
  hosts = Hosts.get_hosts_from_id(id)
  shas = {}
  # There's probably a better way to do this...
  puts `tput clear` if clr

  hosts.each do |host|
    result = Floaty.floaty_cmd("snapshot #{host} --service vmpooler")
    answer = Floaty.parse_floaty_json_output(result)
    sha = answer[host]['snapshot']
    puts "#{host}: #{sha}"
    shas[host] = sha
  end

  data = Config.load_data
  data['snapshots'] ||= {}
  data['snapshots'][id] ||= {}
  data['snapshots'][id][snaptag] = shas
  Config.write_data(data)

  puts
  puts 'Waiting for snapshots to appear in floaty query...'
  alldone = false
  until alldone
    puts `tput cup #{hosts.count + 2}` if clr
    alldone = true
    print "\r" unless clr
    hosts.each do |host|
      answer = query(host)[host]
      done = answer.keys.include?('snapshots') && answer['snapshots'].include?(shas[host])
      status = done ? 'Done'.green : 'Wait'.yellow
      if clr
        puts "* %s #{status} *" % "#{host}:".ljust(16)
      else
        print "* %s #{status} *" % "#{host}:".ljust(16)
      end
      alldone &= done
    end
    sleep(1)
  end
  puts ''
end
snaptag_exists?(id, snaptag) click to toggle source
# File lib/floatyhelper/vm.rb, line 139
def self.snaptag_exists?(id, snaptag)
  data = Config.load_data
  data['snapshots'].keys.include?(id) ? data['snapshots'][id].keys.include?(snaptag) : false
end