diff options
author | Matthew Hicks <mhicks@mhicks-host.usersys.redhat.com> | 2008-06-23 10:18:11 -0400 |
---|---|---|
committer | Matthew Hicks <mhicks@mhicks-host.usersys.redhat.com> | 2008-06-23 10:18:11 -0400 |
commit | 534eed2e09b7335d475d5f9d2b1f8743aa211e78 (patch) | |
tree | a88c143bebb639b954dfb93daa534994764a7861 /cloudmasterd/bin | |
parent | 1f39f0c73556ba84b925471a7f3e4c0da793eca5 (diff) | |
download | tools-534eed2e09b7335d475d5f9d2b1f8743aa211e78.tar.gz tools-534eed2e09b7335d475d5f9d2b1f8743aa211e78.tar.xz tools-534eed2e09b7335d475d5f9d2b1f8743aa211e78.zip |
More RPM fixes to get the cloudmaster-sync working from scratch
RPM dependency fixups
Diffstat (limited to 'cloudmasterd/bin')
-rwxr-xr-x | cloudmasterd/bin/cloudmasterd-sync | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/cloudmasterd/bin/cloudmasterd-sync b/cloudmasterd/bin/cloudmasterd-sync new file mode 100755 index 0000000..f30a6c4 --- /dev/null +++ b/cloudmasterd/bin/cloudmasterd-sync @@ -0,0 +1,142 @@ +#!/usr/bin/ruby + +require 'rubygems' +require 'open3' +require 'sqlite3' +require 'active_record' + +# This is needed to let a 'kill PID' command cleanly +# kill the process without requiring -9 +Signal.trap("TERM") do + # Clean up any active record connections + ActiveRecord::Base.remove_connection + + # Cleanly exit + exit 0 +end + +def parse_hosts(func_stderr) + hosts = [] + func_stderr.split("\n").each do |host_line| + # Handle a remote exception coming from a disconnected host + if host_line.index("remote exception") then + hosts.pop() + else + hosts << host_line.split(":")[1][2..-1] + end + end + return hosts +end + +def sync_memory + current_state = {} + Open3.popen3("func '*' call virt freemem") do |stdin, stdout, stderr| + hosts = parse_hosts(stderr.read) + + # Parse out the machines that belong to each host and zip them together in a hash + stdout.read.split("\n").each_with_index do |memory, index| + current_state[hosts[index]] = memory + end + end + + Cloud.transaction do + # Sync up the DB state - delete everything first + Cloud.delete_all + + # Create the current entries + current_state.each do |host, memory| + Cloud.create :name => host, :memory => memory + end + end +end + +def sync_state + current_state = {} + Open3.popen3("func '*' call virt state") do |stdin, stdout, stderr| + hosts = parse_hosts(stderr.read) + + # Parse out the machines that belong to each host and zip them together in a hash + stdout.read.split("\n").each_with_index do |host, index| + host[1..-2].split(", ").each do |machine| + name, state = machine[1..-2].split(" ") + current_state[name] = {:state => state, :cloud => hosts[index]} unless name == "Domain-0" + end + end + end + + # Sync up the state for all the machines + Machine.find(:all).each do |machine| + if current_state.has_key?(machine.name) then + # We have a current state match for this machine + machine.update_attributes(:cloud => current_state[machine.name][:cloud], :state => current_state[machine.name][:state]) + + # Delete the key so we can determine unaccounted for machines + current_state.delete(machine.name) + else + # Not good - the machine in the DB isn't locateable + machine.update_attribute(:state, "missing") + end + end + + # We need to create an 'unknown' instance for all the remaining keys + current_state.each do |name, machine| + Machine.create :name => name, :email => "unknown", :cloud => machine[:cloud], :state => machine[:state] + end +end + +def sync_owners + # Sync up any unowned machines that now have an owner (handles race condition with syncing states) + unowned_machines = {} + Machine.find(:all, :conditions => "email = 'unknown'").each do |machine| + unowned_machines[machine.name] = machine + end + + owned_machines = {} + Machine.find(:all, :conditions => "email <> 'unknown'").each do |machine| + owned_machines[machine.name] = machine + end + + owned_machines.each do |name, machine| + if unowned_machines.has_key?(name) then + # Delete the unowned machine and update the owned one + u_machine = unowned_machines[name] + machine.update_attributes(:cloud => u_machine.cloud, :state => u_machine.state) + u_machine.destroy() + end + end +end + +# Wait until the DB is there to establish the connection +until File.exists?("/var/lib/cloudmaster.db") do + sleep 10 +end + +ActiveRecord::Base.logger = Logger.new('/var/log/cloudmasterd-sync.log', 5, 1024000) +ActiveRecord::Base.colorize_logging = false + +# Setup the database connection +ActiveRecord::Base.establish_connection( + :adapter => "sqlite3", + :dbfile => "/var/lib/cloudmaster.db" +) + +class Machine < ActiveRecord::Base + set_table_name "cloudmasterd_machine" +end + +class Cloud < ActiveRecord::Base + set_table_name "cloudmasterd_cloud" +end + +# Constantly keep the database in sync +while true do + begin + sync_memory + sync_state + sync_owners + rescue Exception => e + puts "ERROR: An error occured during syncing - #{e.to_s}" + end + + sleep 5 +end |