fix ownership-change permission check
[arvados.git] / app / models / node.rb
index ab971ac3af533f85a163019448412998b0f9f92e..2333d80544607cfe015fcdd7023aac123b2a2127 100644 (file)
@@ -1,5 +1,7 @@
-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
@@ -13,12 +15,43 @@ class Node < ActiveRecord::Base
               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]
 
@@ -36,18 +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)
+      if info[:ec2_instance_id]
+        `ec2-create-tags #{self.info[:ec2_instance_id]} --tag 'hostname=#{self.hostname}'`
+      end
     end
 
     save
@@ -58,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}"
@@ -66,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
@@ -79,7 +125,9 @@ class Node < ActiveRecord::Base
 
   def dnsmasq_update
     if self.hostname_changed? or self.ip_address_changed?
-      self.class.dnsmasq_update(self.hostname, self.ip_address)
+      if self.hostname and self.ip_address
+        self.class.dnsmasq_update(self.hostname, self.ip_address)
+      end
     end
   end
 
@@ -90,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|