diff --git a/Gopkg.lock b/Gopkg.lock index 9bf5e2e54..738a5ad9a 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -412,8 +412,8 @@ "watch", "winfile" ] - revision = "a30252cb686a21eb2d0b98132633053ec2f7f1e5" - version = "v1.0.0" + revision = "000912af8de2d2b9d184786b4cf4c3542b7884e5" + source = "github.com/vsco/tail" [[projects]] name = "github.com/imdario/mergo" @@ -937,10 +937,10 @@ version = "v1.2.1" [[projects]] - name = "gopkg.in/fsnotify.v1" + name = "gopkg.in/fsnotify/fsnotify.v1" packages = ["."] - revision = "629574ca2a5df945712d3079857300b5e4da0236" - version = "v1.4.2" + revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9" + version = "v1.4.7" [[projects]] name = "gopkg.in/inconshreveable/log15.v2" @@ -993,6 +993,7 @@ revision = "a5b47d3" [[projects]] + branch = "release-1.7" name = "k8s.io/apimachinery" packages = [ "pkg/api/equality", @@ -1040,7 +1041,7 @@ "pkg/watch", "third_party/forked/golang/reflect" ] - revision = "release-1.7" + revision = "208a6980b14bbb263f29482482eabdbcfff9f7bb" [[projects]] name = "k8s.io/client-go" @@ -1148,6 +1149,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "0e6b4c24ecfee35b0dd0427d72e47f7eaa4370e616e5a24d1ce01b69e585f080" + inputs-digest = "e6a1088c4d3674f4e0395c4775c38d31ab91a8c428aa4cb7038c6b8c5b732ae8" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 13e983034..4fcaee9ad 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -53,9 +53,11 @@ name = "github.com/google/go-querystring" revision = "53e6ce116135b80d037921a7fdd5138cf32d7a8a" +# See hpcloud/tail#138 [[constraint]] name = "github.com/hpcloud/tail" - version = "=1.0.0" + source = "github.com/vsco/tail" + revision = "000912af8de2d2b9d184786b4cf4c3542b7884e5" [[constraint]] name = "github.com/onsi/ginkgo" @@ -89,6 +91,10 @@ name = "k8s.io/kubernetes" version = "=1.7.5" +[[override]] + name = "k8s.io/apimachinery" + branch = "release-1.7" + [[constraint]] name = "golang.org/x/crypto" revision = "9419663f5a44be8b34ca85f08abc5fe1be11f8a3" diff --git a/vendor/github.com/hpcloud/tail/ratelimiter/memory.go b/vendor/github.com/hpcloud/tail/ratelimiter/memory.go index 8f6a5784a..bf3c2131b 100644 --- a/vendor/github.com/hpcloud/tail/ratelimiter/memory.go +++ b/vendor/github.com/hpcloud/tail/ratelimiter/memory.go @@ -5,7 +5,10 @@ import ( "time" ) -const GC_SIZE int = 100 +const ( + GC_SIZE int = 100 + GC_PERIOD time.Duration = 60 * time.Second +) type Memory struct { store map[string]LeakyBucket @@ -44,11 +47,10 @@ func (m *Memory) GarbageCollect() { now := time.Now() // rate limit GC to once per minute - if now.Add(60*time.Second).Unix() > m.lastGCCollected.Unix() { - + if now.Unix() >= m.lastGCCollected.Add(GC_PERIOD).Unix() { for key, bucket := range m.store { // if the bucket is drained, then GC - if bucket.DrainedAt().Unix() > now.Unix() { + if bucket.DrainedAt().Unix() < now.Unix() { delete(m.store, key) } } diff --git a/vendor/github.com/hpcloud/tail/tail.go b/vendor/github.com/hpcloud/tail/tail.go index 2d252d605..c99cdaa2b 100644 --- a/vendor/github.com/hpcloud/tail/tail.go +++ b/vendor/github.com/hpcloud/tail/tail.go @@ -22,7 +22,7 @@ import ( ) var ( - ErrStop = fmt.Errorf("tail should now stop") + ErrStop = errors.New("tail should now stop") ) type Line struct { @@ -250,7 +250,7 @@ func (tail *Tail) tailFileSync() { tail.openReader() - var offset int64 = 0 + var offset int64 var err error // Read line by line. @@ -273,10 +273,9 @@ func (tail *Tail) tailFileSync() { if cooloff { // Wait a second before seeking till the end of // file when rate limit is reached. - msg := fmt.Sprintf( - "Too much log activity; waiting a second " + - "before resuming tailing") - tail.Lines <- &Line{msg, time.Now(), fmt.Errorf(msg)} + msg := ("Too much log activity; waiting a second " + + "before resuming tailing") + tail.Lines <- &Line{msg, time.Now(), errors.New(msg)} select { case <-time.After(time.Second): case <-tail.Dying(): diff --git a/vendor/github.com/hpcloud/tail/watch/filechanges.go b/vendor/github.com/hpcloud/tail/watch/filechanges.go index 3ce5dcecb..f80aead9a 100644 --- a/vendor/github.com/hpcloud/tail/watch/filechanges.go +++ b/vendor/github.com/hpcloud/tail/watch/filechanges.go @@ -8,7 +8,7 @@ type FileChanges struct { func NewFileChanges() *FileChanges { return &FileChanges{ - make(chan bool), make(chan bool), make(chan bool)} + make(chan bool, 1), make(chan bool, 1), make(chan bool, 1)} } func (fc *FileChanges) NotifyModified() { diff --git a/vendor/github.com/hpcloud/tail/watch/inotify.go b/vendor/github.com/hpcloud/tail/watch/inotify.go index 4478f1e1a..2bbfe0b60 100644 --- a/vendor/github.com/hpcloud/tail/watch/inotify.go +++ b/vendor/github.com/hpcloud/tail/watch/inotify.go @@ -10,7 +10,7 @@ import ( "github.com/hpcloud/tail/util" - "gopkg.in/fsnotify.v1" + "gopkg.in/fsnotify/fsnotify.v1" "gopkg.in/tomb.v1" ) @@ -75,7 +75,6 @@ func (fw *InotifyFileWatcher) ChangeEvents(t *tomb.Tomb, pos int64) (*FileChange fw.Size = pos go func() { - defer RemoveWatch(fw.Filename) events := Events(fw.Filename) @@ -88,9 +87,11 @@ func (fw *InotifyFileWatcher) ChangeEvents(t *tomb.Tomb, pos int64) (*FileChange select { case evt, ok = <-events: if !ok { + RemoveWatch(fw.Filename) return } case <-t.Dying(): + RemoveWatch(fw.Filename) return } @@ -99,13 +100,19 @@ func (fw *InotifyFileWatcher) ChangeEvents(t *tomb.Tomb, pos int64) (*FileChange fallthrough case evt.Op&fsnotify.Rename == fsnotify.Rename: + RemoveWatch(fw.Filename) changes.NotifyDeleted() return + //With an open fd, unlink(fd) - inotify returns IN_ATTRIB (==fsnotify.Chmod) + case evt.Op&fsnotify.Chmod == fsnotify.Chmod: + fallthrough + case evt.Op&fsnotify.Write == fsnotify.Write: fi, err := os.Stat(fw.Filename) if err != nil { if os.IsNotExist(err) { + RemoveWatch(fw.Filename) changes.NotifyDeleted() return } diff --git a/vendor/github.com/hpcloud/tail/watch/inotify_tracker.go b/vendor/github.com/hpcloud/tail/watch/inotify_tracker.go index 03be4275c..739b3c2ab 100644 --- a/vendor/github.com/hpcloud/tail/watch/inotify_tracker.go +++ b/vendor/github.com/hpcloud/tail/watch/inotify_tracker.go @@ -12,7 +12,7 @@ import ( "github.com/hpcloud/tail/util" - "gopkg.in/fsnotify.v1" + "gopkg.in/fsnotify/fsnotify.v1" ) type InotifyTracker struct { @@ -83,21 +83,21 @@ func watch(winfo *watchInfo) error { } // RemoveWatch signals the run goroutine to remove the watch for the input filename -func RemoveWatch(fname string) { - remove(&watchInfo{ +func RemoveWatch(fname string) error { + return remove(&watchInfo{ fname: fname, }) } // RemoveWatch create signals the run goroutine to remove the watch for the input filename -func RemoveWatchCreate(fname string) { - remove(&watchInfo{ +func RemoveWatchCreate(fname string) error { + return remove(&watchInfo{ op: fsnotify.Create, fname: fname, }) } -func remove(winfo *watchInfo) { +func remove(winfo *watchInfo) error { // start running the shared InotifyTracker if not already running once.Do(goRun) @@ -108,27 +108,10 @@ func remove(winfo *watchInfo) { delete(shared.done, winfo.fname) close(done) } - - fname := winfo.fname - if winfo.isCreate() { - // Watch for new files to be created in the parent directory. - fname = filepath.Dir(fname) - } - shared.watchNums[fname]-- - watchNum := shared.watchNums[fname] - if watchNum == 0 { - delete(shared.watchNums, fname) - } shared.mux.Unlock() - // If we were the last ones to watch this file, unsubscribe from inotify. - // This needs to happen after releasing the lock because fsnotify waits - // synchronously for the kernel to acknowledge the removal of the watch - // for this file, which causes us to deadlock if we still held the lock. - if watchNum == 0 { - shared.watcher.Remove(fname) - } shared.remove <- winfo + return <-shared.error } // Events returns a channel to which FileEvents corresponding to the input filename @@ -142,8 +125,8 @@ func Events(fname string) <-chan fsnotify.Event { } // Cleanup removes the watch for the input filename if necessary. -func Cleanup(fname string) { - RemoveWatch(fname) +func Cleanup(fname string) error { + return RemoveWatch(fname) } // watchFlags calls fsnotify.WatchFlags for the input filename and flags, creating @@ -154,6 +137,8 @@ func (shared *InotifyTracker) addWatch(winfo *watchInfo) error { if shared.chans[winfo.fname] == nil { shared.chans[winfo.fname] = make(chan fsnotify.Event) + } + if shared.done[winfo.fname] == nil { shared.done[winfo.fname] = make(chan bool) } @@ -163,47 +148,50 @@ func (shared *InotifyTracker) addWatch(winfo *watchInfo) error { fname = filepath.Dir(fname) } + var err error // already in inotify watch - if shared.watchNums[fname] > 0 { - shared.watchNums[fname]++ - if winfo.isCreate() { - shared.watchNums[winfo.fname]++ - } - return nil + if shared.watchNums[fname] == 0 { + err = shared.watcher.Add(fname) } - - err := shared.watcher.Add(fname) if err == nil { shared.watchNums[fname]++ - if winfo.isCreate() { - shared.watchNums[winfo.fname]++ - } } return err } // removeWatch calls fsnotify.RemoveWatch for the input filename and closes the // corresponding events channel. -func (shared *InotifyTracker) removeWatch(winfo *watchInfo) { +func (shared *InotifyTracker) removeWatch(winfo *watchInfo) error { shared.mux.Lock() - defer shared.mux.Unlock() ch := shared.chans[winfo.fname] - if ch == nil { - return + if ch != nil { + delete(shared.chans, winfo.fname) + close(ch) } - delete(shared.chans, winfo.fname) - close(ch) - - if !winfo.isCreate() { - return + fname := winfo.fname + if winfo.isCreate() { + // Watch for new files to be created in the parent directory. + fname = filepath.Dir(fname) } + shared.watchNums[fname]-- + watchNum := shared.watchNums[fname] + if watchNum == 0 { + delete(shared.watchNums, fname) + } + shared.mux.Unlock() - shared.watchNums[winfo.fname]-- - if shared.watchNums[winfo.fname] == 0 { - delete(shared.watchNums, winfo.fname) + var err error + // If we were the last ones to watch this file, unsubscribe from inotify. + // This needs to happen after releasing the lock because fsnotify waits + // synchronously for the kernel to acknowledge the removal of the watch + // for this file, which causes us to deadlock if we still held the lock. + if watchNum == 0 { + err = shared.watcher.Remove(fname) } + + return err } // sendEvent sends the input event to the appropriate Tail. @@ -238,7 +226,7 @@ func (shared *InotifyTracker) run() { shared.error <- shared.addWatch(winfo) case winfo := <-shared.remove: - shared.removeWatch(winfo) + shared.error <- shared.removeWatch(winfo) case event, open := <-shared.watcher.Events: if !open { diff --git a/vendor/gopkg.in/fsnotify.v1/AUTHORS b/vendor/gopkg.in/fsnotify/fsnotify.v1/AUTHORS similarity index 88% rename from vendor/gopkg.in/fsnotify.v1/AUTHORS rename to vendor/gopkg.in/fsnotify/fsnotify.v1/AUTHORS index 0a5bf8f61..5ab5d41c5 100644 --- a/vendor/gopkg.in/fsnotify.v1/AUTHORS +++ b/vendor/gopkg.in/fsnotify/fsnotify.v1/AUTHORS @@ -8,8 +8,10 @@ # Please keep the list sorted. +Aaron L Adrien Bustany Amit Krishnan +Anmol Sethi Bjørn Erik Pedersen Bruno Bigras Caleb Spare @@ -26,6 +28,7 @@ Kelvin Fo Ken-ichirou MATSUZAWA Matt Layher Nathan Youngman +Nickolai Zeldovich Patrick Paul Hammond Pawel Knap @@ -33,12 +36,15 @@ Pieter Droogendijk Pursuit92 Riku Voipio Rob Figueiredo +Rodrigo Chiossi Slawek Ligus Soge Zhang Tiffany Jernigan Tilak Sharma +Tom Payne Travis Cline Tudor Golubenco +Vahe Khachikyan Yukang bronze1man debrando diff --git a/vendor/gopkg.in/fsnotify.v1/LICENSE b/vendor/gopkg.in/fsnotify/fsnotify.v1/LICENSE similarity index 100% rename from vendor/gopkg.in/fsnotify.v1/LICENSE rename to vendor/gopkg.in/fsnotify/fsnotify.v1/LICENSE diff --git a/vendor/gopkg.in/fsnotify.v1/fen.go b/vendor/gopkg.in/fsnotify/fsnotify.v1/fen.go similarity index 100% rename from vendor/gopkg.in/fsnotify.v1/fen.go rename to vendor/gopkg.in/fsnotify/fsnotify.v1/fen.go diff --git a/vendor/gopkg.in/fsnotify.v1/fsnotify.go b/vendor/gopkg.in/fsnotify/fsnotify.v1/fsnotify.go similarity index 91% rename from vendor/gopkg.in/fsnotify.v1/fsnotify.go rename to vendor/gopkg.in/fsnotify/fsnotify.v1/fsnotify.go index e7f55fee7..190bf0de5 100644 --- a/vendor/gopkg.in/fsnotify.v1/fsnotify.go +++ b/vendor/gopkg.in/fsnotify/fsnotify.v1/fsnotify.go @@ -9,6 +9,7 @@ package fsnotify import ( "bytes" + "errors" "fmt" ) @@ -60,3 +61,6 @@ func (op Op) String() string { func (e Event) String() string { return fmt.Sprintf("%q: %s", e.Name, e.Op.String()) } + +// Common errors that can be reported by a watcher +var ErrEventOverflow = errors.New("fsnotify queue overflow") diff --git a/vendor/gopkg.in/fsnotify.v1/inotify.go b/vendor/gopkg.in/fsnotify/fsnotify.v1/inotify.go similarity index 87% rename from vendor/gopkg.in/fsnotify.v1/inotify.go rename to vendor/gopkg.in/fsnotify/fsnotify.v1/inotify.go index f3b74c51f..d9fd1b88a 100644 --- a/vendor/gopkg.in/fsnotify.v1/inotify.go +++ b/vendor/gopkg.in/fsnotify/fsnotify.v1/inotify.go @@ -24,7 +24,6 @@ type Watcher struct { Events chan Event Errors chan error mu sync.Mutex // Map access - cv *sync.Cond // sync removing on rm_watch with IN_IGNORE fd int poller *fdPoller watches map[string]*watch // Map of inotify watches (key: path) @@ -56,7 +55,6 @@ func NewWatcher() (*Watcher, error) { done: make(chan struct{}), doneResp: make(chan struct{}), } - w.cv = sync.NewCond(&w.mu) go w.readEvents() return w, nil @@ -103,21 +101,23 @@ func (w *Watcher) Add(name string) error { var flags uint32 = agnosticEvents w.mu.Lock() - watchEntry, found := w.watches[name] - w.mu.Unlock() - if found { - watchEntry.flags |= flags - flags |= unix.IN_MASK_ADD + defer w.mu.Unlock() + watchEntry := w.watches[name] + if watchEntry != nil { + flags |= watchEntry.flags | unix.IN_MASK_ADD } wd, errno := unix.InotifyAddWatch(w.fd, name, flags) if wd == -1 { return errno } - w.mu.Lock() - w.watches[name] = &watch{wd: uint32(wd), flags: flags} - w.paths[wd] = name - w.mu.Unlock() + if watchEntry == nil { + w.watches[name] = &watch{wd: uint32(wd), flags: flags} + w.paths[wd] = name + } else { + watchEntry.wd = uint32(wd) + watchEntry.flags = flags + } return nil } @@ -135,6 +135,13 @@ func (w *Watcher) Remove(name string) error { if !ok { return fmt.Errorf("can't remove non-existent inotify watch for: %s", name) } + + // We successfully removed the watch if InotifyRmWatch doesn't return an + // error, we need to clean up our internal state to ensure it matches + // inotify's kernel state. + delete(w.paths, int(watch.wd)) + delete(w.watches, name) + // inotify_rm_watch will return EINVAL if the file has been deleted; // the inotify will already have been removed. // watches and pathes are deleted in ignoreLinux() implicitly and asynchronously @@ -152,13 +159,6 @@ func (w *Watcher) Remove(name string) error { return errno } - // wait until ignoreLinux() deleting maps - exists := true - for exists { - w.cv.Wait() - _, exists = w.watches[name] - } - return nil } @@ -245,13 +245,31 @@ func (w *Watcher) readEvents() { mask := uint32(raw.Mask) nameLen := uint32(raw.Len) + + if mask&unix.IN_Q_OVERFLOW != 0 { + select { + case w.Errors <- ErrEventOverflow: + case <-w.done: + return + } + } + // If the event happened to the watched directory or the watched file, the kernel // doesn't append the filename to the event, but we would like to always fill the // the "Name" field with a valid filename. We retrieve the path of the watch from // the "paths" map. w.mu.Lock() - name := w.paths[int(raw.Wd)] + name, ok := w.paths[int(raw.Wd)] + // IN_DELETE_SELF occurs when the file/directory being watched is removed. + // This is a sign to clean up the maps, otherwise we are no longer in sync + // with the inotify kernel state which has already deleted the watch + // automatically. + if ok && mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF { + delete(w.paths, int(raw.Wd)) + delete(w.watches, name) + } w.mu.Unlock() + if nameLen > 0 { // Point "bytes" at the first byte of the filename bytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent])) @@ -262,7 +280,7 @@ func (w *Watcher) readEvents() { event := newEvent(name, mask) // Send the events that are not ignored on the events channel - if !event.ignoreLinux(w, raw.Wd, mask) { + if !event.ignoreLinux(mask) { select { case w.Events <- event: case <-w.done: @@ -279,15 +297,9 @@ func (w *Watcher) readEvents() { // Certain types of events can be "ignored" and not sent over the Events // channel. Such as events marked ignore by the kernel, or MODIFY events // against files that do not exist. -func (e *Event) ignoreLinux(w *Watcher, wd int32, mask uint32) bool { +func (e *Event) ignoreLinux(mask uint32) bool { // Ignore anything the inotify API says to ignore if mask&unix.IN_IGNORED == unix.IN_IGNORED { - w.mu.Lock() - defer w.mu.Unlock() - name := w.paths[int(wd)] - delete(w.paths, int(wd)) - delete(w.watches, name) - w.cv.Broadcast() return true } diff --git a/vendor/gopkg.in/fsnotify.v1/inotify_poller.go b/vendor/gopkg.in/fsnotify/fsnotify.v1/inotify_poller.go similarity index 100% rename from vendor/gopkg.in/fsnotify.v1/inotify_poller.go rename to vendor/gopkg.in/fsnotify/fsnotify.v1/inotify_poller.go diff --git a/vendor/gopkg.in/fsnotify.v1/kqueue.go b/vendor/gopkg.in/fsnotify/fsnotify.v1/kqueue.go similarity index 94% rename from vendor/gopkg.in/fsnotify.v1/kqueue.go rename to vendor/gopkg.in/fsnotify/fsnotify.v1/kqueue.go index c2b4acb18..86e76a3d6 100644 --- a/vendor/gopkg.in/fsnotify.v1/kqueue.go +++ b/vendor/gopkg.in/fsnotify/fsnotify.v1/kqueue.go @@ -22,7 +22,7 @@ import ( type Watcher struct { Events chan Event Errors chan error - done chan bool // Channel for sending a "quit message" to the reader goroutine + done chan struct{} // Channel for sending a "quit message" to the reader goroutine kq int // File descriptor (as returned by the kqueue() syscall). @@ -56,7 +56,7 @@ func NewWatcher() (*Watcher, error) { externalWatches: make(map[string]bool), Events: make(chan Event), Errors: make(chan error), - done: make(chan bool), + done: make(chan struct{}), } go w.readEvents() @@ -71,10 +71,8 @@ func (w *Watcher) Close() error { return nil } w.isClosed = true - w.mu.Unlock() // copy paths to remove while locked - w.mu.Lock() var pathsToRemove = make([]string, 0, len(w.watches)) for name := range w.watches { pathsToRemove = append(pathsToRemove, name) @@ -82,15 +80,12 @@ func (w *Watcher) Close() error { w.mu.Unlock() // unlock before calling Remove, which also locks - var err error for _, name := range pathsToRemove { - if e := w.Remove(name); e != nil && err == nil { - err = e - } + w.Remove(name) } - // Send "quit" message to the reader goroutine: - w.done <- true + // send a "quit" message to the reader goroutine + close(w.done) return nil } @@ -266,17 +261,12 @@ func (w *Watcher) addWatch(name string, flags uint32) (string, error) { func (w *Watcher) readEvents() { eventBuffer := make([]unix.Kevent_t, 10) +loop: for { // See if there is a message on the "done" channel select { case <-w.done: - err := unix.Close(w.kq) - if err != nil { - w.Errors <- err - } - close(w.Events) - close(w.Errors) - return + break loop default: } @@ -284,7 +274,11 @@ func (w *Watcher) readEvents() { kevents, err := read(w.kq, eventBuffer, &keventWaitTime) // EINTR is okay, the syscall was interrupted before timeout expired. if err != nil && err != unix.EINTR { - w.Errors <- err + select { + case w.Errors <- err: + case <-w.done: + break loop + } continue } @@ -319,8 +313,12 @@ func (w *Watcher) readEvents() { if path.isDir && event.Op&Write == Write && !(event.Op&Remove == Remove) { w.sendDirectoryChangeEvents(event.Name) } else { - // Send the event on the Events channel - w.Events <- event + // Send the event on the Events channel. + select { + case w.Events <- event: + case <-w.done: + break loop + } } if event.Op&Remove == Remove { @@ -352,6 +350,18 @@ func (w *Watcher) readEvents() { kevents = kevents[1:] } } + + // cleanup + err := unix.Close(w.kq) + if err != nil { + // only way the previous loop breaks is if w.done was closed so we need to async send to w.Errors. + select { + case w.Errors <- err: + default: + } + } + close(w.Events) + close(w.Errors) } // newEvent returns an platform-independent Event based on kqueue Fflags. @@ -407,7 +417,11 @@ func (w *Watcher) sendDirectoryChangeEvents(dirPath string) { // Get all files files, err := ioutil.ReadDir(dirPath) if err != nil { - w.Errors <- err + select { + case w.Errors <- err: + case <-w.done: + return + } } // Search for new files @@ -428,7 +442,11 @@ func (w *Watcher) sendFileCreatedEventIfNew(filePath string, fileInfo os.FileInf w.mu.Unlock() if !doesExist { // Send create event - w.Events <- newCreateEvent(filePath) + select { + case w.Events <- newCreateEvent(filePath): + case <-w.done: + return + } } // like watchDirectoryFiles (but without doing another ReadDir) diff --git a/vendor/gopkg.in/fsnotify.v1/open_mode_bsd.go b/vendor/gopkg.in/fsnotify/fsnotify.v1/open_mode_bsd.go similarity index 100% rename from vendor/gopkg.in/fsnotify.v1/open_mode_bsd.go rename to vendor/gopkg.in/fsnotify/fsnotify.v1/open_mode_bsd.go diff --git a/vendor/gopkg.in/fsnotify.v1/open_mode_darwin.go b/vendor/gopkg.in/fsnotify/fsnotify.v1/open_mode_darwin.go similarity index 100% rename from vendor/gopkg.in/fsnotify.v1/open_mode_darwin.go rename to vendor/gopkg.in/fsnotify/fsnotify.v1/open_mode_darwin.go diff --git a/vendor/gopkg.in/fsnotify.v1/windows.go b/vendor/gopkg.in/fsnotify/fsnotify.v1/windows.go similarity index 100% rename from vendor/gopkg.in/fsnotify.v1/windows.go rename to vendor/gopkg.in/fsnotify/fsnotify.v1/windows.go