vendor: update vendored upspin.io to bcbe577

Change-Id: I4f6e648684f983e87f13b00551ef6681cecc60d0
Reviewed-on: https://upspin-review.googlesource.com/16120
Reviewed-by: Rob Pike <r@golang.org>
diff --git a/Gopkg.lock b/Gopkg.lock
index 9fe8e59..0d6eecb 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -59,7 +59,7 @@
   branch = "master"
   name = "upspin.io"
   packages = ["access","bind","cache","client","client/clientutil","client/file","cloud/mail","cmd/cacheserver/cacheutil","config","dir/inprocess","dir/remote","dir/unassigned","errors","factotum","flags","key/inprocess","key/keygen","key/proquint","key/remote","key/sha256key","key/transports","key/unassigned","key/usercache","log","metric","pack","pack/ee","pack/eeintegrity","pack/internal","pack/packutil","pack/plain","path","rpc","rpc/local","serverutil","serverutil/signup","shutdown","store/inprocess","store/remote","store/transports","store/unassigned","subcmd","transports","upspin","upspin/proto","user","valid","version"]
-  revision = "2577ed2a663b0f010ded618cc90b6d89f8bc9006"
+  revision = "bcbe577d41646dffd734f21cf604a7cbeeafa634"
 
 [solve-meta]
   analyzer-name = "dep"
diff --git a/vendor/upspin.io/cmd/cacheserver/serve.go b/vendor/upspin.io/cmd/cacheserver/serve.go
index 1f48ffc..da42bd8 100644
--- a/vendor/upspin.io/cmd/cacheserver/serve.go
+++ b/vendor/upspin.io/cmd/cacheserver/serve.go
@@ -8,10 +8,13 @@
 	"expvar"
 	"flag"
 	"net/http"
+	"os"
+	"path/filepath"
 
 	"upspin.io/config"
 	"upspin.io/dir/dircache"
 	"upspin.io/flags"
+	"upspin.io/log"
 	"upspin.io/rpc/dirserver"
 	"upspin.io/rpc/local"
 	"upspin.io/rpc/storeserver"
@@ -39,13 +42,18 @@
 	maxRefBytes := (9 * (*cacheSizeFlag)) / 10
 	maxLogBytes := maxRefBytes / 9
 
-	sc, blockFlusher, err := storecache.New(cfg, flags.CacheDir, maxRefBytes, *writethrough)
+	myCacheDir := filepath.Join(flags.CacheDir, string(cfg.UserName()))
+
+	// Link old structure cache files into the new structure.
+	relocate(flags.CacheDir, myCacheDir)
+
+	sc, blockFlusher, err := storecache.New(cfg, myCacheDir, maxRefBytes, *writethrough)
 	if err != nil {
 		return nil, err
 	}
 	ss := storeserver.New(cfg, sc, "")
 
-	dc, err := dircache.New(cfg, flags.CacheDir, maxLogBytes, blockFlusher)
+	dc, err := dircache.New(cfg, myCacheDir, maxLogBytes, blockFlusher)
 	if err != nil {
 		return nil, err
 	}
@@ -70,3 +78,67 @@
 	}()
 	return done, nil
 }
+
+// relocate links the old directory contents one level down into a
+// user specific directory. By linking the files one at a time rather
+// than linking or renaming the directories, we cause the least interference
+// between old and new worlds should an old server still be running.
+//
+// TODO(p): when everyone has had a chance to convert, replace this with
+// a routine that removes the old structure.
+func relocate(old, new string) {
+	if _, err := os.Stat(new); err == nil || !os.IsNotExist(err) {
+		// Already done, do nothing.
+		return
+	}
+	if err := os.MkdirAll(new, 0700); err != nil {
+		log.Debug.Printf("cacheserver/relocate: %s", err)
+		return
+	}
+	walkAndMove(old, new, "storewritebackqueue", nil)
+	walkAndMove(old, new, "storecache", nil)
+	walkAndMove(old, new, "dircache", nil)
+}
+
+// walkAndMove links old files into new structure.
+func walkAndMove(oldDir, newDir, name string, info os.FileInfo) {
+	old := filepath.Join(oldDir, name)
+	new := filepath.Join(newDir, name)
+	if info == nil {
+		var err error
+		info, err = os.Stat(old)
+		if err != nil {
+			log.Debug.Printf("cacheserver/walkAndMove: %s", err)
+			return
+		}
+	}
+
+	// Link files into new directory structure.
+	if !info.Mode().IsDir() {
+		if err := os.Link(old, new); err != nil {
+			log.Debug.Printf("cacheserver/walkAndMove: %s", err)
+		}
+		return
+	}
+	if err := os.MkdirAll(new, 0700); err != nil {
+		log.Debug.Printf("cacheserver/walkAndMove: %s", err)
+		return
+	}
+
+	// Read and descend directories.
+	f, err := os.Open(old)
+	if err != nil {
+		log.Debug.Printf("cacheserver/walkAndMove: %s", err)
+		return
+	}
+	infos, err := f.Readdir(0)
+	f.Close()
+	if err != nil {
+		log.Debug.Printf("cacheserver/walkAndMove: %s", err)
+		return
+
+	}
+	for _, i := range infos {
+		walkAndMove(old, new, i.Name(), i)
+	}
+}
diff --git a/vendor/upspin.io/dir/remote/remote.go b/vendor/upspin.io/dir/remote/remote.go
index b070899..ce993bf 100644
--- a/vendor/upspin.io/dir/remote/remote.go
+++ b/vendor/upspin.io/dir/remote/remote.go
@@ -252,7 +252,7 @@
 
 func (r *remote) opf(method string, format string, args ...interface{}) *operation {
 	ep := r.cfg.endpoint.String()
-	s := fmt.Sprintf("dir/remote.%s(%q)", method, ep)
+	s := fmt.Sprintf("dir/remote: %q: dir.%s", ep, method)
 	op := &operation{s, fmt.Sprintf(format, args...)}
 	log.Debug.Print(op)
 	return op
diff --git a/vendor/upspin.io/key/remote/remote.go b/vendor/upspin.io/key/remote/remote.go
index 48cbaf8..24e6d15 100644
--- a/vendor/upspin.io/key/remote/remote.go
+++ b/vendor/upspin.io/key/remote/remote.go
@@ -110,7 +110,7 @@
 
 func (r *remote) opf(method string, format string, args ...interface{}) *operation {
 	ep := r.cfg.endpoint.String()
-	s := fmt.Sprintf("key/remote.%s(%q)", method, ep)
+	s := fmt.Sprintf("key/remote: %q: key.%s", ep, method)
 	op := &operation{s, fmt.Sprintf(format, args...)}
 	log.Debug.Print(op)
 	return op
diff --git a/vendor/upspin.io/serverutil/ratecounter.go b/vendor/upspin.io/serverutil/ratecounter.go
index 1e3cddb..9cfe0fb 100644
--- a/vendor/upspin.io/serverutil/ratecounter.go
+++ b/vendor/upspin.io/serverutil/ratecounter.go
@@ -64,7 +64,7 @@
 
 // String implements expvar.Val
 func (r *RateCounter) String() string {
-	return fmt.Sprintf("%g ops/s", r.Rate()/float64(r.d.Seconds()))
+	return fmt.Sprintf(`"%g ops/s"`, r.Rate()/float64(r.d.Seconds()))
 }
 
 func (r *RateCounter) loop() {
diff --git a/vendor/upspin.io/serverutil/signup/signup.go b/vendor/upspin.io/serverutil/signup/signup.go
index f0f5b32..213d54d 100644
--- a/vendor/upspin.io/serverutil/signup/signup.go
+++ b/vendor/upspin.io/serverutil/signup/signup.go
@@ -37,12 +37,6 @@
 	// signupGracePeriod is the period of validity for a signup request.
 	signupGracePeriod = 24 * time.Hour
 
-	// signupNotifyAddress is the address that should receive signup notifications.
-	signupNotifyAddress = "upspin-sendgrid@google.com"
-
-	// fromAddress is the origin address for signup messages.
-	fromAddress = "noreply@upspin.io"
-
 	noHTML = "" // for mail.Send
 )
 
@@ -52,26 +46,38 @@
 	baseURL string
 	fact    upspin.Factotum
 	key     upspin.KeyServer
-	mail    mail.Mail
-	project string
+	mail    *MailConfig
 
 	rate serverutil.RateLimiter
 }
 
+// MailConfig holds the mail configuration used by the signup handler.
+type MailConfig struct {
+	// Mail holds the mailer used for sending signup emails and notifications.
+	mail.Mail
+
+	// Project is the name used in the subject line of signup notifications,
+	// to distinguish between test and production keyserver instances.
+	Project string
+
+	// Notify specifies the recipient address for signup notifications.
+	Notify string
+
+	// From specifies the address from which to send mail messages.
+	From string
+}
+
 // NewHandler creates a new handler that serves signup requests (made by
 // 'upspin signup') and verification requests (visited by clicking the link in
 // the email).
 // The Factotum is used to sign the verification URL. The KeyServer is where
-// the new user will be created. The Mail is used to send mail. The provided
-// project name is used in the subject line of signup notifications, to
-// distinguish test and production keyserver instances.
-func NewHandler(baseURL string, fact upspin.Factotum, key upspin.KeyServer, m mail.Mail, project string) http.Handler {
+// the new user will be created. The MailConfig is used to send mail.
+func NewHandler(baseURL string, fact upspin.Factotum, key upspin.KeyServer, mc *MailConfig) http.Handler {
 	return &handler{
 		baseURL: baseURL,
 		fact:    fact,
 		key:     key,
-		mail:    m,
-		project: project,
+		mail:    mc,
 		rate: serverutil.RateLimiter{
 			Backoff: 1 * time.Minute,
 			Max:     24 * time.Hour,
@@ -164,12 +170,11 @@
 			return
 		}
 
-		// Send a note to our internal list, so we're aware of signups.
-		subject := fmt.Sprintf("New signup on %s: %s", m.project, string(u.Name))
-		body := fmt.Sprintf("%s signed up on %s on %s", u.Name, m.project, time.Now().Format(time.Stamp))
-		err = m.mail.Send(signupNotifyAddress, fromAddress, subject, body, noHTML)
+		subject := fmt.Sprintf("New signup on %s: %s", m.mail.Project, string(u.Name))
+		body := fmt.Sprintf("%s signed up on %s on %s", u.Name, m.mail.Project, time.Now().Format(time.Stamp))
+		err = m.mail.Send(m.mail.Notify, m.mail.From, subject, body, noHTML)
 		if err != nil {
-			log.Error.Printf("Error sending mail to %q: %v", signupNotifyAddress, err)
+			log.Error.Printf("Error sending mail to %q: %v", m.mail.Notify, err)
 			// Don't prevent signup if this fails.
 		}
 
@@ -238,7 +243,7 @@
 	fmt.Fprintln(body, "\nIf you were not expecting this message, please ignore it.")
 	// TODO(adg): implement opt out link
 	const subject = "Upspin signup confirmation"
-	err = m.mail.Send(string(u.Name), fromAddress, subject, body.String(), noHTML)
+	err = m.mail.Send(string(u.Name), m.mail.From, subject, body.String(), noHTML)
 	if err != nil {
 		log.Error.Printf("Error sending mail to %q: %v", u.Name, err)
 		errorf(http.StatusInternalServerError, "could not send signup email")
@@ -364,8 +369,8 @@
 
 var signupURLScheme = "https" // Tests may override this.
 
-// MakeRequest sends a signup request to the given URL for the given Config
-// using the provided Client or http.DefaultClient if client is nil.
+// MakeRequest sends a signup request for the given Config to the Config's
+// KeyServer Endpoint using the Config's TLS certs (if any).
 func MakeRequest(cfg upspin.Config) error {
 	query, err := makeQueryString(cfg)
 	if err != nil {
diff --git a/vendor/upspin.io/store/remote/remote.go b/vendor/upspin.io/store/remote/remote.go
index e5d0cec..417dbfc 100644
--- a/vendor/upspin.io/store/remote/remote.go
+++ b/vendor/upspin.io/store/remote/remote.go
@@ -93,7 +93,7 @@
 
 // Put implements upspin.StoreServer.Put.
 func (r *remote) Put(data []byte) (*upspin.Refdata, error) {
-	op := r.opf("Put", "%v bytes", len(data))
+	op := r.opf("Put", "%.16x...) (%v bytes", data, len(data))
 
 	req := &proto.StorePutRequest{
 		Data: data,
@@ -218,7 +218,7 @@
 
 func (r *remote) opf(method string, format string, args ...interface{}) *operation {
 	ep := r.cfg.endpoint.String()
-	s := fmt.Sprintf("store/remote.%s(%q)", method, ep)
+	s := fmt.Sprintf("store/remote: %q: store.%s", ep, method)
 	op := &operation{s, fmt.Sprintf(format, args...)}
 	log.Debug.Print(op)
 	return op
diff --git a/vendor/upspin.io/subcmd/server.go b/vendor/upspin.io/subcmd/server.go
index 46148cb..4624e53 100644
--- a/vendor/upspin.io/subcmd/server.go
+++ b/vendor/upspin.io/subcmd/server.go
@@ -25,14 +25,6 @@
 
 	// StoreConfig specifies the configuration options for the StoreServer.
 	StoreConfig []string
-
-	// Bucket specifies the Google Cloud Storage bucket that the
-	// upspinserver should use to store data.
-	// If empty, local disk is used instead.
-	// Deprecated: StoreConfig should be used instead.
-	Bucket string
-
-	// TODO(adg): remove the Bucket field.
 }
 
 // ServerConfigFile specifies the file name of the JSON-encoded ServerConfig.
diff --git a/vendor/upspin.io/user/user.go b/vendor/upspin.io/user/user.go
index f0bd7a3..c6f54f5 100644
--- a/vendor/upspin.io/user/user.go
+++ b/vendor/upspin.io/user/user.go
@@ -26,20 +26,20 @@
 //
 // The rules are:
 //
-// <name> := <user name>@<domain name>
+// 	<name> := <user name>@<domain name>
 //
-// <domain name> :=
+// 	<domain name> :=
 //
-// - each . separated token < 64 characters
-// - character set for tokens [a-z0-9\-]
-// - final token at least two characters
-// - whole name < 254 characters
-// - characters are case insensitive
-// - final period is OK, but we remove it
+// 	- each . separated token < 64 characters
+// 	- character set for tokens [a-z0-9\-]
+// 	- final token at least two characters
+// 	- whole name < 254 characters
+// 	- characters are case insensitive
+// 	- final period is OK, but we remove it
 //
 // We ignore the rules of punycode, which is defined in https://tools.ietf.org/html/rfc3490 .
 //
-// <user name> :=
+// 	<user name> :=
 //
 // Names are validated and canonicalized by the UsernameCasePreserved profile
 // of the RFC 7613, "Preparation, Enforcement, and Comparison of Internationalized Strings",
diff --git a/vendor/upspin.io/version/make_version.go b/vendor/upspin.io/version/make_version.go
index e83ea42..c1d35be 100644
--- a/vendor/upspin.io/version/make_version.go
+++ b/vendor/upspin.io/version/make_version.go
@@ -27,7 +27,7 @@
 		return
 	}
 
-	output := fmt.Sprintf(outputFormat, time.Now().In(time.UTC).Format(time.Stamp+" UTC"), version)
+	output := fmt.Sprintf(outputFormat, time.Now().In(time.UTC).Format(time.UnixDate), version)
 
 	err := ioutil.WriteFile("git_version.go", []byte(output), 0664)
 	if err != nil {
@@ -47,7 +47,7 @@
 
 func init() {
 	var err error
-	BuildTime, err = time.Parse(time.Stamp + " UTC", %[1]q)
+	BuildTime, err = time.Parse(time.UnixDate, %[1]q)
 	if err != nil {
 		panic(err)
 	}
diff --git a/vendor/upspin.io/version/version.go b/vendor/upspin.io/version/version.go
index 4544bb5..741e80e 100644
--- a/vendor/upspin.io/version/version.go
+++ b/vendor/upspin.io/version/version.go
@@ -26,7 +26,7 @@
 	if GitSHA == "" {
 		return "devel\n"
 	}
-	str := fmt.Sprintf("Build time: %s\n", BuildTime.In(time.UTC).Format(time.Stamp+" UTC"))
+	str := fmt.Sprintf("Build time: %s\n", BuildTime.In(time.UTC).Format(time.Stamp+" 2006 UTC"))
 	str += fmt.Sprintf("Git hash:   %s\n", GitSHA)
 	return str
 }