Merge pull request #71011 from sigma/pr/fix-inotify

replace golang.org/x/exp/inotify with standalone library
pull/58/head
k8s-ci-robot 2018-11-22 18:07:51 -08:00 committed by GitHub
commit 12e5eb7dc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 5 additions and 429 deletions

4
Godeps/Godeps.json generated
View File

@ -3422,10 +3422,6 @@
"ImportPath": "golang.org/x/crypto/ssh/terminal",
"Rev": "de0752318171da717af4ce24d0a2e8626afaeb11"
},
{
"ImportPath": "golang.org/x/exp/inotify",
"Rev": "292a51b8d262487dab23a588950e8052d63d9113"
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "0ed95abb35c445290478a5348a7b38bb154135fd"

35
Godeps/LICENSES generated
View File

@ -98293,41 +98293,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
================================================================================
= vendor/golang.org/x/exp/inotify licensed under: =
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
= vendor/golang.org/x/exp/LICENSE 5d4950ecb7b26d2c5e4e7b4e0dd74707
================================================================================
================================================================================
= vendor/golang.org/x/net/context licensed under: =

View File

@ -129,7 +129,7 @@ go_library(
"//vendor/k8s.io/utils/exec:go_default_library",
] + select({
"@io_bazel_rules_go//go/platform:linux": [
"//vendor/golang.org/x/exp/inotify:go_default_library",
"//vendor/github.com/sigma/go-inotify:go_default_library",
],
"@io_bazel_rules_go//go/platform:windows": [
"//pkg/windows/service:go_default_library",

View File

@ -17,7 +17,7 @@ limitations under the License.
package app
import (
"golang.org/x/exp/inotify"
"github.com/sigma/go-inotify"
"k8s.io/klog"
)

View File

@ -48,7 +48,7 @@ go_library(
] + select({
"@io_bazel_rules_go//go/platform:linux": [
"//staging/src/k8s.io/client-go/util/flowcontrol:go_default_library",
"//vendor/golang.org/x/exp/inotify:go_default_library",
"//vendor/github.com/sigma/go-inotify:go_default_library",
],
"//conditions:default": [],
}),

View File

@ -61,7 +61,7 @@ type sourceFile struct {
}
func NewSourceFile(path string, nodeName types.NodeName, period time.Duration, updates chan<- interface{}) {
// "golang.org/x/exp/inotify" requires a path without trailing "/"
// "github.com/sigma/go-inotify" requires a path without trailing "/"
path = strings.TrimRight(path, string(os.PathSeparator))
config := newSourceFile(path, nodeName, period, updates)

View File

@ -26,7 +26,7 @@ import (
"strings"
"time"
"golang.org/x/exp/inotify"
"github.com/sigma/go-inotify"
"k8s.io/klog"
"k8s.io/api/core/v1"

1
vendor/BUILD vendored
View File

@ -389,7 +389,6 @@ filegroup(
"//vendor/golang.org/x/crypto/poly1305:all-srcs",
"//vendor/golang.org/x/crypto/salsa20/salsa:all-srcs",
"//vendor/golang.org/x/crypto/ssh:all-srcs",
"//vendor/golang.org/x/exp/inotify:all-srcs",
"//vendor/golang.org/x/net/context:all-srcs",
"//vendor/golang.org/x/net/html:all-srcs",
"//vendor/golang.org/x/net/http2:all-srcs",

3
vendor/golang.org/x/exp/AUTHORS generated vendored
View File

@ -1,3 +0,0 @@
# This source code refers to The Go Authors for copyright purposes.
# The master list of authors is in the main Go distribution,
# visible at http://tip.golang.org/AUTHORS.

View File

@ -1,3 +0,0 @@
# This source code was written by the Go contributors.
# The master list of contributors is in the main Go distribution,
# visible at http://tip.golang.org/CONTRIBUTORS.

27
vendor/golang.org/x/exp/LICENSE generated vendored
View File

@ -1,27 +0,0 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

22
vendor/golang.org/x/exp/PATENTS generated vendored
View File

@ -1,22 +0,0 @@
Additional IP Rights Grant (Patents)
"This implementation" means the copyrightable works distributed by
Google as part of the Go project.
Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.

View File

@ -1,23 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["inotify_linux.go"],
importmap = "k8s.io/kubernetes/vendor/golang.org/x/exp/inotify",
importpath = "golang.org/x/exp/inotify",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -1,306 +0,0 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
Package inotify implements a wrapper for the Linux inotify system.
Example:
watcher, err := inotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
err = watcher.Watch("/tmp")
if err != nil {
log.Fatal(err)
}
for {
select {
case ev := <-watcher.Event:
log.Println("event:", ev)
case err := <-watcher.Error:
log.Println("error:", err)
}
}
*/
package inotify
import (
"errors"
"fmt"
"os"
"strings"
"sync"
"syscall"
"unsafe"
)
type Event struct {
Mask uint32 // Mask of events
Cookie uint32 // Unique cookie associating related events (for rename(2))
Name string // File name (optional)
}
type watch struct {
wd uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall)
flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags)
}
type Watcher struct {
mu sync.Mutex
fd int // File descriptor (as returned by the inotify_init() syscall)
watches map[string]*watch // Map of inotify watches (key: path)
paths map[int]string // Map of watched paths (key: watch descriptor)
Error chan error // Errors are sent on this channel
Event chan *Event // Events are returned on this channel
done chan bool // Channel for sending a "quit message" to the reader goroutine
isClosed bool // Set to true when Close() is first called
}
// NewWatcher creates and returns a new inotify instance using inotify_init(2)
func NewWatcher() (*Watcher, error) {
fd, errno := syscall.InotifyInit()
if fd == -1 {
return nil, os.NewSyscallError("inotify_init", errno)
}
w := &Watcher{
fd: fd,
watches: make(map[string]*watch),
paths: make(map[int]string),
Event: make(chan *Event),
Error: make(chan error),
done: make(chan bool, 1),
}
go w.readEvents()
return w, nil
}
// Close closes an inotify watcher instance
// It sends a message to the reader goroutine to quit and removes all watches
// associated with the inotify instance
func (w *Watcher) Close() error {
if w.isClosed {
return nil
}
w.isClosed = true
// Send "quit" message to the reader goroutine
w.done <- true
for path := range w.watches {
w.RemoveWatch(path)
}
return nil
}
// AddWatch adds path to the watched file set.
// The flags are interpreted as described in inotify_add_watch(2).
func (w *Watcher) AddWatch(path string, flags uint32) error {
if w.isClosed {
return errors.New("inotify instance already closed")
}
watchEntry, found := w.watches[path]
if found {
watchEntry.flags |= flags
flags |= syscall.IN_MASK_ADD
}
w.mu.Lock() // synchronize with readEvents goroutine
wd, err := syscall.InotifyAddWatch(w.fd, path, flags)
if err != nil {
w.mu.Unlock()
return &os.PathError{
Op: "inotify_add_watch",
Path: path,
Err: err,
}
}
if !found {
w.watches[path] = &watch{wd: uint32(wd), flags: flags}
w.paths[wd] = path
}
w.mu.Unlock()
return nil
}
// Watch adds path to the watched file set, watching all events.
func (w *Watcher) Watch(path string) error {
return w.AddWatch(path, IN_ALL_EVENTS)
}
// RemoveWatch removes path from the watched file set.
func (w *Watcher) RemoveWatch(path string) error {
watch, ok := w.watches[path]
if !ok {
return errors.New(fmt.Sprintf("can't remove non-existent inotify watch for: %s", path))
}
success, errno := syscall.InotifyRmWatch(w.fd, watch.wd)
if success == -1 {
return os.NewSyscallError("inotify_rm_watch", errno)
}
delete(w.watches, path)
// Locking here to protect the read from paths in readEvents.
w.mu.Lock()
delete(w.paths, int(watch.wd))
w.mu.Unlock()
return nil
}
// readEvents reads from the inotify file descriptor, converts the
// received events into Event objects and sends them via the Event channel
func (w *Watcher) readEvents() {
var buf [syscall.SizeofInotifyEvent * 4096]byte
for {
n, err := syscall.Read(w.fd, buf[:])
// See if there is a message on the "done" channel
var done bool
select {
case done = <-w.done:
default:
}
// If EOF or a "done" message is received
if n == 0 || done {
// The syscall.Close can be slow. Close
// w.Event first.
close(w.Event)
err := syscall.Close(w.fd)
if err != nil {
w.Error <- os.NewSyscallError("close", err)
}
close(w.Error)
return
}
if n < 0 {
w.Error <- os.NewSyscallError("read", err)
continue
}
if n < syscall.SizeofInotifyEvent {
w.Error <- errors.New("inotify: short read in readEvents()")
continue
}
var offset uint32 = 0
// We don't know how many events we just read into the buffer
// While the offset points to at least one whole event...
for offset <= uint32(n-syscall.SizeofInotifyEvent) {
// Point "raw" to the event in the buffer
raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset]))
event := new(Event)
event.Mask = uint32(raw.Mask)
event.Cookie = uint32(raw.Cookie)
nameLen := uint32(raw.Len)
// 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, ok := w.paths[int(raw.Wd)]
w.mu.Unlock()
if ok {
event.Name = name
if nameLen > 0 {
// Point "bytes" at the first byte of the filename
bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent]))
// The filename is padded with NUL bytes. TrimRight() gets rid of those.
event.Name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000")
}
// Send the event on the events channel
w.Event <- event
}
// Move to the next event in the buffer
offset += syscall.SizeofInotifyEvent + nameLen
}
}
}
// String formats the event e in the form
// "filename: 0xEventMask = IN_ACCESS|IN_ATTRIB_|..."
func (e *Event) String() string {
var events string = ""
m := e.Mask
for _, b := range eventBits {
if m&b.Value == b.Value {
m &^= b.Value
events += "|" + b.Name
}
}
if m != 0 {
events += fmt.Sprintf("|%#x", m)
}
if len(events) > 0 {
events = " == " + events[1:]
}
return fmt.Sprintf("%q: %#x%s", e.Name, e.Mask, events)
}
const (
// Options for inotify_init() are not exported
// IN_CLOEXEC uint32 = syscall.IN_CLOEXEC
// IN_NONBLOCK uint32 = syscall.IN_NONBLOCK
// Options for AddWatch
IN_DONT_FOLLOW uint32 = syscall.IN_DONT_FOLLOW
IN_ONESHOT uint32 = syscall.IN_ONESHOT
IN_ONLYDIR uint32 = syscall.IN_ONLYDIR
// The "IN_MASK_ADD" option is not exported, as AddWatch
// adds it automatically, if there is already a watch for the given path
// IN_MASK_ADD uint32 = syscall.IN_MASK_ADD
// Events
IN_ACCESS uint32 = syscall.IN_ACCESS
IN_ALL_EVENTS uint32 = syscall.IN_ALL_EVENTS
IN_ATTRIB uint32 = syscall.IN_ATTRIB
IN_CLOSE uint32 = syscall.IN_CLOSE
IN_CLOSE_NOWRITE uint32 = syscall.IN_CLOSE_NOWRITE
IN_CLOSE_WRITE uint32 = syscall.IN_CLOSE_WRITE
IN_CREATE uint32 = syscall.IN_CREATE
IN_DELETE uint32 = syscall.IN_DELETE
IN_DELETE_SELF uint32 = syscall.IN_DELETE_SELF
IN_MODIFY uint32 = syscall.IN_MODIFY
IN_MOVE uint32 = syscall.IN_MOVE
IN_MOVED_FROM uint32 = syscall.IN_MOVED_FROM
IN_MOVED_TO uint32 = syscall.IN_MOVED_TO
IN_MOVE_SELF uint32 = syscall.IN_MOVE_SELF
IN_OPEN uint32 = syscall.IN_OPEN
// Special events
IN_ISDIR uint32 = syscall.IN_ISDIR
IN_IGNORED uint32 = syscall.IN_IGNORED
IN_Q_OVERFLOW uint32 = syscall.IN_Q_OVERFLOW
IN_UNMOUNT uint32 = syscall.IN_UNMOUNT
)
var eventBits = []struct {
Value uint32
Name string
}{
{IN_ACCESS, "IN_ACCESS"},
{IN_ATTRIB, "IN_ATTRIB"},
{IN_CLOSE, "IN_CLOSE"},
{IN_CLOSE_NOWRITE, "IN_CLOSE_NOWRITE"},
{IN_CLOSE_WRITE, "IN_CLOSE_WRITE"},
{IN_CREATE, "IN_CREATE"},
{IN_DELETE, "IN_DELETE"},
{IN_DELETE_SELF, "IN_DELETE_SELF"},
{IN_MODIFY, "IN_MODIFY"},
{IN_MOVE, "IN_MOVE"},
{IN_MOVED_FROM, "IN_MOVED_FROM"},
{IN_MOVED_TO, "IN_MOVED_TO"},
{IN_MOVE_SELF, "IN_MOVE_SELF"},
{IN_OPEN, "IN_OPEN"},
{IN_ISDIR, "IN_ISDIR"},
{IN_IGNORED, "IN_IGNORED"},
{IN_Q_OVERFLOW, "IN_Q_OVERFLOW"},
{IN_UNMOUNT, "IN_UNMOUNT"},
}