<commit_before>#!/usr/bin/env ruby

require 'json'
require 'date'
require 'etc'
require 'pp'

def main
  opts = parse_opts
  vbm = find_virtualbox(opts)    
  results = list_vms(opts, vbm).
    select { |vm_name| vm_name =~ opts[:filter] }.
    map {|vm_name| get_vm_details(opts, vbm, vm_name) }.
    reject{|d| d.nil? }
  output_results(opts, results)
end

def parse_opts
  return {
    :running_only => false,
    :filter => /.*/,
    # :filter => /centos6/,
    :do_name => true,
    :do_vagrantfile_dir => true,
    :do_status => true,
    :do_user => true,
    :do_pid => true,  # depends on status, name and user
    :do_ps_stats => true, # depends on status and pid

    # sum of harddisks
    # OS
    # guest additions version
    # memory
    # cpus
    # port offset
    # last legit login
    # cpu time
    # used memory
    # presence of sandman file
    # info from Vagrantfile
    #   git up to date?
    #   uses includes?
    #   vagrant config version?
    #   

  }
end

def find_virtualbox(opts)
  return `which VBoxManage`.chomp
end

def list_vms(opts, vbm)
  cmd = opts[:running_only] ? 'runningvms' : 'vms'
  vms = `#{vbm} list #{cmd}`.split(/\n/).map { |l| (l.split(/\s+/))[0].gsub('"', '') }
end

def get_vm_details(opts, vbm, vm_name) 
  # Run showvminfo
  vmi = Hash.new
  `#{vbm} showvminfo --machinereadable #{vm_name}`.split(/\n/).each do |line|
    match = line.match(/(?<key>.+)="?(?<val>[^"]*)"?$/)    
    vmi[match[:key]] = match[:val] if match
  end

  #pp vmi
  
  return nil unless looks_like_vagrant(vmi)

  details = {}
  opts.select { |opt, val| opt =~ /^do_/ && val }.each do |task, flag|
    self.send(task, vmi, details)
  end

#   extract Vfile dir from shared folder list
#   extract portmappings
#   
  
  return details
end

def do_name(v,d)
  d[:name] = v['name']
end

def do_vagrantfile_dir(v,d)
  mapping_name = v.keys.find {|k| k =~ /^SharedFolderNameMachineMapping/ && v[k] == 'v-root' }
  mapping_name = mapping_name.sub('FolderNameMachine', 'FolderPathMachine')
  d[:vagrantfile_dir] = v[mapping_name]

  dir_parts = d[:vagrantfile_dir].split('/') # TODO UNPORTABLE
  d[:project_vm] = dir_parts[-1]
  d[:project] = dir_parts[-2]
end

def do_status(v,d)
  d[:status] = v['VMState']
  # "VMStateChangeTime"=>"2013-07-26T19:54:36.354000000",
  d[:status_change_epoch] = DateTime.parse(v['VMStateChangeTime']).strftime('%s') 
end

def do_user(v,d)
  d[:username] = Etc.getpwuid(Process.euid).name
end

def do_pid(v,d)
  d[:pid] = nil
  if d[:status] == 'running' then
    entry = (`ps -u #{d[:username]} -o pid= -o args=`.split(/\n/).grep(/VBoxHeadless/).grep(Regexp.new(d[:name])))[0]
    if entry then
      entry.strip!
      d[:pid] = (entry.split(/\s+/))[0]
    end
  end
end                                                                                      

def do_ps_stats(v,d)
  d[:used_memory_kb] = nil
  d[:used_cpu_sec] = nil
  if d[:status] == 'running' then
    entry = `ps -p #{d[:pid]} -o vsz= -o time=`
    m = entry.match(/(?<vsz>\d+)\s+(?<days>\d{0,2})-?(?<hours>\d{2}):(?<minutes>\d{2}):(?<seconds>\d{2})/)
    if m then
      d[:used_memory_kb] = m[:vsz]
      d[:used_cpu_sec] = m[:seconds].to_i + m[:minutes].to_i*60 + m[:hours].to_i*3600 + (m[:days] || 0).to_i*3600*24
    end
  end
end


def looks_like_vagrant(vmi)
  vmi.any? {|k,v| k =~ /^SharedFolderNameMachineMapping/ && v == 'v-root' }
end


def output_results (opts, results)
  puts JSON.pretty_generate(results)
end




main()<commit_msg>Assigned cpu and memory stats<commit_after>#!/usr/bin/env ruby

require 'json'
require 'date'
require 'etc'
require 'pp'

def main
  opts = parse_opts
  vbm = find_virtualbox(opts)    
  results = list_vms(opts, vbm).
    select { |vm_name| vm_name =~ opts[:filter] }.
    map {|vm_name| get_vm_details(opts, vbm, vm_name) }.
    reject{|d| d.nil? }
  output_results(opts, results)
end

def parse_opts
  return {
    :running_only => false,
    # :filter => /.*/,
    :filter => /centos6/,
    :do_name => true,
    :do_vagrantfile_dir => true,
    :do_status => true,
    :do_user => true,
    :do_cpus => true,
    :do_memory => true,
    :do_pid => true,  # depends on status, name and user
    :do_ps_stats => true, # depends on status and pid

    # sum of harddisks
    # OS
    # guest additions version
    # port offset
    # last legit login
    # presence of sandman file
    # info from Vagrantfile
    #   git up to date?
    #   uses includes?
    #   vagrant config version?
    #   

  }
end

def find_virtualbox(opts)
  return `which VBoxManage`.chomp
end

def list_vms(opts, vbm)
  cmd = opts[:running_only] ? 'runningvms' : 'vms'
  vms = `#{vbm} list #{cmd}`.split(/\n/).map { |l| (l.split(/\s+/))[0].gsub('"', '') }
end

def get_vm_details(opts, vbm, vm_name) 
  # Run showvminfo
  vmi = Hash.new
  `#{vbm} showvminfo --machinereadable #{vm_name}`.split(/\n/).each do |line|
    match = line.match(/(?<key>.+)="?(?<val>[^"]*)"?$/)    
    vmi[match[:key]] = match[:val] if match
  end

  pp vmi
  
  return nil unless looks_like_vagrant(vmi)

  details = {}
  opts.select { |opt, val| opt =~ /^do_/ && val }.each do |task, flag|
    self.send(task, vmi, details)
  end

#   extract Vfile dir from shared folder list
#   extract portmappings
#   
  
  return details
end

def do_name(v,d)
  d[:name] = v['name']
end

def do_vagrantfile_dir(v,d)
  mapping_name = v.keys.find {|k| k =~ /^SharedFolderNameMachineMapping/ && v[k] == 'v-root' }
  mapping_name = mapping_name.sub('FolderNameMachine', 'FolderPathMachine')
  d[:vagrantfile_dir] = v[mapping_name]

  dir_parts = d[:vagrantfile_dir].split('/') # TODO UNPORTABLE
  d[:project_vm] = dir_parts[-1]
  d[:project] = dir_parts[-2]
end

def do_status(v,d)
  d[:status] = v['VMState']
  # "VMStateChangeTime"=>"2013-07-26T19:54:36.354000000",
  d[:status_change_epoch] = DateTime.parse(v['VMStateChangeTime']).strftime('%s') 
end

def do_user(v,d)
  d[:username] = Etc.getpwuid(Process.euid).name
end

def do_pid(v,d)
  d[:pid] = nil
  if d[:status] == 'running' then
    entry = (`ps -u #{d[:username]} -o pid= -o args=`.split(/\n/).grep(/VBoxHeadless/).grep(Regexp.new(d[:name])))[0]
    if entry then
      entry.strip!
      d[:pid] = (entry.split(/\s+/))[0]
    end
  end
end                                                                                      

def do_ps_stats(v,d)
  d[:used_memory_kb] = nil
  d[:used_cpu_sec] = nil
  if d[:status] == 'running' then
    entry = `ps -p #{d[:pid]} -o vsz= -o time=`
    m = entry.match(/(?<vsz>\d+)\s+(?<days>\d{0,2})-?(?<hours>\d{2}):(?<minutes>\d{2}):(?<seconds>\d{2})/)
    if m then
      d[:used_memory_kb] = m[:vsz]
      d[:used_cpu_sec] = m[:seconds].to_i + m[:minutes].to_i*60 + m[:hours].to_i*3600 + (m[:days] || 0).to_i*3600*24
    end
  end
end

def do_memory(v,d)
  d[:assigned_memory_mb] = v['memory']
end

def do_cpus(v,d)
  d[:assigned_cpus] = v['cpus']
end


def looks_like_vagrant(vmi)
  vmi.any? {|k,v| k =~ /^SharedFolderNameMachineMapping/ && v == 'v-root' }
end


def output_results (opts, results)
  puts JSON.pretty_generate(results)
end




main()
{'fraction_non_alphanumeric': 0.17879858657243816, 'fraction_numerical': 0.013286219081272085, 'mean_word_length': 3.027319294251565, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1315267', 'n_tokens_mistral': 2928, 'n_tokens_neox': 2821, 'n_words': 591}