[ARVADOS] created: da57a99777f022ae6f6a4122c7940d00339f5503

git at public.curoverse.com git at public.curoverse.com
Fri May 1 03:11:37 EDT 2015


        at  da57a99777f022ae6f6a4122c7940d00339f5503 (commit)


commit da57a99777f022ae6f6a4122c7940d00339f5503
Author: Tom Clegg <tom at curoverse.com>
Date:   Fri May 1 03:13:47 2015 -0400

    5724: gofmt fixes.

diff --git a/services/keepstore/handler_test.go b/services/keepstore/handler_test.go
index 71da956..5b65cd8 100644
--- a/services/keepstore/handler_test.go
+++ b/services/keepstore/handler_test.go
@@ -228,13 +228,13 @@ func TestPutAndDeleteSkipReadonlyVolumes(t *testing.T) {
 	IssueRequest(
 		&RequestTester{
 			method:       "PUT",
-			uri:          "/"+TEST_HASH,
+			uri:          "/" + TEST_HASH,
 			request_body: TEST_BLOCK,
 		})
 	IssueRequest(
 		&RequestTester{
 			method:       "DELETE",
-			uri:          "/"+TEST_HASH,
+			uri:          "/" + TEST_HASH,
 			request_body: TEST_BLOCK,
 			api_token:    data_manager_token,
 		})
diff --git a/services/keepstore/keepstore_test.go b/services/keepstore/keepstore_test.go
index a6e29f4..8874674 100644
--- a/services/keepstore/keepstore_test.go
+++ b/services/keepstore/keepstore_test.go
@@ -345,7 +345,7 @@ func TestDiscoverTmpfs(t *testing.T) {
 			t.Errorf("Discover returned %s, expected %s\n",
 				resultVols[i].(*UnixVolume).root, tmpdir)
 		}
-		if expectReadonly := i % 2 == 1; expectReadonly != resultVols[i].(*UnixVolume).readonly {
+		if expectReadonly := i%2 == 1; expectReadonly != resultVols[i].(*UnixVolume).readonly {
 			t.Errorf("Discover added %s with readonly=%v, should be %v",
 				tmpdir, !expectReadonly, expectReadonly)
 		}
diff --git a/services/keepstore/perms_test.go b/services/keepstore/perms_test.go
index d0081cd..7367dbf 100644
--- a/services/keepstore/perms_test.go
+++ b/services/keepstore/perms_test.go
@@ -48,15 +48,15 @@ func TestVerifySignatureExtraHints(t *testing.T) {
 	PermissionSecret = []byte(known_key)
 	defer func() { PermissionSecret = nil }()
 
-	if !VerifySignature(known_locator + "+K at xyzzy" + known_sig_hint, known_token) {
+	if !VerifySignature(known_locator+"+K at xyzzy"+known_sig_hint, known_token) {
 		t.Fatal("Verify cannot handle hint before permission signature")
 	}
 
-	if !VerifySignature(known_locator + known_sig_hint + "+Zfoo", known_token) {
+	if !VerifySignature(known_locator+known_sig_hint+"+Zfoo", known_token) {
 		t.Fatal("Verify cannot handle hint after permission signature")
 	}
 
-	if !VerifySignature(known_locator + "+K at xyzzy" + known_sig_hint + "+Zfoo", known_token) {
+	if !VerifySignature(known_locator+"+K at xyzzy"+known_sig_hint+"+Zfoo", known_token) {
 		t.Fatal("Verify cannot handle hints around permission signature")
 	}
 }
@@ -66,11 +66,11 @@ func TestVerifySignatureWrongSize(t *testing.T) {
 	PermissionSecret = []byte(known_key)
 	defer func() { PermissionSecret = nil }()
 
-	if !VerifySignature(known_hash + "+999999" + known_sig_hint, known_token) {
+	if !VerifySignature(known_hash+"+999999"+known_sig_hint, known_token) {
 		t.Fatal("Verify cannot handle incorrect size hint")
 	}
 
-	if !VerifySignature(known_hash + known_sig_hint, known_token) {
+	if !VerifySignature(known_hash+known_sig_hint, known_token) {
 		t.Fatal("Verify cannot handle missing size hint")
 	}
 }
diff --git a/services/keepstore/trash_worker_test.go b/services/keepstore/trash_worker_test.go
index a11756b..0511b48 100644
--- a/services/keepstore/trash_worker_test.go
+++ b/services/keepstore/trash_worker_test.go
@@ -15,8 +15,8 @@ type TrashWorkerTestData struct {
 	Block2      []byte
 	BlockMtime2 int64
 
-	CreateData       bool
-	CreateInVolume1  bool
+	CreateData      bool
+	CreateInVolume1 bool
 
 	UseTrashLifeTime bool
 	DifferentMtimes  bool
@@ -202,7 +202,7 @@ func performTrashWorkerTest(testData TrashWorkerTestData, t *testing.T) {
 		}
 	}
 
-	oldBlockTime := time.Now().Add(-blob_signature_ttl-time.Minute)
+	oldBlockTime := time.Now().Add(-blob_signature_ttl - time.Minute)
 
 	// Create TrashRequest for the test
 	trashRequest := TrashRequest{
diff --git a/services/keepstore/volume.go b/services/keepstore/volume.go
index 0f9fcff..f581b28 100644
--- a/services/keepstore/volume.go
+++ b/services/keepstore/volume.go
@@ -69,7 +69,7 @@ func (vm *RRVolumeManager) NextWritable() Volume {
 		return nil
 	}
 	i := atomic.AddUint32(&vm.counter, 1)
-	return vm.writables[i % uint32(len(vm.writables))]
+	return vm.writables[i%uint32(len(vm.writables))]
 }
 
 func (vm *RRVolumeManager) Close() {
diff --git a/services/keepstore/volume_test.go b/services/keepstore/volume_test.go
index 3d6b95f..379c890 100644
--- a/services/keepstore/volume_test.go
+++ b/services/keepstore/volume_test.go
@@ -14,15 +14,15 @@ type MockVolume struct {
 	Store      map[string][]byte
 	Timestamps map[string]time.Time
 	// Bad volumes return an error for every operation.
-	Bad        bool
+	Bad bool
 	// Touchable volumes' Touch() method succeeds for a locator
 	// that has been Put().
-	Touchable  bool
+	Touchable bool
 	// Readonly volumes return an error for Put, Delete, and
 	// Touch.
-	Readonly   bool
-	called     map[string]int
-	mutex      sync.Mutex
+	Readonly bool
+	called   map[string]int
+	mutex    sync.Mutex
 }
 
 // CreateMockVolume returns a non-Bad, non-Readonly, Touchable mock
diff --git a/services/keepstore/volume_unix.go b/services/keepstore/volume_unix.go
index f825988..3b7c993 100644
--- a/services/keepstore/volume_unix.go
+++ b/services/keepstore/volume_unix.go
@@ -70,12 +70,12 @@ func (v *UnixVolume) IOHandler() {
 
 func MakeUnixVolume(root string, serialize bool, readonly bool) *UnixVolume {
 	v := &UnixVolume{
-		root: root,
-		queue: nil,
+		root:     root,
+		queue:    nil,
 		readonly: readonly,
 	}
 	if serialize {
-		v.queue =make(chan *IORequest)
+		v.queue = make(chan *IORequest)
 		go v.IOHandler()
 	}
 	return v

commit 5bf77ec1bbbd91ee2f1d063d963850c600251ca7
Author: Tom Clegg <tom at curoverse.com>
Date:   Fri May 1 03:11:46 2015 -0400

    5724: Rename -permission-* flags to -blob-sign* to match apiserver. Tidy up some time-related code.

diff --git a/services/keepstore/handler_test.go b/services/keepstore/handler_test.go
index 1765ddf..71da956 100644
--- a/services/keepstore/handler_test.go
+++ b/services/keepstore/handler_test.go
@@ -54,11 +54,11 @@ func TestGetHandler(t *testing.T) {
 	// Turn on permission settings so we can generate signed locators.
 	enforce_permissions = true
 	PermissionSecret = []byte(known_key)
-	permission_ttl = time.Duration(300) * time.Second
+	blob_signature_ttl = 300 * time.Second
 
 	var (
 		unsigned_locator  = "/" + TEST_HASH
-		valid_timestamp   = time.Now().Add(permission_ttl)
+		valid_timestamp   = time.Now().Add(blob_signature_ttl)
 		expired_timestamp = time.Now().Add(-time.Hour)
 		signed_locator    = "/" + SignLocator(TEST_HASH, known_token, valid_timestamp)
 		expired_locator   = "/" + SignLocator(TEST_HASH, known_token, expired_timestamp)
@@ -176,7 +176,7 @@ func TestPutHandler(t *testing.T) {
 	// With a server key.
 
 	PermissionSecret = []byte(known_key)
-	permission_ttl = time.Duration(300) * time.Second
+	blob_signature_ttl = 300 * time.Second
 
 	// When a permission key is available, the locator returned
 	// from an authenticated PUT request will be signed.
@@ -440,10 +440,10 @@ func TestDeleteHandler(t *testing.T) {
 	vols := KeepVM.AllWritable()
 	vols[0].Put(TEST_HASH, TEST_BLOCK)
 
-	// Explicitly set the permission_ttl to 0 for these
+	// Explicitly set the blob_signature_ttl to 0 for these
 	// tests, to ensure the MockVolume deletes the blocks
 	// even though they have just been created.
-	permission_ttl = time.Duration(0)
+	blob_signature_ttl = time.Duration(0)
 
 	var user_token = "NOT DATA MANAGER TOKEN"
 	data_manager_token = "DATA MANAGER TOKEN"
@@ -528,10 +528,10 @@ func TestDeleteHandler(t *testing.T) {
 		t.Error("superuser_existing_block_req: block not deleted")
 	}
 
-	// A DELETE request on a block newer than permission_ttl should return
-	// success but leave the block on the volume.
+	// A DELETE request on a block newer than blob_signature_ttl
+	// should return success but leave the block on the volume.
 	vols[0].Put(TEST_HASH, TEST_BLOCK)
-	permission_ttl = time.Duration(1) * time.Hour
+	blob_signature_ttl = time.Hour
 
 	response = IssueRequest(superuser_existing_block_req)
 	ExpectStatusCode(t,
diff --git a/services/keepstore/handlers.go b/services/keepstore/handlers.go
index b64294f..d355e92 100644
--- a/services/keepstore/handlers.go
+++ b/services/keepstore/handlers.go
@@ -197,7 +197,7 @@ func PutBlockHandler(resp http.ResponseWriter, req *http.Request) {
 	return_hash := fmt.Sprintf("%s+%d", hash, len(buf))
 	api_token := GetApiToken(req)
 	if PermissionSecret != nil && api_token != "" {
-		expiry := time.Now().Add(permission_ttl)
+		expiry := time.Now().Add(blob_signature_ttl)
 		return_hash = SignLocator(return_hash, api_token, expiry)
 	}
 	resp.Write([]byte(return_hash + "\n"))
diff --git a/services/keepstore/keepstore.go b/services/keepstore/keepstore.go
index 401d66f..c6cb00d 100644
--- a/services/keepstore/keepstore.go
+++ b/services/keepstore/keepstore.go
@@ -39,17 +39,17 @@ var PROC_MOUNTS = "/proc/mounts"
 
 // enforce_permissions controls whether permission signatures
 // should be enforced (affecting GET and DELETE requests).
-// Initialized by the --enforce-permissions flag.
+// Initialized by the -enforce-permissions flag.
 var enforce_permissions bool
 
-// permission_ttl is the time duration for which new permission
+// blob_signature_ttl is the time duration for which new permission
 // signatures (returned by PUT requests) will be valid.
-// Initialized by the --permission-ttl flag.
-var permission_ttl time.Duration
+// Initialized by the -permission-ttl flag.
+var blob_signature_ttl time.Duration
 
 // data_manager_token represents the API token used by the
 // Data Manager, and is required on certain privileged operations.
-// Initialized by the --data-manager-token-file flag.
+// Initialized by the -data-manager-token-file flag.
 var data_manager_token string
 
 // never_delete can be used to prevent the DELETE handler from
@@ -200,7 +200,7 @@ func main() {
 	var (
 		data_manager_token_file string
 		listen                  string
-		permission_key_file     string
+		blob_signing_key_file   string
 		permission_ttl_sec      int
 		volumes                 volumeSet
 		pidfile                 string
@@ -228,17 +228,27 @@ func main() {
 		"If set, nothing will be deleted. HTTP 405 will be returned "+
 			"for valid DELETE requests.")
 	flag.StringVar(
-		&permission_key_file,
+		&blob_signing_key_file,
 		"permission-key-file",
 		"",
+		"Synonym for -blob-signing-key-file.")
+	flag.StringVar(
+		&blob_signing_key_file,
+		"blob-signing-key-file",
+		"",
 		"File containing the secret key for generating and verifying "+
-			"permission signatures.")
+			"blob permission signatures.")
 	flag.IntVar(
 		&permission_ttl_sec,
 		"permission-ttl",
-		1209600,
-		"Expiration time (in seconds) for newly generated permission "+
-			"signatures.")
+		0,
+		"Synonym for -blob-signature-ttl.")
+	flag.IntVar(
+		&permission_ttl_sec,
+		"blob-signature-ttl",
+		int(time.Duration(2*7*24*time.Hour).Seconds()),
+		"Lifetime of blob permission signatures. "+
+			"See services/api/config/application.default.yml.")
 	flag.BoolVar(
 		&flagSerializeIO,
 		"serialize",
@@ -285,28 +295,25 @@ func main() {
 			log.Fatalf("reading data manager token: %s\n", err)
 		}
 	}
-	if permission_key_file != "" {
-		if buf, err := ioutil.ReadFile(permission_key_file); err == nil {
+	if blob_signing_key_file != "" {
+		if buf, err := ioutil.ReadFile(blob_signing_key_file); err == nil {
 			PermissionSecret = bytes.TrimSpace(buf)
 		} else {
 			log.Fatalf("reading permission key: %s\n", err)
 		}
 	}
 
-	// Initialize permission TTL
-	permission_ttl = time.Duration(permission_ttl_sec) * time.Second
+	blob_signature_ttl = time.Duration(permission_ttl_sec) * time.Second
 
-	// If --enforce-permissions is true, we must have a permission key
-	// to continue.
 	if PermissionSecret == nil {
 		if enforce_permissions {
-			log.Fatal("--enforce-permissions requires a permission key")
+			log.Fatal("-enforce-permissions requires a permission key")
 		} else {
 			log.Println("Running without a PermissionSecret. Block locators " +
 				"returned by this server will not be signed, and will be rejected " +
 				"by a server that enforces permissions.")
-			log.Println("To fix this, run Keep with --permission-key-file=<path> " +
-				"to define the location of a file containing the permission key.")
+			log.Println("To fix this, use the -permission-key-file flag " +
+				"to specify the file containing the permission key.")
 		}
 	}
 
diff --git a/services/keepstore/trash_worker.go b/services/keepstore/trash_worker.go
index ca26912..bc1775f 100644
--- a/services/keepstore/trash_worker.go
+++ b/services/keepstore/trash_worker.go
@@ -14,30 +14,34 @@ import (
 */
 
 func RunTrashWorker(trashq *WorkQueue) {
-	nextItem := trashq.NextItem
-	for item := range nextItem {
+	for item := range trashq.NextItem {
 		trashRequest := item.(TrashRequest)
-		err := TrashItem(trashRequest)
-		if err != nil {
-			log.Printf("Trash request error for %s: %s", trashRequest, err)
-		}
+		TrashItem(trashRequest)
 	}
 }
 
-/*
-	Delete the block indicated by the Locator in TrashRequest.
-*/
-func TrashItem(trashRequest TrashRequest) (err error) {
-	// Verify if the block is to be deleted based on its Mtime
+// TrashItem deletes the indicated block from every writable volume.
+func TrashItem(trashRequest TrashRequest) {
+	reqMtime := time.Unix(trashRequest.BlockMtime, 0)
+	if time.Since(reqMtime) < blob_signature_ttl {
+		log.Printf("WARNING: data manager asked to delete a %v old block %v (BlockMtime %d = %v), but my blob_signature_ttl is %v! Skipping.",
+			time.Since(reqMtime),
+			trashRequest.Locator,
+			trashRequest.BlockMtime,
+			reqMtime,
+			blob_signature_ttl)
+		return
+	}
 	for _, volume := range KeepVM.AllWritable() {
 		mtime, err := volume.Mtime(trashRequest.Locator)
 		if err != nil || trashRequest.BlockMtime != mtime.Unix() {
 			continue
 		}
-		currentTime := time.Now().Unix()
-		if time.Duration(currentTime-trashRequest.BlockMtime)*time.Second >= permission_ttl {
-			err = volume.Delete(trashRequest.Locator)
+		err = volume.Delete(trashRequest.Locator)
+		if err != nil {
+			log.Printf("%v Delete(%v): %v", volume, trashRequest.Locator, err)
+			continue
 		}
+		log.Printf("%v Delete(%v) OK", volume, trashRequest.Locator)
 	}
-	return
 }
diff --git a/services/keepstore/trash_worker_test.go b/services/keepstore/trash_worker_test.go
index af4040a..a11756b 100644
--- a/services/keepstore/trash_worker_test.go
+++ b/services/keepstore/trash_worker_test.go
@@ -17,9 +17,9 @@ type TrashWorkerTestData struct {
 
 	CreateData       bool
 	CreateInVolume1  bool
-	UseDelayToCreate bool
 
 	UseTrashLifeTime bool
+	DifferentMtimes  bool
 
 	DeleteLocator string
 
@@ -122,8 +122,8 @@ func TestTrashWorkerIntegration_MtimeMatchesForLocator1ButNotForLocator2(t *test
 		Locator2: TEST_HASH,
 		Block2:   TEST_BLOCK,
 
-		CreateData:       true,
-		UseDelayToCreate: true,
+		CreateData:      true,
+		DifferentMtimes: true,
 
 		DeleteLocator: TEST_HASH,
 
@@ -183,8 +183,6 @@ func TestTrashWorkerIntegration_SameLocatorInTwoVolumesWithDefaultTrashLifeTime(
 
 /* Perform the test */
 func performTrashWorkerTest(testData TrashWorkerTestData, t *testing.T) {
-	actual_permission_ttl := permission_ttl
-
 	// Create Keep Volumes
 	KeepVM = MakeTestVolumeManager(2)
 	defer KeepVM.Close()
@@ -195,11 +193,6 @@ func performTrashWorkerTest(testData TrashWorkerTestData, t *testing.T) {
 		vols[0].Put(testData.Locator1, testData.Block1)
 		vols[0].Put(testData.Locator1+".meta", []byte("metadata"))
 
-		// One of the tests deletes a locator with different Mtimes in two different volumes
-		if testData.UseDelayToCreate {
-			time.Sleep(1 * time.Second)
-		}
-
 		if testData.CreateInVolume1 {
 			vols[0].Put(testData.Locator2, testData.Block2)
 			vols[0].Put(testData.Locator2+".meta", []byte("metadata"))
@@ -209,24 +202,30 @@ func performTrashWorkerTest(testData TrashWorkerTestData, t *testing.T) {
 		}
 	}
 
+	oldBlockTime := time.Now().Add(-blob_signature_ttl-time.Minute)
+
 	// Create TrashRequest for the test
 	trashRequest := TrashRequest{
 		Locator:    testData.DeleteLocator,
-		BlockMtime: time.Now().Unix(),
+		BlockMtime: oldBlockTime.Unix(),
 	}
 
-	// delay by permission_ttl to allow deletes to work
-	time.Sleep(1 * time.Second)
-
 	// Run trash worker and put the trashRequest on trashq
 	trashList := list.New()
 	trashList.PushBack(trashRequest)
 	trashq = NewWorkQueue()
+	defer trashq.Close()
 
-	// Trash worker would not delete block if its Mtime is within trash life time.
-	// Hence, we will have to bypass it to allow the deletion to succeed.
 	if !testData.UseTrashLifeTime {
-		permission_ttl = time.Duration(1) * time.Second
+		// Trash worker would not delete block if its Mtime is
+		// within trash life time. Back-date the block to
+		// allow the deletion to succeed.
+		for _, v := range vols {
+			v.(*MockVolume).Timestamps[testData.DeleteLocator] = oldBlockTime
+			if testData.DifferentMtimes {
+				oldBlockTime = oldBlockTime.Add(time.Second)
+			}
+		}
 	}
 	go RunTrashWorker(trashq)
 
@@ -259,10 +258,10 @@ func performTrashWorkerTest(testData TrashWorkerTestData, t *testing.T) {
 		}
 	}
 
-	// One test used the same locator in two different volumes but with different Mtime values
-	// Hence let's verify that only one volume has it and the other is deleted
-	if (testData.ExpectLocator1) &&
-		(testData.Locator1 == testData.Locator2) {
+	// The DifferentMtimes test puts the same locator in two
+	// different volumes, but only one copy has an Mtime matching
+	// the trash request.
+	if testData.DifferentMtimes {
 		locatorFoundIn := 0
 		for _, volume := range KeepVM.AllReadable() {
 			if _, err := volume.Get(testData.Locator1); err == nil {
@@ -270,11 +269,7 @@ func performTrashWorkerTest(testData TrashWorkerTestData, t *testing.T) {
 			}
 		}
 		if locatorFoundIn != 1 {
-			t.Errorf("Expected locator to be found in only one volume after deleting. But found: %s", locatorFoundIn)
+			t.Errorf("Found %d copies of %s, expected 1", locatorFoundIn, testData.Locator1)
 		}
 	}
-
-	// Done
-	permission_ttl = actual_permission_ttl
-	trashq.Close()
 }
diff --git a/services/keepstore/volume_test.go b/services/keepstore/volume_test.go
index e93bb03..3d6b95f 100644
--- a/services/keepstore/volume_test.go
+++ b/services/keepstore/volume_test.go
@@ -125,7 +125,7 @@ func (v *MockVolume) Delete(loc string) error {
 		return MethodDisabledError
 	}
 	if _, ok := v.Store[loc]; ok {
-		if time.Since(v.Timestamps[loc]) < permission_ttl {
+		if time.Since(v.Timestamps[loc]) < blob_signature_ttl {
 			return nil
 		}
 		delete(v.Store, loc)
diff --git a/services/keepstore/volume_unix.go b/services/keepstore/volume_unix.go
index 20bc9c5..f825988 100644
--- a/services/keepstore/volume_unix.go
+++ b/services/keepstore/volume_unix.go
@@ -287,15 +287,15 @@ func (v *UnixVolume) Delete(loc string) error {
 	}
 	defer unlockfile(f)
 
-	// If the block has been PUT more recently than -permission_ttl,
-	// return success without removing the block.  This guards against
-	// a race condition where a block is old enough that Data Manager
-	// has added it to the trash list, but the user submitted a PUT
-	// for the block since then.
+	// If the block has been PUT in the last blob_signature_ttl
+	// seconds, return success without removing the block. This
+	// protects data from garbage collection until it is no longer
+	// possible for clients to retrieve the unreferenced blocks
+	// anyway (because the permission signatures have expired).
 	if fi, err := os.Stat(p); err != nil {
 		return err
 	} else {
-		if time.Since(fi.ModTime()) < permission_ttl {
+		if time.Since(fi.ModTime()) < blob_signature_ttl {
 			return nil
 		}
 	}

commit 6fc44a67b911cead1513e6ddb517f56dd509663b
Author: Tom Clegg <tom at curoverse.com>
Date:   Fri May 1 00:59:20 2015 -0400

    5724: Add blobSignatureTtl to discovery doc. Add config comment/explanation.

diff --git a/services/api/app/controllers/arvados/v1/schema_controller.rb b/services/api/app/controllers/arvados/v1/schema_controller.rb
index dcc9c63..62d5e59 100644
--- a/services/api/app/controllers/arvados/v1/schema_controller.rb
+++ b/services/api/app/controllers/arvados/v1/schema_controller.rb
@@ -35,6 +35,7 @@ class Arvados::V1::SchemaController < ApplicationController
         servicePath: "arvados/v1/",
         batchPath: "batch",
         defaultTrashLifetime: Rails.application.config.default_trash_lifetime,
+        blobSignatureTtl: Rails.application.config.blob_signature_ttl,
         maxRequestSize: Rails.application.config.max_request_size,
         parameters: {
           alt: {
diff --git a/services/api/app/models/collection.rb b/services/api/app/models/collection.rb
index 89ad874..ccfb35e 100644
--- a/services/api/app/models/collection.rb
+++ b/services/api/app/models/collection.rb
@@ -60,7 +60,7 @@ class Collection < ArvadosModel
       signing_opts = {
         key: Rails.configuration.blob_signing_key,
         api_token: api_token,
-        ttl: Rails.configuration.blob_signing_ttl,
+        ttl: Rails.configuration.blob_signature_ttl,
       }
       self.manifest_text.lines.each do |entry|
         entry.split[1..-1].each do |tok|
@@ -195,7 +195,7 @@ class Collection < ArvadosModel
     signing_opts = {
       key: Rails.configuration.blob_signing_key,
       api_token: token,
-      ttl: Rails.configuration.blob_signing_ttl,
+      ttl: Rails.configuration.blob_signature_ttl,
     }
     m = manifest.dup
     munge_manifest_locators!(m) do |loc|
diff --git a/services/api/config/application.default.yml b/services/api/config/application.default.yml
index e7dbf29..b57c016 100644
--- a/services/api/config/application.default.yml
+++ b/services/api/config/application.default.yml
@@ -220,9 +220,23 @@ common:
   # a site secret. It should be at least 50 characters.
   blob_signing_key: ~
 
-  # Amount of time (in seconds) for which a blob permission signature
-  # remains valid.  Default: 2 weeks (1209600 seconds)
-  blob_signing_ttl: 1209600
+  # Lifetime (in seconds) of blob permission signatures generated by
+  # the API server. This determines how long a client can take (after
+  # retrieving a collection record) to retrieve the collection data
+  # from Keep. If the client needs more time than that (assuming the
+  # collection still has the same content and the relevant user/token
+  # still has permission) the client can retrieve the collection again
+  # to get fresh signatures.
+  #
+  # Datamanager considers an unreferenced block older than this to be
+  # eligible for garbage collection. Therefore, it should never be
+  # smaller than the corresponding value used by any local keepstore
+  # service (see keepstore -blob-signing-ttl flag). This rule prevents
+  # datamanager from trying to garbage-collect recently written blocks
+  # while clients are still holding valid signatures.
+  #
+  # The default is 2 weeks.
+  blob_signature_ttl: 1209600
 
   # Allow clients to create collections by providing a manifest with
   # unsigned data blob locators. IMPORTANT: This effectively disables

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list