diff --git a/vendor/github.com/mholt/certmagic/filestorage.go b/vendor/github.com/mholt/certmagic/filestorage.go index 0837f54cd..88e00c10f 100644 --- a/vendor/github.com/mholt/certmagic/filestorage.go +++ b/vendor/github.com/mholt/certmagic/filestorage.go @@ -18,6 +18,7 @@ import ( "fmt" "io/ioutil" "os" + "path" "path/filepath" "runtime" "sync" @@ -67,16 +68,34 @@ func (fs FileStorage) Delete(key string) error { } // List returns all keys that match prefix. -func (fs FileStorage) List(prefix string) ([]string, error) { - d, err := os.Open(fs.Filename(prefix)) - if os.IsNotExist(err) { - return nil, ErrNotExist(err) - } - if err != nil { - return nil, err - } - defer d.Close() - return d.Readdirnames(-1) +func (fs FileStorage) List(prefix string, recursive bool) ([]string, error) { + var keys []string + walkPrefix := fs.Filename(prefix) + + err := filepath.Walk(walkPrefix, func(fpath string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info == nil { + return fmt.Errorf("%s: file info is nil", fpath) + } + if fpath == walkPrefix { + return nil + } + + suffix, err := filepath.Rel(walkPrefix, fpath) + if err != nil { + return fmt.Errorf("%s: could not make path relative: %v", fpath, err) + } + keys = append(keys, path.Join(prefix, suffix)) + + if !recursive && info.IsDir() { + return filepath.SkipDir + } + return nil + }) + + return keys, err } // Stat returns information about key. @@ -89,9 +108,10 @@ func (fs FileStorage) Stat(key string) (KeyInfo, error) { return KeyInfo{}, err } return KeyInfo{ - Key: key, - Modified: fi.ModTime(), - Size: fi.Size(), + Key: key, + Modified: fi.ModTime(), + Size: fi.Size(), + IsTerminal: !fi.IsDir(), }, nil } diff --git a/vendor/github.com/mholt/certmagic/maintain.go b/vendor/github.com/mholt/certmagic/maintain.go index b8e150ee8..a3d691025 100644 --- a/vendor/github.com/mholt/certmagic/maintain.go +++ b/vendor/github.com/mholt/certmagic/maintain.go @@ -261,7 +261,7 @@ func (certCache *Cache) updateOCSPStaples() { // deleteOldStapleFiles deletes cached OCSP staples that have expired. // TODO: We should do this for long-expired certificates, too. func (certCache *Cache) deleteOldStapleFiles() { - ocspKeys, err := certCache.storage.List(prefixOCSP) + ocspKeys, err := certCache.storage.List(prefixOCSP, false) if err != nil { // maybe just hasn't been created yet; no big deal return diff --git a/vendor/github.com/mholt/certmagic/memorysync.go b/vendor/github.com/mholt/certmagic/memorysync.go deleted file mode 100644 index 52884edfa..000000000 --- a/vendor/github.com/mholt/certmagic/memorysync.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2015 Matthew Holt -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package certmagic - -import ( - "fmt" - "sync" -) - -// MemoryLocker implements the Locker interface -// using memory. An empty value is NOT VALID, -// so you must use NewMemoryLocker() to get one. -type MemoryLocker struct { - nameLocks map[string]*MemoryWaiter - nameLocksMu *sync.Mutex -} - -// NewMemoryLocker returns a valid Locker backed by fs. -func NewMemoryLocker() *MemoryLocker { - return &MemoryLocker{ - nameLocks: make(map[string]*MemoryWaiter), - nameLocksMu: new(sync.Mutex), - } -} - -// TryLock attempts to get a lock for name, otherwise it returns -// a Waiter value to wait until the other process is finished. -func (l *MemoryLocker) TryLock(name string) (Waiter, error) { - l.nameLocksMu.Lock() - defer l.nameLocksMu.Unlock() - - // see if lock already exists within this process - w, ok := l.nameLocks[name] - if ok { - return w, nil - } - - // we got the lock, so create it - w = &MemoryWaiter{wg: new(sync.WaitGroup)} - w.wg.Add(1) - l.nameLocks[name] = w - - return nil, nil -} - -// Unlock releases the lock for name. -func (l *MemoryLocker) Unlock(name string) error { - l.nameLocksMu.Lock() - defer l.nameLocksMu.Unlock() - - w, ok := l.nameLocks[name] - if !ok { - return fmt.Errorf("MemoryLocker: no lock to release for %s", name) - } - - w.wg.Done() - delete(l.nameLocks, name) - - return nil -} - -// MemoryWaiter implements Waiter in memory. -type MemoryWaiter struct { - wg *sync.WaitGroup -} - -// Wait waits until w.wg is done. -func (w *MemoryWaiter) Wait() { - w.Wait() -} - -var _ Locker = &MemoryLocker{} -var _ Waiter = &MemoryWaiter{} diff --git a/vendor/github.com/mholt/certmagic/storage.go b/vendor/github.com/mholt/certmagic/storage.go index 3e20420bb..df502058b 100644 --- a/vendor/github.com/mholt/certmagic/storage.go +++ b/vendor/github.com/mholt/certmagic/storage.go @@ -49,7 +49,11 @@ type Storage interface { Exists(key string) bool // List returns all keys that match prefix. - List(prefix string) ([]string, error) + // If recursive is true, non-terminal keys + // will be enumerated (i.e. "directories" + // should be walked); otherwise, only keys + // prefixed exactly by prefix will be listed. + List(prefix string, recursive bool) ([]string, error) // Stat returns information about key. Stat(key string) (KeyInfo, error) @@ -92,9 +96,10 @@ type Waiter interface { // KeyInfo holds information about a key in storage. type KeyInfo struct { - Key string - Modified time.Time - Size int64 + Key string + Modified time.Time + Size int64 + IsTerminal bool // false for keys that only contain other keys (like directories) } // storeTx stores all the values or none at all. diff --git a/vendor/github.com/mholt/certmagic/user.go b/vendor/github.com/mholt/certmagic/user.go index b5116725a..ee11bdbf8 100644 --- a/vendor/github.com/mholt/certmagic/user.go +++ b/vendor/github.com/mholt/certmagic/user.go @@ -24,6 +24,7 @@ import ( "fmt" "io" "os" + "path" "sort" "strings" @@ -240,16 +241,16 @@ func (cfg *Config) askUserAgreement(agreementURL string) bool { // account, errors here are discarded to simplify code flow in // the caller, and errors are not important here anyway. func (cfg *Config) mostRecentUserEmail() string { - userList, err := cfg.certCache.storage.List(StorageKeys.UsersPrefix(cfg.CA)) + userList, err := cfg.certCache.storage.List(StorageKeys.UsersPrefix(cfg.CA), false) if err != nil || len(userList) == 0 { return "" } sort.Slice(userList, func(i, j int) bool { - iInfo, _ := cfg.certCache.storage.Stat(StorageKeys.UserPrefix(cfg.CA, userList[i])) - jInfo, _ := cfg.certCache.storage.Stat(StorageKeys.UserPrefix(cfg.CA, userList[j])) + iInfo, _ := cfg.certCache.storage.Stat(userList[i]) + jInfo, _ := cfg.certCache.storage.Stat(userList[j]) return jInfo.Modified.Before(iInfo.Modified) }) - user, err := cfg.getUser(userList[0]) + user, err := cfg.getUser(path.Base(userList[0])) if err != nil { return "" } diff --git a/vendor/manifest b/vendor/manifest index a08ae9c99..0556d2bdb 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -138,7 +138,7 @@ "importpath": "github.com/mholt/certmagic", "repository": "https://github.com/mholt/certmagic", "vcs": "git", - "revision": "5b3085c491553887f36460365533eb5955fdeef0", + "revision": "dc98c40439d15f67021f10f0d9219a39d7cf2990", "branch": "master", "notests": true },