summaryrefslogtreecommitdiffstats
path: root/cloudmasterd/bin
diff options
context:
space:
mode:
authorMatthew Hicks <mhicks@mhicks-host.usersys.redhat.com>2008-06-23 10:18:11 -0400
committerMatthew Hicks <mhicks@mhicks-host.usersys.redhat.com>2008-06-23 10:18:11 -0400
commit534eed2e09b7335d475d5f9d2b1f8743aa211e78 (patch)
treea88c143bebb639b954dfb93daa534994764a7861 /cloudmasterd/bin
parent1f39f0c73556ba84b925471a7f3e4c0da793eca5 (diff)
downloadtools-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-xcloudmasterd/bin/cloudmasterd-sync142
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