X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/4d7734fcf5d403f196fd66247815bc6f4f67865d..a326799df9f652cd3bbee7956ea8a912d6acc4bd:/app/models/node.rb diff --git a/app/models/node.rb b/app/models/node.rb index 4b51fd4bfe..2333d80544 100644 --- a/app/models/node.rb +++ b/app/models/node.rb @@ -1,20 +1,57 @@ -class Node < ActiveRecord::Base +class Node < OrvosModel include AssignUuid + include KindAndEtag + include CommonApiTemplate serialize :info, Hash before_validation :ensure_ping_secret + after_update :dnsmasq_update MAX_SLOTS = 64 - @@confdir = begin - Rails.configuration.dnsmasq_conf_dir or - ('/etc/dnsmasq.d' if File.exists? '/etc/dnsmasq.d/.') + @@confdir = if Rails.configuration.respond_to? :dnsmasq_conf_dir + Rails.configuration.dnsmasq_conf_dir + elsif File.exists? '/etc/dnsmasq.d/.' + '/etc/dnsmasq.d' + else + nil end + @@domain = Rails.configuration.compute_node_domain rescue `hostname --domain`.strip + @@nameservers = Rails.configuration.compute_node_nameservers + + api_accessible :superuser, :extend => :common do |t| + t.add :hostname + t.add :domain + t.add :ip_address + t.add :first_ping_at + t.add :last_ping_at + t.add :info + t.add :status + t.add lambda { |x| @@nameservers }, :as => :nameservers + end def info @info ||= Hash.new super end + def domain + super || @@domain + end + + def status + if !self.last_ping_at + if Time.now - self.created_at > 5.minutes + 'startup-fail' + else + 'pending' + end + elsif Time.now - self.last_ping_at > 1.hours + 'missing' + else + 'running' + end + end + def ping(o) raise "must have :ip and :ping_secret" unless o[:ip] and o[:ping_secret] @@ -32,19 +69,28 @@ class Node < ActiveRecord::Base end # Record instance ID if not already known - self.info[:ec2_instance_id] ||= o[:ec2_instance_id] + if !self.info[:ec2_instance_id] and o[:ec2_instance_id] + self.info[:ec2_instance_id] = o[:ec2_instance_id] + `ec2-create-tags #{self.info[:ec2_instance_id]} --tag 'Name=#{self.uuid}'` + end # Assign hostname if self.slot_number.nil? try_slot = 0 begin self.slot_number = try_slot - try_slot += 1 - break if self.save rescue nil + begin + self.save! + break + rescue ActiveRecord::RecordNotUnique + try_slot += 1 + end raise "No available node slots" if try_slot == MAX_SLOTS end while true self.hostname = self.class.hostname_for_slot(self.slot_number) - self.class.dnsmasq_update(self.hostname, self.ip_address) + if info[:ec2_instance_id] + `ec2-create-tags #{self.info[:ec2_instance_id]} --tag 'hostname=#{self.hostname}'` + end end save @@ -55,7 +101,8 @@ class Node < ActiveRecord::Base cmd = ["ec2-run-instances", "--user-data '#{ping_url}'", "-t c1.xlarge -n 1 -g orvos-compute", - "ami-68ca6901" + "--client-token", self.uuid, + Rails.configuration.compute_node_ami ].join(' ') self.info[:ec2_start_command] = cmd logger.info "#{self.uuid} ec2_start_command= #{cmd.inspect}" @@ -63,7 +110,9 @@ class Node < ActiveRecord::Base self.info[:ec2_start_result] = result logger.info "#{self.uuid} ec2_start_result= #{result.inspect}" result.match(/INSTANCE\s*(i-[0-9a-f]+)/) do |m| - self.info[:ec2_instance_id] = m[1] + instance_id = m[1] + self.info[:ec2_instance_id] = instance_id + `ec2-create-tags #{instance_id} --tag 'Name=#{self.uuid}'` end self.save! end @@ -74,6 +123,14 @@ class Node < ActiveRecord::Base self.info[:ping_secret] ||= rand(2**256).to_s(36) end + def dnsmasq_update + if self.hostname_changed? or self.ip_address_changed? + if self.hostname and self.ip_address + self.class.dnsmasq_update(self.hostname, self.ip_address) + end + end + end + def self.dnsmasq_update(hostname, ip_address) return unless @@confdir ptr_domain = ip_address. @@ -81,6 +138,7 @@ class Node < ActiveRecord::Base hostfile = File.join @@confdir, hostname File.open hostfile, 'w' do |f| f.puts "address=/#{hostname}/#{ip_address}" + f.puts "address=/#{hostname}.#{@@domain}/#{ip_address}" if @@domain f.puts "ptr-record=#{ptr_domain},#{hostname}" end File.open(File.join(@@confdir, 'restart.txt'), 'w') do |f|