[ARVADOS] updated: 10caf4bc580e7f1646373ef9c1eda1579f0eb52d

git at public.curoverse.com git at public.curoverse.com
Wed Sep 24 11:39:00 EDT 2014


Summary of changes:
 apps/workbench/app/assets/javascripts/dates.js     |   3 +
 .../app/assets/stylesheets/application.css.scss    |  13 ++
 .../app/assets/stylesheets/projects.css.scss       |   9 +-
 .../app/controllers/application_controller.rb      |  24 +-
 apps/workbench/app/helpers/application_helper.rb   |   4 +
 .../app/helpers/pipeline_instances_helper.rb       |  77 +++++--
 apps/workbench/app/models/job.rb                   |   4 +
 .../app/views/application/_content_layout.html.erb |  10 +-
 .../views/application/_job_status_label.html.erb   |   2 +-
 .../{show.html.erb => _title_and_buttons.html.erb} |  22 +-
 apps/workbench/app/views/application/show.html.erb |  71 +-----
 .../collections/_show_source_summary.html.erb      |   3 +-
 .../workbench/app/views/jobs/_show_status.html.erb | 110 ++-------
 apps/workbench/app/views/jobs/show.html.erb        |  32 +++
 ...unning.html.erb => _running_component.html.erb} | 105 ++-------
 .../_show_components_running.html.erb              | 252 ++++-----------------
 .../views/projects/_compute_node_status.html.erb   |  45 +++-
 .../views/projects/_compute_node_summary.html.erb  |  10 +-
 .../app/views/projects/_show_dashboard.html.erb    |  62 ++---
 .../test/integration/user_profile_test.rb          |   2 +-
 doc/api/methods/nodes.html.textile.liquid          |   2 +-
 doc/api/schema/Job.html.textile.liquid             |   2 +-
 doc/api/schema/Node.html.textile.liquid            |   2 +-
 sdk/cli/Gemfile.lock                               |  32 +--
 sdk/cli/README.textile                             |  11 -
 sdk/cli/arvados-cli.gemspec                        |  14 +-
 sdk/python/bin/arv-get                             |   6 +-
 sdk/ruby/arvados.gemspec                           |  18 +-
 .../app/controllers/arvados/v1/nodes_controller.rb |  27 +--
 services/api/app/models/job.rb                     | 141 +++++-------
 services/api/app/models/node.rb                    |  17 +-
 .../db/migrate/20140918153705_add_state_to_job.rb  |  23 +-
 .../migrate/20140919152716_add_job_id_to_nodes.rb  |   7 -
 .../20140924091559_add_job_uuid_to_nodes.rb        |  13 ++
 services/api/db/structure.sql                      |   4 +-
 services/api/script/crunch-dispatch.rb             |  90 +++-----
 services/api/test/fixtures/nodes.yml               |  40 +++-
 .../functional/arvados/v1/jobs_controller_test.rb  |  21 +-
 .../functional/arvados/v1/nodes_controller_test.rb |  26 +--
 services/api/test/unit/job_test.rb                 |  49 ++--
 services/api/test/unit/node_test.rb                |   6 +
 services/keepstore/handlers.go                     |  18 +-
 42 files changed, 565 insertions(+), 864 deletions(-)
 copy apps/workbench/app/views/application/{show.html.erb => _title_and_buttons.html.erb} (76%)
 create mode 100644 apps/workbench/app/views/jobs/show.html.erb
 copy apps/workbench/app/views/pipeline_instances/{_show_components_running.html.erb => _running_component.html.erb} (68%)
 delete mode 100644 sdk/cli/README.textile
 delete mode 100644 services/api/db/migrate/20140919152716_add_job_id_to_nodes.rb
 create mode 100644 services/api/db/migrate/20140924091559_add_job_uuid_to_nodes.rb

       via  10caf4bc580e7f1646373ef9c1eda1579f0eb52d (commit)
       via  bd11f050966012037da8f4672d6802bfedf64ef2 (commit)
       via  9f6ab8b8b14af04c8971870d1991a3f49a78022f (commit)
       via  06a956718e8dd55a2cdd4a84fcdfb7a3b5a0f635 (commit)
       via  8c97b8ad6f4b026f8bd2626a6d1b76d2fc60f253 (commit)
       via  b25e164d6cfc0712be5856c63f7592145669232d (commit)
       via  9c7058321b88320594fccec767a8326e0bb9db4f (commit)
       via  92211c8bed5aaf3abd83d02c4adbaf2329123bac (commit)
       via  1d5d09e8d1568fdae039571306bd5e56a8273ac7 (commit)
       via  eec77d22e408fe3983cba666c6f5185ecf2d15ec (commit)
       via  4ea6cda50c7fcd3d30ac01e8a421cc68cd4ea23d (commit)
       via  5ef678825d7b436526489e9158a916b605814133 (commit)
       via  d2517f46eb0d1a668ac8124144220436c80d6f65 (commit)
       via  240ab2c50a01531df162850be255a4c4e1084fc2 (commit)
       via  3e3df723e221dadf2512ac4935c1f6f0fe8f7834 (commit)
       via  d23d4ce9e4c52605cb23286b9e9b46a808f7437d (commit)
       via  5af4f00db1cbac83f52bf02b424968fd0ef387b1 (commit)
       via  1fc256cee80eef7aa2178789f23a729ba9f27b79 (commit)
       via  d6478bb286c0bb1e7b8af67fb4800db792200022 (commit)
       via  22c7912d7c62877647fc714cd0bbef8f37a2b120 (commit)
       via  5b2a15b6a4addfc648ef1060be47ffef64e64777 (commit)
       via  d70e5d076e907266c0f40364aaa69fdce449ce9f (commit)
       via  7e27eb2cca7e9e22ad1f56a6f0ecbbc40ad4cb64 (commit)
       via  104244f9ab68f409dbad2272910c21e317994a5d (commit)
       via  2e8aee62b13edd8eac34ac8536d41992c7adbf69 (commit)
       via  80ec2c7fe823b84ba5b3533f3c43d1bf3c627f70 (commit)
       via  96e711607984bd74a682dd3f3819dbc453a6591b (commit)
       via  6fcb589fc76b9251a142dd76d3019c993cfcd71c (commit)
       via  59607e4635868117051d77aa4a84fa9f689c52e7 (commit)
       via  aecc7109edd37aee2388c06a36d5c8ba853b3267 (commit)
       via  ccff8ce154b393512dd4b563853f63a9abeefba4 (commit)
       via  4eaf39dbe947beaaa87e656b470d7f21880ba607 (commit)
       via  148306afed19fc9138a04bcf161d8f24d83b2ac0 (commit)
       via  f9a2ed53565bf921821dff5e2120b6496ac9acdd (commit)
       via  c446dd845656e944c2d3f91f8d00e320c37b66a1 (commit)
       via  15409c5e2b7946ff7f5fd104a6757a4d874448d4 (commit)
       via  c24d0cc28ee40a37d7f0ead787394765386e5413 (commit)
       via  95723281b6a2b9d594f92cc5577c2f41e08338df (commit)
       via  fb9235f1b9abe0661eb7640c4db0ab7001f90f1d (commit)
       via  1ccabc86f9eb3b51e02a3571d5b133fec8258f49 (commit)
       via  5be834f3ac1bdd81f2c40514cdb5795a8585e1f6 (commit)
      from  e56010c12b4cc0695000d54291588fc713ed60b0 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 10caf4bc580e7f1646373ef9c1eda1579f0eb52d
Author: Brett Smith <brett at curoverse.com>
Date:   Wed Sep 24 11:40:52 2014 -0400

    2881: Fixup crunch-dispatch based on review.

diff --git a/services/api/script/crunch-dispatch.rb b/services/api/script/crunch-dispatch.rb
index 44d8a0a..4573f2b 100755
--- a/services/api/script/crunch-dispatch.rb
+++ b/services/api/script/crunch-dispatch.rb
@@ -61,70 +61,43 @@ class Dispatcher
     end
   end
 
-  def crunch_wrapper_is_slurm?
-    Server::Application.config.crunch_job_wrapper.to_s.match /^slurm/
-  end
-
-  def sinfo
-    @@slurm_version ||= Gem::Version.new(`sinfo --version`.match(/\b[\d\.]+\b/)[0])
-    if Gem::Version.new('2.3') <= @@slurm_version
-      `sinfo --noheader -o '%n:%t'`.strip
-    else
-      # Expand rows with hostname ranges (like "foo[1-3,5,9-12]:idle")
-      # into multiple rows with one hostname each.
-      `sinfo --noheader -o '%N:%t'`.split("\n").collect do |line|
-        tokens = line.split ":"
-        if (re = tokens[0].match /^(.*?)\[([-,\d]+)\]$/)
-          re[2].split(",").collect do |range|
-            range = range.split("-").collect(&:to_i)
-            (range[0]..range[-1]).collect do |n|
-              [re[1] + n.to_s, tokens[1..-1]].join ":"
-            end
-          end
-        else
-          tokens.join ":"
-        end
-      end.flatten.join "\n"
+  def slurm_status
+    slurm_nodes = {}
+    `sinfo --noheader -o %n:%t`.each_line do |sinfo_line|
+      hostname, state = sinfo_line.chomp.split(":", 2)
+      state.sub!(/\W+$/, "")
+      state = "down" unless %w(idle alloc down).include? state
+      slurm_nodes[hostname] = {state: state, job: nil}
     end
+    `squeue --noheader -o %n:%j`.each_line do |squeue_line|
+      hostname, job_uuid = squeue_line.chomp.split(":", 2)
+      next unless slurm_nodes[hostname]
+      slurm_nodes[hostname][:job] = job_uuid
+    end
+    slurm_nodes
   end
 
   def update_node_status
-    if crunch_wrapper_is_slurm?
-      @node_state ||= {}
-      node_seen = {}
+    return unless Server::Application.config.crunch_job_wrapper.to_s.match /^slurm/
+    @node_state ||= {}
+    slurm_status.each_pair do |hostname, slurmdata|
+      next if @node_state[hostname] == slurmdata
       begin
-        sinfo.split("\n").
-          each do |line|
-          re = line.match /(\S+?):+(idle|alloc|down)?/
-          next if !re
-
-          _, node_name, node_state = *re
-          node_state = 'down' unless %w(idle alloc down).include? node_state
-
-          # sinfo tells us about a node N times if it is shared by N partitions
-          next if node_seen[node_name]
-          node_seen[node_name] = true
-
-          # update our database (and cache) when a node's state changes
-          if @node_state[node_name] != node_state
-            @node_state[node_name] = node_state
-            node = Node.where('hostname=?', node_name).order(:last_ping_at).last
-            if node
-              $stderr.puts "dispatch: update #{node_name} state to #{node_state}"
-              node.info['slurm_state'] = node_state
-              if node_state == "idle"
-                node.job = nil
-              end
-              if not node.save
-                $stderr.puts "dispatch: failed to update #{node.uuid}: #{node.errors.messages}"
-              end
-            elsif node_state != 'down'
-              $stderr.puts "dispatch: sinfo reports '#{node_name}' is not down, but no node has that name"
-            end
+        node = Node.where('hostname=?', hostname).order(:last_ping_at).last
+        if node
+          $stderr.puts "dispatch: update #{hostname} state to #{slurmdata}"
+          node.info["slurm_state"] = slurmdata[:state]
+          node.job_uuid = slurmdata[:job]
+          if node.save
+            @node_state[hostname] = slurmdata
+          else
+            $stderr.puts "dispatch: failed to update #{node.uuid}: #{node.errors.messages}"
           end
+        elsif slurmdata[:state] != 'down'
+          $stderr.puts "dispatch: SLURM reports '#{hostname}' is not down, but no node has that name"
         end
       rescue => error
-        $stderr.puts "dispatch: error updating node status: #{error}"
+        $stderr.puts "dispatch: error updating #{hostname} node status: #{error}"
       end
     end
   end
@@ -323,10 +296,7 @@ class Dispatcher
         log_truncated: false
       }
       i.close
-      if crunch_wrapper_is_slurm?
-        assign_job_to_nodes(job, nodelist)
-        update_node_status
-      end
+      update_node_status
     end
   end
 

commit bd11f050966012037da8f4672d6802bfedf64ef2
Author: Brett Smith <brett at curoverse.com>
Date:   Wed Sep 24 11:37:16 2014 -0400

    2881: Fixup API server changes based on review.

diff --git a/doc/api/methods/nodes.html.textile.liquid b/doc/api/methods/nodes.html.textile.liquid
index f846086..b2c7924 100644
--- a/doc/api/methods/nodes.html.textile.liquid
+++ b/doc/api/methods/nodes.html.textile.liquid
@@ -77,4 +77,4 @@ table(table table-bordered table-condensed).
 {background:#ccffcc}.|uuid|string|The UUID of the Node in question.|path||
 |node|object||query||
 
-To update a node's job assignment, set the node object's @job_id@ to the UUID of the job, or null to clear the assignment.
+To remove a node's job assignment, update the node object's @job_uuid@ to null.
diff --git a/doc/api/schema/Job.html.textile.liquid b/doc/api/schema/Job.html.textile.liquid
index 5418834..f94f093 100644
--- a/doc/api/schema/Job.html.textile.liquid
+++ b/doc/api/schema/Job.html.textile.liquid
@@ -34,7 +34,7 @@ See "Script versions":#script_version below for more detail about acceptable way
 |running|boolean|Whether the job is running||
 |success|boolean|Whether the job indicated successful completion|Is null if job has not finished|
 |is_locked_by_uuid|string|UUID of the user who has locked this job|Is null if job is not locked. The system user locks the job when starting the job, in order to prevent job attributes from being altered.|
-|nodes|array|List of node objects that have been assigned to this job|Refer to the "Node schema":{{site.baseurl}}/api/schema/Node.html.|
+|node_uuids|array|List of UUID strings for node objects that have been assigned to this job||
 |log|string|Collection UUID|Is null if the job has not finished. After the job runs, the given collection contains a text file with log messages provided by the @arv-crunch-job@ task scheduler as well as the standard error streams provided by the task processes.|
 |tasks_summary|hash|Summary of task completion states.|Example: @{"done":0,"running":4,"todo":2,"failed":0}@|
 |output|string|Collection UUID|Is null if the job has not finished.|
diff --git a/doc/api/schema/Node.html.textile.liquid b/doc/api/schema/Node.html.textile.liquid
index e373751..ff9e882 100644
--- a/doc/api/schema/Node.html.textile.liquid
+++ b/doc/api/schema/Node.html.textile.liquid
@@ -22,7 +22,7 @@ table(table table-bordered table-condensed).
 |hostname|string|||
 |domain|string|||
 |ip_address|string|||
-|job|hash|The job that this node is assigned to work on.  This field is null if the node is idle.  Refer to the "Job schema":{{site.baseurl}}/api/schema/Job.html for details.  If you do not have permission to read the job, you will only see its @running@ attribute.||
+|job_uuid|string|The UUID of the job that this node is assigned to work on.  If you do not have permission to read the job, this will be null.||
 |first_ping_at|datetime|||
 |last_ping_at|datetime|||
 |info|hash|||
diff --git a/services/api/app/controllers/arvados/v1/nodes_controller.rb b/services/api/app/controllers/arvados/v1/nodes_controller.rb
index 7cb75f5..c9ac096 100644
--- a/services/api/app/controllers/arvados/v1/nodes_controller.rb
+++ b/services/api/app/controllers/arvados/v1/nodes_controller.rb
@@ -11,15 +11,8 @@ class Arvados::V1::NodesController < ApplicationController
   end
 
   def update
-    # Translate a job UUID to its numeric ID for the association,
-    # and mark the job readable if we found anything.
-    if resource_attrs[:job_id]
-      search_key = (resource_attrs[:job_id] =~ /\D/) ? :uuid : :id
-      resource_attrs[:job_id] = Job.
-        readable_by(*@read_users).
-        where(search_key => resource_attrs.delete(:job_id)).
-        first.andand.id
-      @object.job_readable = !!resource_attrs[:job_id]
+    if resource_attrs[:job_uuid]
+      @object.job_readable = readable_job_uuids(resource_attrs[:job_uuid]).any?
     end
     super
   end
@@ -59,12 +52,16 @@ class Arvados::V1::NodesController < ApplicationController
       # recently) working
       @objects = model_class.where('last_ping_at >= ?', Time.now - 1.hours)
     end
-    assoc_jobs = Job.
-      readable_by(*@read_users).
-      where(id: @objects.map(&:job_id)).
-      map(&:id)
-    @objects.select(&:job_id).each do |node|
-      node.job_readable = assoc_jobs.include?(node.job_id)
+    assigned_nodes = @objects.select(&:job_uuid)
+    assoc_jobs = readable_job_uuids(*assigned_nodes.map(&:job_uuid))
+    assigned_nodes.each do |node|
+      node.job_readable = assoc_jobs.include?(node.job_uuid)
     end
   end
+
+  protected
+
+  def readable_job_uuids(*uuids)
+    Job.readable_by(*@read_users).select(:uuid).where(uuid: uuids).map(&:uuid)
+  end
 end
diff --git a/services/api/app/models/job.rb b/services/api/app/models/job.rb
index 9eda522..7da6852 100644
--- a/services/api/app/models/job.rb
+++ b/services/api/app/models/job.rb
@@ -16,7 +16,7 @@ class Job < ArvadosModel
   validate :validate_status
 
   has_many :commit_ancestors, :foreign_key => :descendant, :primary_key => :script_version
-  has_many :nodes
+  has_many(:nodes, foreign_key: :job_uuid, primary_key: :uuid)
 
   class SubmitIdReused < StandardError
   end
@@ -46,12 +46,9 @@ class Job < ArvadosModel
     t.add :supplied_script_version
     t.add :docker_image_locator
     t.add :queue_position
-    t.add :nodes
+    t.add :node_uuids
     t.add :description
   end
-  # Nodes have a superuser template for accessing sensitive information.
-  # We need one too so those requests can see associated Job information.
-  api_accessible :superuser, extend: :user
 
   # Supported states for a job
   States = [
@@ -68,6 +65,10 @@ class Job < ArvadosModel
                       running: false)
   end
 
+  def node_uuids
+    nodes.map(&:uuid)
+  end
+
   def self.queue
     self.where('started_at is ? and is_locked_by_uuid is ? and cancelled_at is ? and success is ?',
                nil, nil, nil, nil).
diff --git a/services/api/app/models/node.rb b/services/api/app/models/node.rb
index 0255282..c791f8e 100644
--- a/services/api/app/models/node.rb
+++ b/services/api/app/models/node.rb
@@ -9,9 +9,8 @@ class Node < ArvadosModel
 
   # Only a controller can figure out whether or not the current API tokens
   # have access to the associated Job.  They're expected to set
-  # job_readable=true if they want full Job information to be included in the
-  # API response.
-  belongs_to :job
+  # job_readable=true if the Job UUID can be included in the API response.
+  belongs_to(:job, foreign_key: :job_uuid, primary_key: :uuid)
   attr_accessor :job_readable
 
   MAX_SLOTS = 64
@@ -27,7 +26,7 @@ class Node < ArvadosModel
     t.add :last_ping_at
     t.add :slot_number
     t.add :status
-    t.add :job
+    t.add :api_job_uuid, as: :job_uuid
     t.add :crunch_worker_state
     t.add :properties
   end
@@ -41,13 +40,8 @@ class Node < ArvadosModel
     super || @@domain
   end
 
-  def job
-    db_job = super
-    if db_job and not job_readable
-      {"running" => true}
-    else
-      db_job
-    end
+  def api_job_uuid
+    job_readable ? job_uuid : nil
   end
 
   def crunch_worker_state
diff --git a/services/api/db/migrate/20140919152716_add_job_id_to_nodes.rb b/services/api/db/migrate/20140919152716_add_job_id_to_nodes.rb
deleted file mode 100644
index 7fd8677..0000000
--- a/services/api/db/migrate/20140919152716_add_job_id_to_nodes.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AddJobIdToNodes < ActiveRecord::Migration
-  def change
-    change_table :nodes do |t|
-      t.references :job
-    end
-  end
-end
diff --git a/services/api/db/migrate/20140924091559_add_job_uuid_to_nodes.rb b/services/api/db/migrate/20140924091559_add_job_uuid_to_nodes.rb
new file mode 100644
index 0000000..d8ec20f
--- /dev/null
+++ b/services/api/db/migrate/20140924091559_add_job_uuid_to_nodes.rb
@@ -0,0 +1,13 @@
+class AddJobUuidToNodes < ActiveRecord::Migration
+  def up
+    change_table :nodes do |t|
+      t.column :job_uuid, :string
+    end
+  end
+
+  def down
+    change_table :nodes do |t|
+      t.remove :job_uuid
+    end
+  end
+end
diff --git a/services/api/db/structure.sql b/services/api/db/structure.sql
index e927c51..48bc57a 100644
--- a/services/api/db/structure.sql
+++ b/services/api/db/structure.sql
@@ -642,7 +642,7 @@ CREATE TABLE nodes (
     info text,
     updated_at timestamp without time zone NOT NULL,
     properties text,
-    job_id integer
+    job_uuid character varying(255)
 );
 
 
@@ -2029,4 +2029,4 @@ INSERT INTO schema_migrations (version) VALUES ('20140918153541');
 
 INSERT INTO schema_migrations (version) VALUES ('20140918153705');
 
-INSERT INTO schema_migrations (version) VALUES ('20140919152716');
\ No newline at end of file
+INSERT INTO schema_migrations (version) VALUES ('20140924091559');
\ No newline at end of file
diff --git a/services/api/test/fixtures/nodes.yml b/services/api/test/fixtures/nodes.yml
index 8f2a725..1511501 100644
--- a/services/api/test/fixtures/nodes.yml
+++ b/services/api/test/fixtures/nodes.yml
@@ -7,7 +7,7 @@ busy:
   ip_address: 172.17.2.172
   last_ping_at: <%= 1.minute.ago.to_s(:db) %>
   first_ping_at: <%= 23.hour.ago.to_s(:db) %>
-  job: nearly_finished_job
+  job_uuid: zzzzz-8i9sb-2gx6rz0pjl033w3  # nearly_finished_job
   info:
     ping_secret: "48dpm3b8ijyj3jkr2yczxw0844dqd2752bhll7klodvgz9bg80"
     slurm_state: "alloc"
@@ -21,7 +21,7 @@ down:
   ip_address: 172.17.2.173
   last_ping_at: <%= 1.hour.ago.to_s(:db) %>
   first_ping_at: <%= 23.hour.ago.to_s(:db) %>
-  job: nil
+  job_uuid: ~
   info:
     ping_secret: "2k3i71depad36ugwmlgzilbi4e8n0illb2r8l4efg9mzkb3a1k"
 
@@ -34,7 +34,7 @@ idle:
   ip_address: 172.17.2.174
   last_ping_at: <%= 2.minute.ago.to_s(:db) %>
   first_ping_at: <%= 23.hour.ago.to_s(:db) %>
-  job: nil
+  job_uuid: ~
   info:
     ping_secret: "69udawxvn3zzj45hs8bumvndricrha4lcpi23pd69e44soanc0"
     slurm_state: "idle"
@@ -49,6 +49,7 @@ was_idle_now_down:
   ip_address: 172.17.2.173
   last_ping_at: <%= 1.hour.ago.to_s(:db) %>
   first_ping_at: <%= 23.hour.ago.to_s(:db) %>
+  job_uuid: ~
   info:
     ping_secret: "1bd1yi0x4lb5q4gzqqtrnq30oyj08r8dtdimmanbqw49z1anz2"
     slurm_state: "idle"
diff --git a/services/api/test/functional/arvados/v1/jobs_controller_test.rb b/services/api/test/functional/arvados/v1/jobs_controller_test.rb
index 914f365..a9a49a0 100644
--- a/services/api/test/functional/arvados/v1/jobs_controller_test.rb
+++ b/services/api/test/functional/arvados/v1/jobs_controller_test.rb
@@ -317,27 +317,10 @@ class Arvados::V1::JobsControllerTest < ActionController::TestCase
     end
   end
 
-  test "node assignments with basic info available for the job" do
+  test "job includes assigned nodes" do
     authorize_with :active
     get :show, {id: jobs(:nearly_finished_job).uuid}
     assert_response :success
-    nodes = json_response["nodes"]
-    assert_equal([nodes(:busy).uuid], nodes.map { |n| n["uuid"] })
-    # Make sure the node information does not include superuser fields.
-    refute(nodes.any? { |n| n.has_key?("info") },
-           "non-admin can see privileged node information")
-  end
-
-  test "admin has access to superuser fields in node assignment list" do
-    authorize_with :admin
-    get :show, {id: jobs(:nearly_finished_job).uuid}
-    assert_response :success
-    node_fixture = nodes(:busy)
-    busy_node = json_response["nodes"].
-      select { |n| n["uuid"] == node_fixture.uuid }.first
-    assert_not_nil(busy_node, "assigned node not found in response")
-    assert_not_nil(busy_node["info"], "node info field missing in response")
-    assert_equal(node_fixture.info["ping_secret"],
-                 busy_node["info"]["ping_secret"])
+    assert_equal([nodes(:busy).uuid], json_response["node_uuids"])
   end
 end
diff --git a/services/api/test/functional/arvados/v1/nodes_controller_test.rb b/services/api/test/functional/arvados/v1/nodes_controller_test.rb
index f7bc74e..dd942b6 100644
--- a/services/api/test/functional/arvados/v1/nodes_controller_test.rb
+++ b/services/api/test/functional/arvados/v1/nodes_controller_test.rb
@@ -98,19 +98,14 @@ class Arvados::V1::NodesControllerTest < ActionController::TestCase
     authorize_with :active
     get :show, {id: nodes(:busy).uuid}
     assert_response :success
-    assert_equal(jobs(:nearly_finished_job).uuid,
-                 json_response["job"].andand["uuid"])
+    assert_equal(jobs(:nearly_finished_job).uuid, json_response["job_uuid"])
   end
 
-  test "user without job read permission only sees job running state" do
+  test "user without job read permission can't see job" do
     authorize_with :spectator
     get :show, {id: nodes(:busy).uuid}
     assert_response :success
-    node_job = json_response["job"] || {}
-    assert(node_job.delete("running"),
-           "spectator can't see that node has a job assigned")
-    assert_empty(node_job,
-                 "spectator can see details about node's assigned job")
+    assert_nil(json_response["job"], "spectator can see node's assigned job")
   end
 
   test "admin can associate a job with a node" do
@@ -119,12 +114,12 @@ class Arvados::V1::NodesControllerTest < ActionController::TestCase
     authorize_with :admin
     post :update, {
       id: changed_node.uuid,
-      node: {job_id: assigned_job.uuid},
+      node: {job_uuid: assigned_job.uuid},
     }
     assert_response :success
     assert_equal(changed_node.hostname, json_response["hostname"],
                  "hostname mismatch after defining job")
-    assert_equal(assigned_job.uuid, json_response["job"].andand["uuid"],
+    assert_equal(assigned_job.uuid, json_response["job_uuid"],
                  "mismatch in node's assigned job UUID")
   end
 
@@ -132,7 +127,7 @@ class Arvados::V1::NodesControllerTest < ActionController::TestCase
     authorize_with :active
     post :update, {
       id: nodes(:idle).uuid,
-      node: {job_id: jobs(:queued).uuid},
+      node: {job_uuid: jobs(:queued).uuid},
     }
     assert_response 403
   end
@@ -142,12 +137,12 @@ class Arvados::V1::NodesControllerTest < ActionController::TestCase
     authorize_with :admin
     post :update, {
       id: changed_node.uuid,
-      node: {job_id: nil},
+      node: {job_uuid: nil},
     }
     assert_response :success
     assert_equal(changed_node.hostname, json_response["hostname"],
                  "hostname mismatch after defining job")
-    assert_nil(json_response["job"],
+    assert_nil(json_response["job_uuid"],
                "node still has job assignment after update")
   end
 
@@ -155,7 +150,7 @@ class Arvados::V1::NodesControllerTest < ActionController::TestCase
     authorize_with :project_viewer
     post :update, {
       id: nodes(:busy).uuid,
-      node: {job_id: nil},
+      node: {job_uuid: nil},
     }
     assert_response 403
   end
@@ -167,8 +162,7 @@ class Arvados::V1::NodesControllerTest < ActionController::TestCase
       node: {last_ping_at: 1.second.ago},
     }
     assert_response :success
-    assert_equal(jobs(:nearly_finished_job).uuid,
-                 json_response["job"].andand["uuid"],
+    assert_equal(jobs(:nearly_finished_job).uuid, json_response["job_uuid"],
                  "mismatched job UUID after ping update")
   end
 end

commit 9f6ab8b8b14af04c8971870d1991a3f49a78022f
Merge: e56010c 06a9567
Author: Brett Smith <brett at curoverse.com>
Date:   Wed Sep 24 09:01:15 2014 -0400

    Merge branch 'master' into 2881-node-has-job-wip

diff --cc services/api/app/models/job.rb
index 7b2942e,b4aa625..9eda522
--- a/services/api/app/models/job.rb
+++ b/services/api/app/models/job.rb
@@@ -9,14 -9,13 +9,14 @@@ class Job < ArvadosMode
    before_create :ensure_unique_submit_id
    after_commit :trigger_crunch_dispatch_if_cancelled, :on => :update
    before_validation :set_priority
+   before_validation :update_timestamps_when_state_changes
+   before_validation :update_state_from_old_state_attrs
    validate :ensure_script_version_is_commit
    validate :find_docker_image_locator
-   before_validation :verify_status
-   before_create :set_state_before_save
-   before_save :set_state_before_save
+   validate :validate_status
  
    has_many :commit_ancestors, :foreign_key => :descendant, :primary_key => :script_version
 +  has_many :nodes
  
    class SubmitIdReused < StandardError
    end
diff --cc services/api/app/models/node.rb
index 0a8358c,119a0ed..0255282
--- a/services/api/app/models/node.rb
+++ b/services/api/app/models/node.rb
@@@ -41,16 -33,8 +41,17 @@@ class Node < ArvadosMode
      super || @@domain
    end
  
 +  def job
 +    db_job = super
 +    if db_job and not job_readable
 +      {"running" => true}
 +    else
 +      db_job
 +    end
 +  end
 +
    def crunch_worker_state
+     return 'down' if slot_number.nil?
      case self.info.andand['slurm_state']
      when 'alloc', 'comp'
        'busy'
diff --cc services/api/test/fixtures/nodes.yml
index bee7472,f282e7e..8f2a725
--- a/services/api/test/fixtures/nodes.yml
+++ b/services/api/test/fixtures/nodes.yml
@@@ -6,10 -7,9 +7,10 @@@ busy
    ip_address: 172.17.2.172
    last_ping_at: <%= 1.minute.ago.to_s(:db) %>
    first_ping_at: <%= 23.hour.ago.to_s(:db) %>
 +  job: nearly_finished_job
    info:
-     :ping_secret: "48dpm3b8ijyj3jkr2yczxw0844dqd2752bhll7klodvgz9bg80"
-     :slurm_state: "alloc"
+     ping_secret: "48dpm3b8ijyj3jkr2yczxw0844dqd2752bhll7klodvgz9bg80"
+     slurm_state: "alloc"
  
  down:
    uuid: zzzzz-7ekkf-2vbompg3ecc6e2s
@@@ -19,9 -20,8 +21,9 @@@
    ip_address: 172.17.2.173
    last_ping_at: <%= 1.hour.ago.to_s(:db) %>
    first_ping_at: <%= 23.hour.ago.to_s(:db) %>
 +  job: nil
    info:
-     :ping_secret: "2k3i71depad36ugwmlgzilbi4e8n0illb2r8l4efg9mzkb3a1k"
+     ping_secret: "2k3i71depad36ugwmlgzilbi4e8n0illb2r8l4efg9mzkb3a1k"
  
  idle:
    uuid: zzzzz-7ekkf-2z3mc76g2q73aio
@@@ -31,8 -32,21 +34,22 @@@
    ip_address: 172.17.2.174
    last_ping_at: <%= 2.minute.ago.to_s(:db) %>
    first_ping_at: <%= 23.hour.ago.to_s(:db) %>
 +  job: nil
    info:
-     :ping_secret: "69udawxvn3zzj45hs8bumvndricrha4lcpi23pd69e44soanc0"
-     :slurm_state: "idle"
+     ping_secret: "69udawxvn3zzj45hs8bumvndricrha4lcpi23pd69e44soanc0"
+     slurm_state: "idle"
+     total_cpu_cores: 16
+ 
+ was_idle_now_down:
+   uuid: zzzzz-7ekkf-xuzpkdasl0uzwyz
+   owner_uuid: zzzzz-tpzed-000000000000000
+   hostname: compute3
+   slot_number: ~
+   domain: ""
+   ip_address: 172.17.2.173
+   last_ping_at: <%= 1.hour.ago.to_s(:db) %>
+   first_ping_at: <%= 23.hour.ago.to_s(:db) %>
+   info:
+     ping_secret: "1bd1yi0x4lb5q4gzqqtrnq30oyj08r8dtdimmanbqw49z1anz2"
+     slurm_state: "idle"
      total_cpu_cores: 16

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list