Merge branch '13338-wb-run-wf-proj' refs #13338
authorPeter Amstutz <pamstutz@veritasgenetics.com>
Tue, 1 May 2018 17:35:05 +0000 (13:35 -0400)
committerPeter Amstutz <pamstutz@veritasgenetics.com>
Tue, 1 May 2018 17:35:05 +0000 (13:35 -0400)
Arvados-DCO-1.1-Signed-off-by: Peter Amstutz <pamstutz@veritasgenetics.com>

apps/workbench/test/integration/collections_test.rb
doc/install/install-postgresql.html.textile.liquid
sdk/go/arvadostest/run_servers.go
services/keep-web/handler.go
services/keep-web/handler_test.go
services/nodemanager/tests/integration_test.py
tools/crunchstat-summary/crunchstat_summary/reader.py

index 443130a4a92c60cd6a46a4f4ca749d9712a5a7f9..9aa868c2b8b90ee2dab6a1bbf94dae39d305df96 100644 (file)
@@ -88,7 +88,7 @@ class CollectionsTest < ActionDispatch::IntegrationTest
         link
       end
     end
-    assert_equal(['foo'], hrefs.compact.sort,
+    assert_equal(['./foo'], hrefs.compact.sort,
                  "download page did provide strictly file links")
     click_link "foo"
     assert_text "foo\nfile\n"
index 599730926a0f29bf17b4ef73c6aa2a0a6ee75cef..aabe6629d939c36b782eedc2185d665f485aa3b2 100644 (file)
@@ -9,16 +9,18 @@ Copyright (C) The Arvados Authors. All rights reserved.
 SPDX-License-Identifier: CC-BY-SA-3.0
 {% endcomment %}
 
-Two Arvados Rails servers store data in a PostgreSQL database: the SSO server, and the API server.  The API server requires at least version *9.3* of PostgreSQL.  Beyond that, you have the flexibility to deploy PostgreSQL any way that the Rails servers will be able to connect to it.  Our recommended deployment strategy is:
+Two Arvados Rails servers store data in a PostgreSQL database: the SSO server, and the API server.  The API server requires at least version *9.4* of PostgreSQL.  Beyond that, you have the flexibility to deploy PostgreSQL any way that the Rails servers will be able to connect to it.  Our recommended deployment strategy is:
 
 * Install PostgreSQL on the the same host as the SSO server, and dedicate that install to hosting the SSO database.  This provides the best security for the SSO server, because the database does not have to accept any client connections over the network.  Typical load on the SSO server is light enough that deploying both it and its database on the same host does not compromise performance.
 * If you want to provide the most scalability for your Arvados cluster, install PostgreSQL for the API server on a dedicated host.  This gives you the most flexibility to avoid resource contention, and tune performance separately for the API server and its database.  If performance is less of a concern for your installation, you can install PostgreSQL on the API server host directly, as with the SSO server.
 
 Find the section for your distribution below, and follow it to install PostgreSQL on each host where you will deploy it.  Then follow the steps in the later section(s) to set up PostgreSQL for the Arvados service(s) that need it.
 
-h2. Install PostgreSQL 9.3+
+It is important to make sure that autovacuum is enabled for the PostgreSQL database that backs the API server. Autovacuum is enabled by default since PostgreSQL 8.3.
 
-The API server requires at least version *9.3* of PostgreSQL.
+h2. Install PostgreSQL 9.4+
+
+The API server requires at least version *9.4* of PostgreSQL.
 
 h3(#centos7). CentOS 7
 {% assign rh_version = "7" %}
@@ -39,7 +41,9 @@ h3(#centos7). CentOS 7
 
 h3(#debian). Debian or Ubuntu
 
-Debian 8 (Jessie) and Ubuntu 14.04 (Trusty) and later versions include a sufficiently recent version of Postgres.
+Debian 8 (Jessie) and Ubuntu 16.04 (Xenial) and later versions include a sufficiently recent version of Postgres.
+
+Ubuntu 14.04 (Trusty) requires an updated PostgreSQL version, see "the PostgreSQL ubuntu repository":https://www.postgresql.org/download/linux/ubuntu/
 
 # Install PostgreSQL:
   <notextile><pre>~$ <span class="userinput">sudo apt-get install postgresql</span></pre></notextile>
index dcc2fb084ee9645aca498b820f6a2df6bf20204e..490a7f3e03b470296edfb671e82c864cb23076b6 100644 (file)
@@ -104,7 +104,10 @@ func StopAPI() {
        defer os.Chdir(cwd)
        chdirToPythonTests()
 
-       bgRun(exec.Command("python", "run_test_server.py", "stop"))
+       cmd := exec.Command("python", "run_test_server.py", "stop")
+       bgRun(cmd)
+       // Without Wait, "go test" in go1.10.1 tends to hang. https://github.com/golang/go/issues/24050
+       cmd.Wait()
 }
 
 // StartKeep starts the given number of keep servers,
@@ -132,12 +135,9 @@ func StopKeep(numKeepServers int) {
        chdirToPythonTests()
 
        cmd := exec.Command("python", "run_test_server.py", "stop_keep", "--num-keep-servers", strconv.Itoa(numKeepServers))
-       cmd.Stdin = nil
-       cmd.Stderr = os.Stderr
-       cmd.Stdout = os.Stderr
-       if err := cmd.Run(); err != nil {
-               log.Fatalf("%+v: %s", cmd.Args, err)
-       }
+       bgRun(cmd)
+       // Without Wait, "go test" in go1.10.1 tends to hang. https://github.com/golang/go/issues/24050
+       cmd.Wait()
 }
 
 // Start cmd, with stderr and stdout redirected to our own
index 8b61b54b97564d9d40dccfe9b5587acebc021e08..f69f396f263d7c752bb4d42280ce077288aeff3c 100644 (file)
@@ -615,9 +615,9 @@ the entire directory tree with wget, try:</P>
 <UL>
 {{range .Files}}
 {{if .IsDir }}
-  <LI>{{" " | printf "%15s  " | nbsp}}<A href="{{.Name}}/">{{.Name}}/</A></LI>
+  <LI>{{" " | printf "%15s  " | nbsp}}<A href="{{print "./" .Name}}/">{{.Name}}/</A></LI>
 {{else}}
-  <LI>{{.Size | printf "%15d  " | nbsp}}<A href="{{.Name}}">{{.Name}}</A></LI>
+  <LI>{{.Size | printf "%15d  " | nbsp}}<A href="{{print "./" .Name}}">{{.Name}}</A></LI>
 {{end}}
 {{end}}
 </UL>
index 4894ceb70b2087d21bf08cd3bae1e20fd78a43e0..06401f4825e29595bbefa3b9db368c1576ad2e56 100644 (file)
@@ -12,10 +12,12 @@ import (
        "net/http"
        "net/http/httptest"
        "net/url"
+       "os"
        "path/filepath"
        "regexp"
        "strings"
 
+       "git.curoverse.com/arvados.git/sdk/go/arvados"
        "git.curoverse.com/arvados.git/sdk/go/arvadostest"
        "git.curoverse.com/arvados.git/sdk/go/auth"
        check "gopkg.in/check.v1"
@@ -430,6 +432,38 @@ func (s *IntegrationSuite) TestAnonymousTokenError(c *check.C) {
        )
 }
 
+func (s *IntegrationSuite) TestSpecialCharsInPath(c *check.C) {
+       s.testServer.Config.AttachmentOnlyHost = "download.example.com"
+
+       client := s.testServer.Config.Client
+       client.AuthToken = arvadostest.ActiveToken
+       fs, err := (&arvados.Collection{}).FileSystem(&client, nil)
+       c.Assert(err, check.IsNil)
+       f, err := fs.OpenFile("https:\\\"odd' path chars", os.O_CREATE, 0777)
+       c.Assert(err, check.IsNil)
+       f.Close()
+       mtxt, err := fs.MarshalManifest(".")
+       c.Assert(err, check.IsNil)
+       coll := arvados.Collection{ManifestText: mtxt}
+       err = client.RequestAndDecode(&coll, "POST", "arvados/v1/collections", client.UpdateBody(coll), nil)
+       c.Assert(err, check.IsNil)
+
+       u, _ := url.Parse("http://download.example.com/c=" + coll.UUID + "/")
+       req := &http.Request{
+               Method:     "GET",
+               Host:       u.Host,
+               URL:        u,
+               RequestURI: u.RequestURI(),
+               Header: http.Header{
+                       "Authorization": {"Bearer " + client.AuthToken},
+               },
+       }
+       resp := httptest.NewRecorder()
+       s.testServer.Handler.ServeHTTP(resp, req)
+       c.Check(resp.Code, check.Equals, http.StatusOK)
+       c.Check(resp.Body.String(), check.Matches, `(?ms).*href="./https:%5c%22odd%27%20path%20chars"\S+https:\\&#34;odd&#39; path chars.*`)
+}
+
 // XHRs can't follow redirect-with-cookie so they rely on method=POST
 // and disposition=attachment (telling us it's acceptable to respond
 // with content instead of a redirect) and an Origin header that gets
@@ -660,7 +694,7 @@ func (s *IntegrationSuite) TestDirectoryListing(c *check.C) {
                } else {
                        c.Check(resp.Code, check.Equals, http.StatusOK)
                        for _, e := range trial.expect {
-                               c.Check(resp.Body.String(), check.Matches, `(?ms).*href="`+e+`".*`)
+                               c.Check(resp.Body.String(), check.Matches, `(?ms).*href="./`+e+`".*`)
                        }
                        c.Check(resp.Body.String(), check.Matches, `(?ms).*--cut-dirs=`+fmt.Sprintf("%d", trial.cutDirs)+` .*`)
                }
index 508e626639cb2857e989e9f342fbaf8be2da8aba..1699b5739015864b92fc465f39acb8df43e8b6e3 100755 (executable)
@@ -21,6 +21,7 @@ import logging
 import stat
 import tempfile
 import shutil
+import errno
 from functools import partial
 import arvados
 import StringIO
@@ -256,7 +257,18 @@ def run_test(name, actions, checks, driver_class, jobs, provider):
         logger.info("%s passed", name)
     else:
         if isinstance(detail_content, StringIO.StringIO):
-            sys.stderr.write(detail_content.getvalue())
+            detail_content.seek(0)
+            chunk = detail_content.read(4096)
+            while chunk:
+                try:
+                    sys.stderr.write(chunk)
+                    chunk = detail_content.read(4096)
+                except IOError as e:
+                    if e.errno == errno.EAGAIN:
+                        # try again (probably pipe buffer full)
+                        pass
+                    else:
+                        raise
         logger.info("%s failed", name)
 
     return code
index e8f0861be49350eddc232bd8826a4681af3a424f..98dda673d5a3ab70d65ab1d3989b49f539959b69 100644 (file)
@@ -46,8 +46,9 @@ class LiveLogReader(object):
     EOF = None
 
     def __init__(self, job_uuid):
-        logger.debug('load stderr events for job %s', job_uuid)
         self.job_uuid = job_uuid
+        self.event_types = (['stderr'] if '-8i9sb-' in job_uuid else ['crunchstat', 'arv-mount'])
+        logger.debug('load %s events for job %s', self.event_types, self.job_uuid)
 
     def __str__(self):
         return self.job_uuid
@@ -57,7 +58,7 @@ class LiveLogReader(object):
         last_id = 0
         filters = [
             ['object_uuid', '=', self.job_uuid],
-            ['event_type', '=', 'stderr']]
+            ['event_type', 'in', self.event_types]]
         try:
             while True:
                 page = arvados.api().logs().index(