diff --git a/app/collector.go b/app/collector.go index e7a81f08a..b37dd85b3 100644 --- a/app/collector.go +++ b/app/collector.go @@ -11,7 +11,7 @@ import ( "github.com/ugorji/go/codec" "golang.org/x/net/context" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/report" ) diff --git a/app/collector_test.go b/app/collector_test.go index bfcfcfde2..86a9169f0 100644 --- a/app/collector_test.go +++ b/app/collector_test.go @@ -6,8 +6,8 @@ import ( "golang.org/x/net/context" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/app" - "github.com/weaveworks/scope/common/mtime" "github.com/weaveworks/scope/report" "github.com/weaveworks/scope/test" "github.com/weaveworks/scope/test/reflect" diff --git a/app/multitenant/aws_collector.go b/app/multitenant/aws_collector.go index 51ef9291c..5bef6f775 100644 --- a/app/multitenant/aws_collector.go +++ b/app/multitenant/aws_collector.go @@ -17,8 +17,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "golang.org/x/net/context" + "github.com/weaveworks/common/instrument" "github.com/weaveworks/scope/app" - "github.com/weaveworks/scope/common/instrument" "github.com/weaveworks/scope/report" ) diff --git a/app/multitenant/consul_pipe_router.go b/app/multitenant/consul_pipe_router.go index 9ac3e8155..bc06d2e11 100644 --- a/app/multitenant/consul_pipe_router.go +++ b/app/multitenant/consul_pipe_router.go @@ -13,8 +13,8 @@ import ( "github.com/gorilla/websocket" "golang.org/x/net/context" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/app" - "github.com/weaveworks/scope/common/mtime" "github.com/weaveworks/scope/common/xfer" ) diff --git a/app/multitenant/memcache_client.go b/app/multitenant/memcache_client.go index 4a6218ae6..44a34b4bd 100644 --- a/app/multitenant/memcache_client.go +++ b/app/multitenant/memcache_client.go @@ -13,7 +13,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "golang.org/x/net/context" - "github.com/weaveworks/scope/common/instrument" + "github.com/weaveworks/common/instrument" "github.com/weaveworks/scope/report" ) diff --git a/app/multitenant/s3_client.go b/app/multitenant/s3_client.go index fcad11745..b458239e7 100644 --- a/app/multitenant/s3_client.go +++ b/app/multitenant/s3_client.go @@ -9,7 +9,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "golang.org/x/net/context" - "github.com/weaveworks/scope/common/instrument" + "github.com/weaveworks/common/instrument" "github.com/weaveworks/scope/report" ) diff --git a/app/multitenant/sqs_control_router.go b/app/multitenant/sqs_control_router.go index 2eb9cabad..7ff4c2d54 100644 --- a/app/multitenant/sqs_control_router.go +++ b/app/multitenant/sqs_control_router.go @@ -15,8 +15,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "golang.org/x/net/context" + "github.com/weaveworks/common/instrument" "github.com/weaveworks/scope/app" - "github.com/weaveworks/scope/common/instrument" "github.com/weaveworks/scope/common/xfer" ) diff --git a/app/pipe_router.go b/app/pipe_router.go index 40ef49414..af0febff6 100644 --- a/app/pipe_router.go +++ b/app/pipe_router.go @@ -9,7 +9,7 @@ import ( log "github.com/Sirupsen/logrus" "golang.org/x/net/context" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/common/xfer" ) diff --git a/app/pipes_internal_test.go b/app/pipes_internal_test.go index 20bb6f760..ca1d7b680 100644 --- a/app/pipes_internal_test.go +++ b/app/pipes_internal_test.go @@ -15,7 +15,7 @@ import ( "github.com/gorilla/websocket" "golang.org/x/net/context" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/common/xfer" "github.com/weaveworks/scope/probe/appclient" "github.com/weaveworks/scope/probe/controls" diff --git a/app/weave.go b/app/weave.go index 3ae1b40d5..7ea371170 100644 --- a/app/weave.go +++ b/app/weave.go @@ -7,7 +7,7 @@ import ( fsouza "github.com/fsouza/go-dockerclient" - "github.com/weaveworks/scope/common/backoff" + "github.com/weaveworks/common/backoff" ) // Default values for weave app integration diff --git a/common/backoff/backoff.go b/common/backoff/backoff.go deleted file mode 100644 index 94f5ad6fb..000000000 --- a/common/backoff/backoff.go +++ /dev/null @@ -1,96 +0,0 @@ -package backoff - -import ( - "time" - - log "github.com/Sirupsen/logrus" -) - -type backoff struct { - f func() (bool, error) - quit, done chan struct{} - msg string - initialBackoff, maxBackoff time.Duration -} - -// Interface does f in a loop, sleeping for initialBackoff between -// each iterations. If it hits an error, it exponentially backs -// off to maxBackoff. Backoff will log when it backs off, but -// will stop logging when it reaches maxBackoff. It will also -// log on first success. -type Interface interface { - Start() - Stop() - SetInitialBackoff(time.Duration) - SetMaxBackoff(time.Duration) -} - -// New makes a new Interface -func New(f func() (bool, error), msg string) Interface { - return &backoff{ - f: f, - quit: make(chan struct{}), - done: make(chan struct{}), - msg: msg, - initialBackoff: 10 * time.Second, - maxBackoff: 60 * time.Second, - } -} - -func (b *backoff) SetInitialBackoff(d time.Duration) { - b.initialBackoff = d -} - -func (b *backoff) SetMaxBackoff(d time.Duration) { - b.maxBackoff = d -} - -// Stop the backoff, and waits for it to stop. -func (b *backoff) Stop() { - close(b.quit) - <-b.done -} - -// Start the backoff. Can only be called once. -func (b *backoff) Start() { - defer close(b.done) - backoff := b.initialBackoff - shouldLog := true - - for { - done, err := b.f() - if done { - return - } - - if err != nil { - backoff *= 2 - if backoff > b.maxBackoff { - backoff = b.maxBackoff - } - } else if backoff > b.initialBackoff { - backoff = b.initialBackoff - shouldLog = true - } - - if shouldLog { - if err != nil { - log.Warnf("Error %s, backing off %s: %s", - b.msg, backoff, err) - } else { - log.Infof("Success %s", b.msg) - } - } - - if backoff >= b.maxBackoff || err == nil { - shouldLog = false - } - - select { - case <-time.After(backoff): - case <-b.quit: - return - } - } - -} diff --git a/common/exec/exec.go b/common/exec/exec.go deleted file mode 100644 index fc0b27ad1..000000000 --- a/common/exec/exec.go +++ /dev/null @@ -1,30 +0,0 @@ -package exec - -import ( - "io" - "os/exec" -) - -// Cmd is a hook for mocking -type Cmd interface { - StdoutPipe() (io.ReadCloser, error) - StderrPipe() (io.ReadCloser, error) - Start() error - Wait() error - Kill() error - Output() ([]byte, error) - Run() error -} - -// Command is a hook for mocking -var Command = func(name string, args ...string) Cmd { - return &realCmd{exec.Command(name, args...)} -} - -type realCmd struct { - *exec.Cmd -} - -func (c *realCmd) Kill() error { - return c.Cmd.Process.Kill() -} diff --git a/common/fs/fs.go b/common/fs/fs.go deleted file mode 100644 index 6b9eb4162..000000000 --- a/common/fs/fs.go +++ /dev/null @@ -1,94 +0,0 @@ -package fs - -import ( - "io" - "io/ioutil" - "os" - "syscall" -) - -// Interface is the filesystem interface type. -type Interface interface { - ReadDir(string) ([]os.FileInfo, error) - ReadDirNames(string) ([]string, error) - ReadFile(string) ([]byte, error) - Lstat(string, *syscall.Stat_t) error - Stat(string, *syscall.Stat_t) error - Open(string) (io.ReadWriteCloser, error) -} - -type realFS struct{} - -// FS is the way you should access the filesystem. -var fs Interface = realFS{} - -func (realFS) ReadDir(path string) ([]os.FileInfo, error) { - return ioutil.ReadDir(path) -} - -func (realFS) ReadDirNames(path string) ([]string, error) { - fh, err := os.Open(path) - if err != nil { - return nil, err - } - defer fh.Close() - return fh.Readdirnames(-1) -} - -func (realFS) ReadFile(path string) ([]byte, error) { - return ioutil.ReadFile(path) -} - -func (realFS) Lstat(path string, stat *syscall.Stat_t) error { - return syscall.Lstat(path, stat) -} - -func (realFS) Stat(path string, stat *syscall.Stat_t) error { - return syscall.Stat(path, stat) -} - -func (realFS) Open(path string) (io.ReadWriteCloser, error) { - return os.Open(path) -} - -// trampolines here to allow users to do fs.ReadDir etc - -// ReadDir see ioutil.ReadDir -func ReadDir(path string) ([]os.FileInfo, error) { - return fs.ReadDir(path) -} - -// ReadDirNames see os.File.ReadDirNames -func ReadDirNames(path string) ([]string, error) { - return fs.ReadDirNames(path) -} - -// ReadFile see ioutil.ReadFile -func ReadFile(path string) ([]byte, error) { - return fs.ReadFile(path) -} - -// Lstat see syscall.Lstat -func Lstat(path string, stat *syscall.Stat_t) error { - return fs.Lstat(path, stat) -} - -// Stat see syscall.Stat -func Stat(path string, stat *syscall.Stat_t) error { - return fs.Stat(path, stat) -} - -// Open see os.Open -func Open(path string) (io.ReadWriteCloser, error) { - return fs.Open(path) -} - -// Mock is used to switch out the filesystem for a mock. -func Mock(mock Interface) { - fs = mock -} - -// Restore puts back the real filesystem. -func Restore() { - fs = realFS{} -} diff --git a/common/instrument/instrument.go b/common/instrument/instrument.go deleted file mode 100644 index d90aa90d3..000000000 --- a/common/instrument/instrument.go +++ /dev/null @@ -1,53 +0,0 @@ -package instrument - -import ( - "time" - - "github.com/opentracing/opentracing-go" - "github.com/opentracing/opentracing-go/ext" - "github.com/prometheus/client_golang/prometheus" - "golang.org/x/net/context" -) - -// ErrorCode converts an error in to an http-style error-code. -func ErrorCode(err error) string { - if err == nil { - return "200" - } - return "500" -} - -// TimeRequestHistogram runs 'f' and records how long it took in the given Prometheus -// histogram metric. If 'f' returns successfully, record a "200". Otherwise, record -// "500". It will also emit an OpenTracing span if you have a global tracer configured. -// -// If you want more complicated logic for translating errors into statuses, -// use 'TimeRequestStatus'. -func TimeRequestHistogram(ctx context.Context, method string, metric *prometheus.HistogramVec, f func(context.Context) error) error { - return TimeRequestHistogramStatus(ctx, method, metric, ErrorCode, f) -} - -// TimeRequestHistogramStatus runs 'f' and records how long it took in the given -// Prometheus histogram metric. It will also emit an OpenTracing span if you have -// a global tracer configured. -// -// toStatusCode is a function that translates errors returned by 'f' into -// HTTP-like status codes. -func TimeRequestHistogramStatus(ctx context.Context, method string, metric *prometheus.HistogramVec, toStatusCode func(error) string, f func(context.Context) error) error { - if toStatusCode == nil { - toStatusCode = ErrorCode - } - - sp, newCtx := opentracing.StartSpanFromContext(ctx, method) - ext.SpanKindRPCClient.Set(sp) - startTime := time.Now() - - err := f(newCtx) - - if err != nil { - ext.Error.Set(sp, true) - } - sp.Finish() - metric.WithLabelValues(method, toStatusCode(err)).Observe(time.Now().Sub(startTime).Seconds()) - return err -} diff --git a/common/middleware/errorhandler.go b/common/middleware/errorhandler.go deleted file mode 100644 index 0f7ab6141..000000000 --- a/common/middleware/errorhandler.go +++ /dev/null @@ -1,94 +0,0 @@ -package middleware - -import ( - "bufio" - "fmt" - "net" - "net/http" -) - -func copyHeaders(src, dest http.Header) { - for k, v := range src { - dest[k] = v - } -} - -// ErrorHandler lets you call an alternate http handler upon a certain response code. -// Note it will assume a 200 if the wrapped handler does not write anything -type ErrorHandler struct { - Code int - Handler http.Handler -} - -// Wrap implements Middleware -func (e ErrorHandler) Wrap(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - i := newErrorInterceptor(w, e.Code) - next.ServeHTTP(i, r) - if !i.gotCode { - i.WriteHeader(http.StatusOK) - } - if i.intercepted { - e.Handler.ServeHTTP(w, r) - } - }) -} - -// errorInterceptor wraps an underlying ResponseWriter and buffers all header changes, until it knows the return code. -// It then passes everything through, unless the code matches the target code, in which case it will discard everything. -type errorInterceptor struct { - originalWriter http.ResponseWriter - targetCode int - headers http.Header - gotCode bool - intercepted bool -} - -func newErrorInterceptor(w http.ResponseWriter, code int) *errorInterceptor { - i := errorInterceptor{originalWriter: w, targetCode: code} - i.headers = make(http.Header) - copyHeaders(w.Header(), i.headers) - return &i -} - -// Header implements http.ResponseWriter -func (i *errorInterceptor) Header() http.Header { - return i.headers -} - -// WriteHeader implements http.ResponseWriter -func (i *errorInterceptor) WriteHeader(code int) { - if i.gotCode { - panic("errorInterceptor.WriteHeader() called twice") - } - - i.gotCode = true - if code == i.targetCode { - i.intercepted = true - } else { - copyHeaders(i.headers, i.originalWriter.Header()) - i.originalWriter.WriteHeader(code) - } -} - -// Write implements http.ResponseWriter -func (i *errorInterceptor) Write(data []byte) (int, error) { - if !i.gotCode { - i.WriteHeader(http.StatusOK) - } - if !i.intercepted { - return i.originalWriter.Write(data) - } - return len(data), nil -} - -// errorInterceptor also implements net.Hijacker, to let the downstream Handler -// hijack the connection. This is needed, for example, for working with websockets. -func (i *errorInterceptor) Hijack() (net.Conn, *bufio.ReadWriter, error) { - hj, ok := i.originalWriter.(http.Hijacker) - if !ok { - return nil, nil, fmt.Errorf("error interceptor: can't cast original ResponseWriter to Hijacker") - } - i.gotCode = true - return hj.Hijack() -} diff --git a/common/middleware/instrument.go b/common/middleware/instrument.go deleted file mode 100644 index 676a59f6a..000000000 --- a/common/middleware/instrument.go +++ /dev/null @@ -1,84 +0,0 @@ -package middleware - -import ( - "net/http" - "regexp" - "strconv" - "strings" - "time" - - "github.com/gorilla/mux" - "github.com/prometheus/client_golang/prometheus" -) - -// Instrument is a Middleware which records timings for every HTTP request -type Instrument struct { - RouteMatcher interface { - Match(*http.Request, *mux.RouteMatch) bool - } - Duration *prometheus.HistogramVec -} - -func isWSHandshakeRequest(req *http.Request) bool { - return strings.ToLower(req.Header.Get("Upgrade")) == "websocket" && - strings.ToLower(req.Header.Get("Connection")) == "upgrade" -} - -// Wrap implements middleware.Interface -func (i Instrument) Wrap(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - begin := time.Now() - isWS := strconv.FormatBool(isWSHandshakeRequest(r)) - interceptor := &interceptor{ResponseWriter: w, statusCode: http.StatusOK} - route := i.getRouteName(r) - next.ServeHTTP(interceptor, r) - var ( - status = strconv.Itoa(interceptor.statusCode) - took = time.Since(begin) - ) - i.Duration.WithLabelValues(r.Method, route, status, isWS).Observe(took.Seconds()) - }) -} - -// Return a name identifier for ths request. There are three options: -// 1. The request matches a gorilla mux route, with a name. Use that. -// 2. The request matches an unamed gorilla mux router. Munge the path -// template such that templates like '/api/{org}/foo' come out as -// 'api_org_foo'. -// 3. The request doesn't match a mux route. Munge the Path in the same -// manner as (2). -// We do all this as we do not wish to emit high cardinality labels to -// prometheus. -func (i Instrument) getRouteName(r *http.Request) string { - var routeMatch mux.RouteMatch - if i.RouteMatcher != nil && i.RouteMatcher.Match(r, &routeMatch) { - if name := routeMatch.Route.GetName(); name != "" { - return name - } - if tmpl, err := routeMatch.Route.GetPathTemplate(); err != nil { - return MakeLabelValue(tmpl) - } - } - return MakeLabelValue(r.URL.Path) -} - -var invalidChars = regexp.MustCompile(`[^a-zA-Z0-9]+`) - -// MakeLabelValue converts a Gorilla mux path to a string suitable for use in -// a Prometheus label value. -func MakeLabelValue(path string) string { - // Convert non-alnums to underscores. - result := invalidChars.ReplaceAllString(path, "_") - - // Trim leading and trailing underscores. - result = strings.Trim(result, "_") - - // Make it all lowercase - result = strings.ToLower(result) - - // Special case. - if result == "" { - result = "root" - } - return result -} diff --git a/common/middleware/instrument_test.go b/common/middleware/instrument_test.go deleted file mode 100644 index 4a3c5bd99..000000000 --- a/common/middleware/instrument_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package middleware_test - -import ( - "testing" - - "github.com/weaveworks/scope/common/middleware" -) - -func TestMakeLabelValue(t *testing.T) { - for input, want := range map[string]string{ - "/": "root", // special case - "//": "root", // unintended consequence of special case - "a": "a", - "/foo": "foo", - "foo/": "foo", - "/foo/": "foo", - "/foo/bar": "foo_bar", - "foo/bar/": "foo_bar", - "/foo/bar/": "foo_bar", - "/foo/{orgName}/Bar": "foo_orgname_bar", - "/foo/{org_name}/Bar": "foo_org_name_bar", - "/foo/{org__name}/Bar": "foo_org_name_bar", - "/foo/{org___name}/_Bar": "foo_org_name_bar", - "/foo.bar/baz.qux/": "foo_bar_baz_qux", - } { - if have := middleware.MakeLabelValue(input); want != have { - t.Errorf("%q: want %q, have %q", input, want, have) - } - } -} diff --git a/common/middleware/logging.go b/common/middleware/logging.go deleted file mode 100644 index e05a80ce1..000000000 --- a/common/middleware/logging.go +++ /dev/null @@ -1,69 +0,0 @@ -package middleware - -import ( - "bufio" - "fmt" - "net" - "net/http" - "time" - - log "github.com/Sirupsen/logrus" -) - -// Log middleware logs http requests -type Log struct { - LogSuccess bool // LogSuccess true -> log successful queries; false -> only log failed queries -} - -// Wrap implements Middleware -func (l Log) Wrap(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - begin := time.Now() - uri := r.RequestURI // capture the URI before running next, as it may get rewritten - i := &interceptor{ResponseWriter: w, statusCode: http.StatusOK} - next.ServeHTTP(i, r) - if l.LogSuccess || !(100 <= i.statusCode && i.statusCode < 400) { - log.Infof("%s %s (%d) %s", r.Method, uri, i.statusCode, time.Since(begin)) - } - }) -} - -// Logging middleware logs each HTTP request method, path, response code and -// duration for all HTTP requests. -var Logging = Log{ - LogSuccess: true, -} - -// LogFailed middleware logs each HTTP request method, path, response code and -// duration for non-2xx HTTP requests. -var LogFailed = Log{ - LogSuccess: false, -} - -// interceptor implements WriteHeader to intercept status codes. WriteHeader -// may not be called on success, so initialize statusCode with the status you -// want to report on success, i.e. http.StatusOK. -// -// interceptor also implements net.Hijacker, to let the downstream Handler -// hijack the connection. This is needed, for example, for working with websockets. -type interceptor struct { - http.ResponseWriter - statusCode int - recorded bool -} - -func (i *interceptor) WriteHeader(code int) { - if !i.recorded { - i.statusCode = code - i.recorded = true - } - i.ResponseWriter.WriteHeader(code) -} - -func (i *interceptor) Hijack() (net.Conn, *bufio.ReadWriter, error) { - hj, ok := i.ResponseWriter.(http.Hijacker) - if !ok { - return nil, nil, fmt.Errorf("interceptor: can't cast parent ResponseWriter to Hijacker") - } - return hj.Hijack() -} diff --git a/common/middleware/middleware.go b/common/middleware/middleware.go deleted file mode 100644 index ad8925ac8..000000000 --- a/common/middleware/middleware.go +++ /dev/null @@ -1,33 +0,0 @@ -package middleware - -import ( - "net/http" -) - -// Interface is the shared contract for all middlesware, and allows middlesware -// to wrap handlers. -type Interface interface { - Wrap(http.Handler) http.Handler -} - -// Func is to Interface as http.HandlerFunc is to http.Handler -type Func func(http.Handler) http.Handler - -// Wrap implements Interface -func (m Func) Wrap(next http.Handler) http.Handler { - return m(next) -} - -// Identity is an Interface which doesn't do anything. -var Identity Interface = Func(func(h http.Handler) http.Handler { return h }) - -// Merge produces a middleware that applies multiple middlesware in turn; -// ie Merge(f,g,h).Wrap(handler) == f.Wrap(g.Wrap(h.Wrap(handler))) -func Merge(middlesware ...Interface) Interface { - return Func(func(next http.Handler) http.Handler { - for i := len(middlesware) - 1; i >= 0; i-- { - next = middlesware[i].Wrap(next) - } - return next - }) -} diff --git a/common/middleware/path_rewrite.go b/common/middleware/path_rewrite.go deleted file mode 100644 index 65eb2e9f2..000000000 --- a/common/middleware/path_rewrite.go +++ /dev/null @@ -1,42 +0,0 @@ -package middleware - -import ( - "net/http" - "regexp" -) - -// PathRewrite supports regex matching and replace on Request URIs -func PathRewrite(regexp *regexp.Regexp, replacement string) Interface { - return pathRewrite{ - regexp: regexp, - replacement: replacement, - } -} - -type pathRewrite struct { - regexp *regexp.Regexp - replacement string -} - -func (p pathRewrite) Wrap(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - r.RequestURI = p.regexp.ReplaceAllString(r.RequestURI, p.replacement) - r.URL.Path = p.regexp.ReplaceAllString(r.URL.Path, p.replacement) - next.ServeHTTP(w, r) - }) -} - -// PathReplace replcase Request.RequestURI with the specified string. -func PathReplace(replacement string) Interface { - return pathReplace(replacement) -} - -type pathReplace string - -func (p pathReplace) Wrap(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - r.URL.Path = string(p) - r.RequestURI = string(p) - next.ServeHTTP(w, r) - }) -} diff --git a/common/mtime/mtime.go b/common/mtime/mtime.go deleted file mode 100644 index dd1fc87ca..000000000 --- a/common/mtime/mtime.go +++ /dev/null @@ -1,16 +0,0 @@ -package mtime - -import "time" - -// Now returns the current time. -var Now = func() time.Time { return time.Now() } - -// NowForce sets the time returned by Now to t. -func NowForce(t time.Time) { - Now = func() time.Time { return t } -} - -// NowReset makes Now returns the current time again. -func NowReset() { - Now = func() time.Time { return time.Now() } -} diff --git a/common/network/interface.go b/common/network/interface.go deleted file mode 100644 index 9a94b9ac6..000000000 --- a/common/network/interface.go +++ /dev/null @@ -1,33 +0,0 @@ -package network - -import ( - "fmt" - "net" -) - -// GetFirstAddressOf returns the first IPv4 address of the supplied interface name. -func GetFirstAddressOf(name string) (string, error) { - inf, err := net.InterfaceByName(name) - if err != nil { - return "", err - } - - addrs, err := inf.Addrs() - if err != nil { - return "", err - } - if len(addrs) <= 0 { - return "", fmt.Errorf("No address found for %s", name) - } - - for _, addr := range addrs { - switch v := addr.(type) { - case *net.IPNet: - if ip := v.IP.To4(); ip != nil { - return v.IP.String(), nil - } - } - } - - return "", fmt.Errorf("No address found for %s", name) -} diff --git a/common/sanitize/sanitize.go b/common/sanitize/sanitize.go deleted file mode 100644 index 0ba4eae07..000000000 --- a/common/sanitize/sanitize.go +++ /dev/null @@ -1,44 +0,0 @@ -package sanitize - -import ( - "fmt" - "net" - "net/url" - "strings" - - log "github.com/Sirupsen/logrus" -) - -// URL returns a function that sanitizes a URL string. It lets underspecified -// strings to be converted to usable URLs via some default arguments. -func URL(defaultScheme string, defaultPort int, defaultPath string) func(string) string { - if defaultScheme == "" { - defaultScheme = "http://" - } - return func(s string) string { - if s == "" { - return s // can't do much here - } - if !strings.Contains(s, "://") { - s = defaultScheme + s - } - u, err := url.Parse(s) - if err != nil { - log.Errorf("%q: %v", s, err) - return s // oh well - } - if _, port, err := net.SplitHostPort(u.Host); err != nil && defaultPort > 0 { - u.Host += fmt.Sprintf(":%d", defaultPort) - } else if port == "443" { - if u.Scheme == "ws" { - u.Scheme = "wss" - } else { - u.Scheme = "https" - } - } - if defaultPath != "" && u.Path != defaultPath { - u.Path = defaultPath - } - return u.String() - } -} diff --git a/common/sanitize/sanitize_test.go b/common/sanitize/sanitize_test.go deleted file mode 100644 index b329d52ee..000000000 --- a/common/sanitize/sanitize_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package sanitize_test - -import ( - "testing" - - "github.com/weaveworks/scope/common/sanitize" -) - -func TestSanitizeURL(t *testing.T) { - for _, input := range []struct { - scheme string - port int - path string - input string - want string - }{ - {"", 0, "", "", ""}, - {"", 0, "", "foo", "http://foo"}, - {"", 80, "", "foo", "http://foo:80"}, - {"", 0, "some/path", "foo", "http://foo/some/path"}, - {"", 0, "/some/path", "foo", "http://foo/some/path"}, - {"https://", 0, "", "foo", "https://foo"}, - {"https://", 80, "", "foo", "https://foo:80"}, - {"https://", 0, "some/path", "foo", "https://foo/some/path"}, - {"https://", 0, "", "http://foo", "http://foo"}, // specified scheme beats default... - {"", 0, "", "https://foo", "https://foo"}, // https can be a specified scheme without default... - {"http://", 0, "", "https://foo", "https://foo"}, // https can be a specified scheme with default... - {"", 9999, "", "foo:80", "http://foo:80"}, // specified port beats default... - {"", 0, "/bar", "foo/baz", "http://foo/bar"}, // ...but default path beats specified! - {"", 0, "", "foo:443", "https://foo:443"}, // port 443 addrs default to https scheme - } { - if want, have := input.want, sanitize.URL(input.scheme, input.port, input.path)(input.input); want != have { - t.Errorf("sanitize.URL(%q, %d, %q)(%q): want %q, have %q", input.scheme, input.port, input.path, input.input, want, have) - continue - } - } -} diff --git a/common/weave/client.go b/common/weave/client.go index 359898ceb..921ee0a2f 100644 --- a/common/weave/client.go +++ b/common/weave/client.go @@ -12,7 +12,7 @@ import ( "github.com/ugorji/go/codec" - "github.com/weaveworks/scope/common/exec" + "github.com/weaveworks/common/exec" ) // Client for Weave Net API diff --git a/common/weave/client_test.go b/common/weave/client_test.go index 6dfe9168a..c94e8bfc2 100644 --- a/common/weave/client_test.go +++ b/common/weave/client_test.go @@ -10,7 +10,7 @@ import ( "sync" "testing" - "github.com/weaveworks/scope/common/exec" + "github.com/weaveworks/common/exec" "github.com/weaveworks/scope/common/weave" "github.com/weaveworks/scope/test" testExec "github.com/weaveworks/scope/test/exec" diff --git a/common/xfer/websocket.go b/common/xfer/websocket.go index 7aaeb791d..b96c93067 100644 --- a/common/xfer/websocket.go +++ b/common/xfer/websocket.go @@ -10,7 +10,7 @@ import ( "github.com/gorilla/websocket" "github.com/ugorji/go/codec" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" ) const ( diff --git a/probe/docker/container.go b/probe/docker/container.go index a93604431..50856ee0f 100644 --- a/probe/docker/container.go +++ b/probe/docker/container.go @@ -12,7 +12,7 @@ import ( log "github.com/Sirupsen/logrus" docker "github.com/fsouza/go-dockerclient" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/report" ) diff --git a/probe/docker/container_test.go b/probe/docker/container_test.go index 3b7270019..1098e13c7 100644 --- a/probe/docker/container_test.go +++ b/probe/docker/container_test.go @@ -7,7 +7,7 @@ import ( client "github.com/fsouza/go-dockerclient" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/probe/docker" "github.com/weaveworks/scope/report" "github.com/weaveworks/scope/test" diff --git a/probe/docker/registry_test.go b/probe/docker/registry_test.go index 2083ed15d..6f5da8aa5 100644 --- a/probe/docker/registry_test.go +++ b/probe/docker/registry_test.go @@ -11,7 +11,7 @@ import ( client "github.com/fsouza/go-dockerclient" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/probe/controls" "github.com/weaveworks/scope/probe/docker" "github.com/weaveworks/scope/report" diff --git a/probe/docker/tagger_test.go b/probe/docker/tagger_test.go index df16750aa..e128d6559 100644 --- a/probe/docker/tagger_test.go +++ b/probe/docker/tagger_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/probe/docker" "github.com/weaveworks/scope/probe/process" "github.com/weaveworks/scope/report" diff --git a/probe/endpoint/conntrack.go b/probe/endpoint/conntrack.go index 653eebed6..147008146 100644 --- a/probe/endpoint/conntrack.go +++ b/probe/endpoint/conntrack.go @@ -12,7 +12,7 @@ import ( log "github.com/Sirupsen/logrus" - "github.com/weaveworks/scope/common/exec" + "github.com/weaveworks/common/exec" ) const ( diff --git a/probe/endpoint/conntrack_internal_test.go b/probe/endpoint/conntrack_internal_test.go index fa2dad5ba..43df653fb 100644 --- a/probe/endpoint/conntrack_internal_test.go +++ b/probe/endpoint/conntrack_internal_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - "github.com/weaveworks/scope/common/exec" + "github.com/weaveworks/common/exec" "github.com/weaveworks/scope/test" testexec "github.com/weaveworks/scope/test/exec" ) diff --git a/probe/endpoint/nat_internal_test.go b/probe/endpoint/nat_internal_test.go index 6884afedb..3e0e7383b 100644 --- a/probe/endpoint/nat_internal_test.go +++ b/probe/endpoint/nat_internal_test.go @@ -3,7 +3,7 @@ package endpoint import ( "testing" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/report" "github.com/weaveworks/scope/test" "github.com/weaveworks/scope/test/reflect" diff --git a/probe/endpoint/procspy/proc_internal_test.go b/probe/endpoint/procspy/proc_internal_test.go index da8b9a480..dfbc8d91f 100644 --- a/probe/endpoint/procspy/proc_internal_test.go +++ b/probe/endpoint/procspy/proc_internal_test.go @@ -7,7 +7,7 @@ import ( "testing" "time" - fs_hook "github.com/weaveworks/scope/common/fs" + fs_hook "github.com/weaveworks/common/fs" "github.com/weaveworks/scope/probe/process" "github.com/weaveworks/scope/test/fs" ) diff --git a/probe/endpoint/procspy/proc_linux.go b/probe/endpoint/procspy/proc_linux.go index 0a73130ad..579d71be6 100644 --- a/probe/endpoint/procspy/proc_linux.go +++ b/probe/endpoint/procspy/proc_linux.go @@ -13,7 +13,7 @@ import ( log "github.com/Sirupsen/logrus" "github.com/armon/go-metrics" - "github.com/weaveworks/scope/common/fs" + "github.com/weaveworks/common/fs" "github.com/weaveworks/scope/common/marshal" "github.com/weaveworks/scope/probe/process" ) diff --git a/probe/endpoint/procspy/spy_linux_internal_test.go b/probe/endpoint/procspy/spy_linux_internal_test.go index bdbf11c8e..21af2b7c9 100644 --- a/probe/endpoint/procspy/spy_linux_internal_test.go +++ b/probe/endpoint/procspy/spy_linux_internal_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - fs_hook "github.com/weaveworks/scope/common/fs" + fs_hook "github.com/weaveworks/common/fs" "github.com/weaveworks/scope/probe/process" "github.com/weaveworks/scope/test" ) diff --git a/probe/host/reporter.go b/probe/host/reporter.go index 5135a1154..72a06c8d2 100644 --- a/probe/host/reporter.go +++ b/probe/host/reporter.go @@ -6,7 +6,7 @@ import ( "sync" "time" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/probe/controls" "github.com/weaveworks/scope/report" ) diff --git a/probe/host/reporter_test.go b/probe/host/reporter_test.go index 3e2805775..632f3b9a9 100644 --- a/probe/host/reporter_test.go +++ b/probe/host/reporter_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/probe/controls" "github.com/weaveworks/scope/probe/host" "github.com/weaveworks/scope/report" diff --git a/probe/kubernetes/reporter.go b/probe/kubernetes/reporter.go index b1bb21876..44c7c564a 100644 --- a/probe/kubernetes/reporter.go +++ b/probe/kubernetes/reporter.go @@ -8,7 +8,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/labels" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/probe" "github.com/weaveworks/scope/probe/controls" "github.com/weaveworks/scope/probe/docker" diff --git a/probe/overlay/weave.go b/probe/overlay/weave.go index 3a74dd4cd..819d88eb5 100644 --- a/probe/overlay/weave.go +++ b/probe/overlay/weave.go @@ -8,7 +8,7 @@ import ( "sync" "time" - "github.com/weaveworks/scope/common/backoff" + "github.com/weaveworks/common/backoff" "github.com/weaveworks/scope/common/weave" "github.com/weaveworks/scope/probe/docker" "github.com/weaveworks/scope/probe/host" diff --git a/probe/plugins/registry.go b/probe/plugins/registry.go index c9915127f..11d9d1db1 100644 --- a/probe/plugins/registry.go +++ b/probe/plugins/registry.go @@ -19,8 +19,8 @@ import ( "golang.org/x/net/context" "golang.org/x/net/context/ctxhttp" - "github.com/weaveworks/scope/common/backoff" - "github.com/weaveworks/scope/common/fs" + "github.com/weaveworks/common/backoff" + "github.com/weaveworks/common/fs" "github.com/weaveworks/scope/common/xfer" "github.com/weaveworks/scope/probe/controls" "github.com/weaveworks/scope/report" diff --git a/probe/plugins/registry_internal_test.go b/probe/plugins/registry_internal_test.go index a9f1a2262..1e28f0030 100644 --- a/probe/plugins/registry_internal_test.go +++ b/probe/plugins/registry_internal_test.go @@ -18,7 +18,7 @@ import ( "github.com/paypal/ionet" "github.com/ugorji/go/codec" - fs_hook "github.com/weaveworks/scope/common/fs" + fs_hook "github.com/weaveworks/common/fs" "github.com/weaveworks/scope/common/xfer" "github.com/weaveworks/scope/probe/controls" "github.com/weaveworks/scope/report" diff --git a/probe/probe_internal_test.go b/probe/probe_internal_test.go index 0202ad36c..6b6b4f005 100644 --- a/probe/probe_internal_test.go +++ b/probe/probe_internal_test.go @@ -7,7 +7,7 @@ import ( "time" "github.com/ugorji/go/codec" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/report" "github.com/weaveworks/scope/test" "github.com/weaveworks/scope/test/reflect" diff --git a/probe/process/cache.go b/probe/process/cache.go index 33aefc18c..3d076eb9b 100644 --- a/probe/process/cache.go +++ b/probe/process/cache.go @@ -6,7 +6,7 @@ import ( "github.com/armon/go-metrics" "github.com/coocood/freecache" - "github.com/weaveworks/scope/common/fs" + "github.com/weaveworks/common/fs" ) const ( diff --git a/probe/process/reporter.go b/probe/process/reporter.go index c0f8dd529..5dcbfcfd9 100644 --- a/probe/process/reporter.go +++ b/probe/process/reporter.go @@ -3,7 +3,7 @@ package process import ( "strconv" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/report" ) diff --git a/probe/process/reporter_test.go b/probe/process/reporter_test.go index aaf176844..d4bfe2a31 100644 --- a/probe/process/reporter_test.go +++ b/probe/process/reporter_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/probe/process" "github.com/weaveworks/scope/report" ) diff --git a/probe/process/walker_linux.go b/probe/process/walker_linux.go index 867f7538c..a46eacbae 100644 --- a/probe/process/walker_linux.go +++ b/probe/process/walker_linux.go @@ -10,7 +10,7 @@ import ( linuxproc "github.com/c9s/goprocinfo/linux" - "github.com/weaveworks/scope/common/fs" + "github.com/weaveworks/common/fs" "github.com/weaveworks/scope/probe/host" ) diff --git a/probe/process/walker_linux_test.go b/probe/process/walker_linux_test.go index 7c4b631e7..e5cd3bbcc 100644 --- a/probe/process/walker_linux_test.go +++ b/probe/process/walker_linux_test.go @@ -4,7 +4,7 @@ import ( "reflect" "testing" - fs_hook "github.com/weaveworks/scope/common/fs" + fs_hook "github.com/weaveworks/common/fs" "github.com/weaveworks/scope/probe/process" "github.com/weaveworks/scope/test" "github.com/weaveworks/scope/test/fs" diff --git a/prog/app.go b/prog/app.go index fada21497..0e66b8f19 100644 --- a/prog/app.go +++ b/prog/app.go @@ -21,10 +21,10 @@ import ( "github.com/weaveworks/go-checkpoint" "github.com/weaveworks/weave/common" + "github.com/weaveworks/common/middleware" + "github.com/weaveworks/common/network" "github.com/weaveworks/scope/app" "github.com/weaveworks/scope/app/multitenant" - "github.com/weaveworks/scope/common/middleware" - "github.com/weaveworks/scope/common/network" "github.com/weaveworks/scope/common/weave" "github.com/weaveworks/scope/probe/docker" ) diff --git a/prog/probe.go b/prog/probe.go index dd49881c7..f4030ea21 100644 --- a/prog/probe.go +++ b/prog/probe.go @@ -16,9 +16,9 @@ import ( "github.com/weaveworks/go-checkpoint" "github.com/weaveworks/weave/common" + "github.com/weaveworks/common/network" + "github.com/weaveworks/common/sanitize" "github.com/weaveworks/scope/common/hostname" - "github.com/weaveworks/scope/common/network" - "github.com/weaveworks/scope/common/sanitize" "github.com/weaveworks/scope/common/weave" "github.com/weaveworks/scope/common/xfer" "github.com/weaveworks/scope/probe" diff --git a/render/detailed/summary_test.go b/render/detailed/summary_test.go index 9bf78c128..ba866c16c 100644 --- a/render/detailed/summary_test.go +++ b/render/detailed/summary_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/probe/docker" "github.com/weaveworks/scope/probe/host" "github.com/weaveworks/scope/probe/process" diff --git a/render/filters.go b/render/filters.go index 3838ad32e..da39e0c44 100644 --- a/render/filters.go +++ b/render/filters.go @@ -3,7 +3,7 @@ package render import ( "strings" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/probe/docker" "github.com/weaveworks/scope/probe/endpoint" "github.com/weaveworks/scope/probe/kubernetes" diff --git a/render/short_lived_connections_test.go b/render/short_lived_connections_test.go index a2f4d9c25..f9bca6f69 100644 --- a/render/short_lived_connections_test.go +++ b/render/short_lived_connections_test.go @@ -4,7 +4,7 @@ import ( "fmt" "testing" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/probe/docker" "github.com/weaveworks/scope/probe/endpoint" diff --git a/report/controls.go b/report/controls.go index 80dd2b062..85eed408b 100644 --- a/report/controls.go +++ b/report/controls.go @@ -4,7 +4,7 @@ import ( "time" "github.com/ugorji/go/codec" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" ) // Controls describe the control tags within the Nodes diff --git a/report/node.go b/report/node.go index 858eeaabd..3ad71c6d3 100644 --- a/report/node.go +++ b/report/node.go @@ -3,7 +3,7 @@ package report import ( "time" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" ) // Node describes a superset of the metadata that probes can collect about a diff --git a/report/node_test.go b/report/node_test.go index 85add56cd..1c5f89ab4 100644 --- a/report/node_test.go +++ b/report/node_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/report" "github.com/weaveworks/scope/test" "github.com/weaveworks/scope/test/reflect" diff --git a/report/report.go b/report/report.go index 890ab5be1..e671891c5 100644 --- a/report/report.go +++ b/report/report.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/common/xfer" ) diff --git a/report/report_test.go b/report/report_test.go index 95c10b685..fa5b5f561 100644 --- a/report/report_test.go +++ b/report/report_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" "github.com/weaveworks/scope/report" "github.com/weaveworks/scope/test" s_reflect "github.com/weaveworks/scope/test/reflect" diff --git a/report/table.go b/report/table.go index 04d2abd05..74cbc1a71 100644 --- a/report/table.go +++ b/report/table.go @@ -7,7 +7,7 @@ import ( "time" log "github.com/Sirupsen/logrus" - "github.com/weaveworks/scope/common/mtime" + "github.com/weaveworks/common/mtime" ) // MaxTableRows sets the limit on the table size to render diff --git a/test/diff.go b/test/diff.go deleted file mode 100644 index 477ae98f9..000000000 --- a/test/diff.go +++ /dev/null @@ -1,22 +0,0 @@ -package test - -import ( - "github.com/davecgh/go-spew/spew" - "github.com/pmezard/go-difflib/difflib" -) - -// Diff diffs two arbitrary data structures, giving human-readable output. -func Diff(want, have interface{}) string { - config := spew.NewDefaultConfig() - config.ContinueOnMethod = true - config.SortKeys = true - config.SpewKeys = true - text, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ - A: difflib.SplitLines(config.Sdump(want)), - B: difflib.SplitLines(config.Sdump(have)), - FromFile: "want", - ToFile: "have", - Context: 3, - }) - return "\n" + text -} diff --git a/test/exec/exec.go b/test/exec/exec.go deleted file mode 100644 index 7e1dbe9dc..000000000 --- a/test/exec/exec.go +++ /dev/null @@ -1,79 +0,0 @@ -package exec - -import ( - "bytes" - "io" - "io/ioutil" - - "github.com/weaveworks/scope/common/exec" -) - -type mockCmd struct { - io.ReadCloser - quit chan struct{} -} - -type blockingReader struct { - quit chan struct{} -} - -// NewMockCmdString creates a new mock Cmd which has s on its stdout pipe -func NewMockCmdString(s string) exec.Cmd { - return &mockCmd{ - ReadCloser: struct { - io.Reader - io.Closer - }{ - bytes.NewBufferString(s), - ioutil.NopCloser(nil), - }, - quit: make(chan struct{}), - } -} - -// NewMockCmd creates a new mock Cmd with rc as its stdout pipe -func NewMockCmd(rc io.ReadCloser) exec.Cmd { - return &mockCmd{ - ReadCloser: rc, - quit: make(chan struct{}), - } -} - -func (c *mockCmd) Start() error { - return nil -} - -func (c *mockCmd) Wait() error { - return nil -} - -func (c *mockCmd) StdoutPipe() (io.ReadCloser, error) { - return c.ReadCloser, nil -} - -func (c *mockCmd) StderrPipe() (io.ReadCloser, error) { - return &blockingReader{c.quit}, nil -} - -func (c *mockCmd) Kill() error { - close(c.quit) - return nil -} - -func (c *mockCmd) Output() ([]byte, error) { - return ioutil.ReadAll(c.ReadCloser) -} - -func (c *mockCmd) Run() error { - return nil -} - -func (b *blockingReader) Read(p []byte) (n int, err error) { - <-b.quit - return 0, nil -} - -func (b *blockingReader) Close() error { - <-b.quit - return nil -} diff --git a/test/fs/fs.go b/test/fs/fs.go deleted file mode 100644 index 588cb7892..000000000 --- a/test/fs/fs.go +++ /dev/null @@ -1,287 +0,0 @@ -package fs - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "os" - "strings" - "syscall" - "time" - - "github.com/weaveworks/scope/common/fs" -) - -type mockInode struct{} - -type dir struct { - mockInode - name string - entries map[string]Entry - stat syscall.Stat_t -} - -// File is a mock file -type File struct { - mockInode - FName string - FContents string - FReader io.Reader - FWriter io.Writer - FCloser io.Closer - FStat syscall.Stat_t -} - -// Entry is an entry in the mock filesystem -type Entry interface { - os.FileInfo - fs.Interface - Add(path string, e Entry) error - Remove(path string) error -} - -// Dir creates a new directory with the given entries. -func Dir(name string, entries ...Entry) Entry { - result := dir{ - name: name, - entries: map[string]Entry{}, - } - - for _, entry := range entries { - result.entries[entry.Name()] = entry - } - - return result -} - -func split(path string) (string, string) { - if !strings.HasPrefix(path, "/") { - panic(path) - } - - comps := strings.SplitN(path, "/", 3) - if len(comps) == 2 { - return comps[1], "/" - } - - return comps[1], "/" + comps[2] -} - -func (mockInode) Size() int64 { return 0 } -func (mockInode) Mode() os.FileMode { return 0 } -func (mockInode) ModTime() time.Time { return time.Now() } -func (mockInode) Sys() interface{} { return nil } - -func (p dir) Name() string { return p.name } -func (p dir) IsDir() bool { return true } - -func (p dir) ReadDir(path string) ([]os.FileInfo, error) { - if path == "/" { - result := []os.FileInfo{} - for _, v := range p.entries { - result = append(result, v) - } - return result, nil - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - return nil, fmt.Errorf("Not found: %s", path) - } - - return fs.ReadDir(tail) -} - -func (p dir) ReadDirNames(path string) ([]string, error) { - if path == "/" { - result := []string{} - for _, v := range p.entries { - result = append(result, v.Name()) - } - return result, nil - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - return nil, fmt.Errorf("Not found: %s", path) - } - - return fs.ReadDirNames(tail) -} - -func (p dir) ReadFile(path string) ([]byte, error) { - if path == "/" { - return nil, fmt.Errorf("I'm a directory") - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - return nil, fmt.Errorf("Not found: %s", path) - } - - return fs.ReadFile(tail) -} - -func (p dir) Lstat(path string, stat *syscall.Stat_t) error { - if path == "/" { - *stat = syscall.Stat_t{Mode: syscall.S_IFDIR} - return nil - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - return fmt.Errorf("Not found: %s", path) - } - - return fs.Lstat(tail, stat) -} - -func (p dir) Stat(path string, stat *syscall.Stat_t) error { - if path == "/" { - *stat = syscall.Stat_t{Mode: syscall.S_IFDIR} - return nil - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - return fmt.Errorf("Not found: %s", path) - } - - return fs.Stat(tail, stat) -} - -func (p dir) Open(path string) (io.ReadWriteCloser, error) { - if path == "/" { - return nil, fmt.Errorf("I'm a directory") - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - return nil, fmt.Errorf("Not found: %s", path) - } - - return fs.Open(tail) -} - -func (p dir) Add(path string, e Entry) error { - if path == "/" { - p.entries[e.Name()] = e - return nil - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - fs = Dir(head) - p.entries[head] = fs - } - - return fs.Add(tail, e) -} - -func (p dir) Remove(path string) error { - if _, ok := p.entries[strings.TrimPrefix(path, "/")]; ok { - delete(p.entries, strings.TrimPrefix(path, "/")) - return nil - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - return nil - } - return fs.Remove(tail) -} - -// Name implements os.FileInfo -func (p File) Name() string { return p.FName } - -// IsDir implements os.FileInfo -func (p File) IsDir() bool { return false } - -// ReadDir implements FS -func (p File) ReadDir(path string) ([]os.FileInfo, error) { - return nil, fmt.Errorf("I'm a file") -} - -// ReadDirNames implements FS -func (p File) ReadDirNames(path string) ([]string, error) { - return nil, fmt.Errorf("I'm a file") -} - -// ReadFile implements FS -func (p File) ReadFile(path string) ([]byte, error) { - if path != "/" { - return nil, fmt.Errorf("I'm a file") - } - if p.FReader != nil { - return ioutil.ReadAll(p.FReader) - } - return []byte(p.FContents), nil -} - -// Lstat implements FS -func (p File) Lstat(path string, stat *syscall.Stat_t) error { - if path != "/" { - return fmt.Errorf("I'm a file") - } - *stat = p.FStat - return nil -} - -// Stat implements FS -func (p File) Stat(path string, stat *syscall.Stat_t) error { - if path != "/" { - return fmt.Errorf("I'm a file") - } - *stat = p.FStat - return nil -} - -// Open implements FS -func (p File) Open(path string) (io.ReadWriteCloser, error) { - if path != "/" { - return nil, fmt.Errorf("I'm a file") - } - buf := bytes.NewBuffer([]byte(p.FContents)) - s := struct { - io.Reader - io.Writer - io.Closer - }{ - buf, buf, ioutil.NopCloser(nil), - } - if p.FReader != nil { - s.Reader = p.FReader - } - if p.FWriter != nil { - s.Writer = p.FWriter - } - if p.FCloser != nil { - s.Closer = p.FCloser - } - return s, nil -} - -// Add adds a new node to the fs -func (p File) Add(path string, e Entry) error { - if path != "/" { - return fmt.Errorf("I'm a file") - } - return nil -} - -// Remove removes a node from the fs -func (p File) Remove(path string) error { - if path != "/" { - return fmt.Errorf("I'm a file") - } - return nil -}