#!/usr/bin/env ruby

##############################################################################
# Environment Configuration
##############################################################################
ONE_LOCATION=ENV["ONE_LOCATION"]
USER=ENV["user"]

if !ONE_LOCATION
    RUBY_LIB_LOCATION="/usr/lib/one/ruby"
else
    RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
end

$: << RUBY_LIB_LOCATION

##############################################################################
# Required libraries
##############################################################################
require 'opennebula'
require 'optparse'

include OpenNebula

MAXWAIT=60
INTERVAL=1

def _wait(vm, st)
    wait = 0
    while vm.status != st 
        vm.info
        if vm.status == 'unkn'
          break
        end
        wait += INTERVAL
        sleep(INTERVAL)
        if wait >= MAXWAIT
            break
        end
    end
end

def CreoleGet(variable)
    begin
        value = `CreoleGet #{variable}`
        return value
    rescue
        return nil
    end
end

#
# NAME: _do_suspend
# PARAM: OpenNebula::VirtualMachine object
# AIM: Suspend a virtual machine
#
def _do_suspend(vm, wait)
    if vm.status == "runn"
        puts("Suspending #{vm.name} ...")
        vm.suspend
        if wait
            _wait(vm, "susp")
        end
    end
end

#
# NAME: _do_resume
# PARAM: OpenNebula::VirtualMachine object
# AIM: Resum a suspended virtual machines
#
def _do_resume(vm, wait)
    if vm.status == "susp"
      puts("Resume on #{vm.name}")
      vm.resume
    elsif vm.status == 'unkn'
      puts("Boot on #{vm.name}")
      vm.boot
    else
      return -1
    end
    if wait
      _wait(vm, "runn")
    end
end


options = {:creds => nil, :action => nil, :endpoint => nil}

parser = OptionParser.new do|opts|
  opts.banner = "Usage: #{File.basename(__FILE__)} [options]"
  opts.on('-c', '--creds file', 'Crediential file') do |value|
    options[:creds] = value;
  end

  opts.on('-a', '--action action', 'Action to run') do |value|
    options[:action] = value;
  end

  opts.on('-e', '--end-point url', 'End point URL') do |value|
    options[:endpoint] = value;
  end

  opts.on('-w', '--wait', 'Wait for action ends') do |w|
      options[:wait] = w
  end

  opts.on('-h', '--help', 'Displays Help') do
    puts opts
    exit
  end
end

parser.parse!

# OpenNebula credentials

if not options[:creds]
    options[:creds] = "/var/lib/one/.one/one_auth"
end

if not options[:action]
  options[:action] = "status"
end

if not options[:endpoint]
  ip = CreoleGet('adresse_ip_eth0').chomp
  options[:endpoint] = "http://#{ip}:2633/RPC2"
end

# Actions
SUPPORTED = ['status', 'boot', 'resume', 'shutdown', 'suspend']


if not SUPPORTED.include?(options[:action])
  puts("Action : #{options[:action]}) is not supported")
  exit -1
end

begin
    File.readlines(options[:creds]).each do |line|
        CREDENTIALS = line
    end
rescue
    puts("#{options[:creds]}: Problem loading credentials, check if file exists.")
    exit -1
end

begin
  client = Client.new(CREDENTIALS, options[:endpoint])

  vm_pool = VirtualMachinePool.new(client, -1)

  rc = vm_pool.info
  if OpenNebula.is_error?(rc)
    puts rc.message
    exit -1
  end

  vm_pool.each do |vm|
    case options[:action]
    when "status"
      puts("#{vm.name}\t#{vm.status}")
    when "boot"
      if vm.status == "unkn"
        puts("Booting #{vm.name} ...")
        vm.boot
      end
    when "suspend"
        _do_suspend(vm, options[:wait])
    when "resume"
        _do_resume(vm, options[:wait])
    else
      puts("#{vm.name}\t#{vm.status}")
    end
  end
rescue Exception => e
  puts e.message
  exit -1
end
exit 0