Merge branch 'master' of git.curoverse.com:arvados into 6465-optimize-workbench-integ...
authorManoj <jonam33@gmail.com>
Thu, 16 Jul 2015 19:18:13 +0000 (15:18 -0400)
committerManoj <jonam33@gmail.com>
Thu, 16 Jul 2015 19:18:13 +0000 (15:18 -0400)
docker/build_tools/Makefile
sdk/python/tests/run_test_server.py
services/api/app/controllers/arvados/v1/virtual_machines_controller.rb
services/api/test/functional/arvados/v1/virtual_machines_controller_test.rb

index 6d014b91fa1665d031ea1caa283b576028c8ed70..75702960133b3be2555b851babb9d5bf92e4c9a3 100644 (file)
@@ -20,8 +20,14 @@ clean:
 DEBIAN_IMAGE := $(shell $(DOCKER) images -q arvados/debian |head -n1)
 
 REALCLEAN_CONTAINERS := $(shell $(DOCKER) ps -a |grep -e arvados -e api_server -e keep_server -e keep_proxy_server -e doc_server -e workbench_server |cut -f 1 -d' ')
-REALCLEAN_IMAGES := $(shell $(DOCKER) images -q arvados/* |grep -v $(DEBIAN_IMAGE) 2>/dev/null)
-DEEPCLEAN_IMAGES := $(shell $(DOCKER) images -q arvados/*)
+# Generate a list of docker images tagged as arvados/*
+# but exclude those tagged as arvados/build
+ADI_TEMPFILE := $(shell mktemp)
+ARVADOS_DOCKER_IMAGES := $(shell $(DOCKER) images -q arvados/* |sort > $(ADI_TEMPFILE))
+ABDI_TEMPFILE := $(shell mktemp)
+ARVADOS_BUILD_DOCKER_IMAGES := $(shell $(DOCKER) images -q arvados/build |sort > $(ABDI_TEMPFILE))
+REALCLEAN_IMAGES := $(shell comm -3 $(ADI_TEMPFILE) $(ABDI_TEMPFILE) |grep -v $(DEBIAN_IMAGE) 2>/dev/null)
+DEEPCLEAN_IMAGES := $(shell comm -3 $(ADI_TEMPFILE) $(ABDI_TEMPFILE))
 SKYDNS_CONTAINERS := $(shell $(DOCKER) ps -a |grep -e crosbymichael/skydns -e crosbymichael/skydock |cut -f 1 -d' ')
 SKYDNS_IMAGES := $(shell $(DOCKER) images -q crosbymichael/skyd*)
 
index 02f65e6caf47470928fbbe7fcbee2cafb490e817..31493cc10ad534989ab1efeb83a661a23bd69b92 100644 (file)
@@ -115,6 +115,32 @@ def find_available_port():
     sock.close()
     return port
 
+def _wait_until_port_listens(port, timeout=10):
+    """Wait for a process to start listening on the given port.
+
+    If nothing listens on the port within the specified timeout (given
+    in seconds), print a warning on stderr before returning.
+    """
+    try:
+        subprocess.check_output(['fuser', '-l'])
+    except subprocess.CalledProcessError:
+        print("WARNING: No `fuser` -- cannot wait for port to listen. "+
+              "Sleeping 0.5 and hoping for the best.")
+        time.sleep(0.5)
+        return
+    deadline = time.time() + timeout
+    while time.time() < deadline:
+        try:
+            fuser_says = subprocess.check_output(['fuser', str(port)+'/tcp'])
+        except subprocess.CalledProcessError:
+            time.sleep(0.1)
+            continue
+        return
+    print(
+        "WARNING: Nothing is listening on port {} (waited {} seconds).".
+        format(port, timeout),
+        file=sys.stderr)
+
 def run(leave_running_atexit=False):
     """Ensure an API server is running, and ARVADOS_API_* env vars have
     admin credentials for it.
@@ -224,8 +250,10 @@ def run(leave_running_atexit=False):
     my_api_host = match.group(1)
     os.environ['ARVADOS_API_HOST'] = my_api_host
 
-    # Make sure the server has written its pid file before continuing
+    # Make sure the server has written its pid file and started
+    # listening on its TCP port
     find_server_pid(pid_file)
+    _wait_until_port_listens(port)
 
     reset()
     os.chdir(restore_cwd)
@@ -289,6 +317,8 @@ def _start_keep(n, keep_args):
     with open("{}/keep{}.volume".format(TEST_TMPDIR, n), 'w') as f:
         f.write(keep0)
 
+    _wait_until_port_listens(port)
+
     return port
 
 def run_keep(blob_signing_key=None, enforce_permissions=False):
@@ -369,6 +399,7 @@ def run_keep_proxy():
     }}).execute()
     os.environ["ARVADOS_KEEP_PROXY"] = "http://localhost:{}".format(port)
     _setport('keepproxy', port)
+    _wait_until_port_listens(port)
 
 def stop_keep_proxy():
     if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
@@ -392,6 +423,7 @@ def run_arv_git_httpd():
     with open(_pidfile('arv-git-httpd'), 'w') as f:
         f.write(str(agh.pid))
     _setport('arv-git-httpd', gitport)
+    _wait_until_port_listens(gitport)
 
 def stop_arv_git_httpd():
     if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
index 519178b0bbcf319426dbca39d181be58ef800420..84251db470fff95bbbc23f27397263124464c9d3 100644 (file)
@@ -9,32 +9,40 @@ class Arvados::V1::VirtualMachinesController < ApplicationController
   end
 
   def get_all_logins
-    @users = {}
-    User.includes(:authorized_keys).all.each do |u|
-      @users[u.uuid] = u
-    end
     @response = []
-    @vms = VirtualMachine.includes(:login_permissions)
+    @vms = VirtualMachine.eager_load :login_permissions
     if @object
-      @vms = @vms.where('uuid=?', @object.uuid)
+      @vms = @vms.where uuid: @object.uuid
     else
       @vms = @vms.all
     end
+    @users = {}
+    User.eager_load(:authorized_keys).
+      where('users.uuid in (?)',
+            @vms.map { |vm| vm.login_permissions.map &:tail_uuid }.flatten.uniq).
+      each do |u|
+      @users[u.uuid] = u
+    end
     @vms.each do |vm|
       vm.login_permissions.each do |perm|
         user_uuid = perm.tail_uuid
-        @users[user_uuid].andand.authorized_keys.andand.each do |ak|
-          unless perm.properties['username'].blank?
-            @response << {
-              username: perm.properties['username'],
-              hostname: vm.hostname,
-              groups: (perm.properties["groups"].to_a rescue []),
-              public_key: ak.public_key,
-              user_uuid: user_uuid,
-              virtual_machine_uuid: vm.uuid,
-              authorized_key_uuid: ak.uuid
-            }
-          end
+        next if not @users[user_uuid]
+        next if perm.properties['username'].blank?
+        aks = @users[user_uuid].authorized_keys
+        if aks.empty?
+          # We'll emit one entry, with no public key.
+          aks = [nil]
+        end
+        aks.each do |ak|
+          @response << {
+            username: perm.properties['username'],
+            hostname: vm.hostname,
+            groups: (perm.properties['groups'].to_a rescue []),
+            public_key: ak ? ak.public_key : nil,
+            user_uuid: user_uuid,
+            virtual_machine_uuid: vm.uuid,
+            authorized_key_uuid: ak ? ak.uuid : nil,
+          }
         end
       end
     end
index 8ca2a94c8dccae653c23323dc58d7073eece8254..7c3270c5c5112126b52f90c6fc593da44ef7924e 100644 (file)
@@ -44,4 +44,25 @@ class Arvados::V1::VirtualMachinesControllerTest < ActionController::TestCase
     assert_empty(json_response.
                  select { |login| login["user_uuid"] == spectator_uuid })
   end
+
+  test "logins without ssh keys are listed" do
+    u, vm = nil
+    act_as_system_user do
+      u = create :active_user, first_name: 'Bob', last_name: 'Blogin'
+      vm = VirtualMachine.create! hostname: 'foo.shell'
+      Link.create!(tail_uuid: u.uuid,
+                   head_uuid: vm.uuid,
+                   link_class: 'permission',
+                   name: 'can_login',
+                   properties: {'username' => 'bobblogin'})
+    end
+    authorize_with :admin
+    get :logins, id: vm.uuid
+    assert_response :success
+    assert_equal 1, json_response['items'].length
+    assert_equal nil, json_response['items'][0]['public_key']
+    assert_equal nil, json_response['items'][0]['authorized_key_uuid']
+    assert_equal u.uuid, json_response['items'][0]['user_uuid']
+    assert_equal 'bobblogin', json_response['items'][0]['username']
+  end
 end