From 2e14f1c2a9a28c74dc71adc4f866c1e56a558847 Mon Sep 17 00:00:00 2001 From: Rolf Neugebauer Date: Thu, 19 May 2016 10:49:07 +0100 Subject: [PATCH 1/5] go: vendor shared hvsock/vsock packages These packages will be shared by a number of utilities so vendoring them in a shared place. Signed-off-by: Rolf Neugebauer --- .../github.com/rneugeba/virtsock/go/LICENSE | 71 +++ .../rneugeba/virtsock/go/examples/client.go | 49 +++ .../rneugeba/virtsock/go/examples/hvgoecho.go | 131 ++++++ .../virtsock/go/examples/hvgostress.go | 243 +++++++++++ .../rneugeba/virtsock/go/hvsock/hvsock.go | 412 ++++++++++++++++++ .../virtsock/go/hvsock/hvsock_darwin.go | 69 +++ .../virtsock/go/hvsock/hvsock_linux.go | 147 +++++++ .../virtsock/go/hvsock/hvsock_windows.go | 309 +++++++++++++ .../virtsock/go/hvsock/zsyscall_windows.go | 100 +++++ .../rneugeba/virtsock/go/vsock/vsock_linux.go | 171 ++++++++ alpine/packages/go/vendor/manifest | 14 + 11 files changed, 1716 insertions(+) create mode 100644 alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/LICENSE create mode 100644 alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/examples/client.go create mode 100644 alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/examples/hvgoecho.go create mode 100644 alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/examples/hvgostress.go create mode 100644 alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock.go create mode 100644 alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_darwin.go create mode 100644 alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_linux.go create mode 100644 alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_windows.go create mode 100644 alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/zsyscall_windows.go create mode 100644 alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/vsock/vsock_linux.go create mode 100644 alpine/packages/go/vendor/manifest diff --git a/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/LICENSE b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/LICENSE new file mode 100644 index 000000000..a85d08915 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/LICENSE @@ -0,0 +1,71 @@ +Copyright 2016 Rolf Neugebauer + +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. + + +Some of the code in ./go/hvsock.go, ./go/hvsock_windows.go, and +zsyscall_windows.go is covered by the following licenses: +============================================================================== + +The MIT License (MIT) + +Copyright (c) 2015 Microsoft + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +and +=== + +Copyright (c) 2012 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. \ No newline at end of file diff --git a/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/examples/client.go b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/examples/client.go new file mode 100644 index 000000000..dd93b3439 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/examples/client.go @@ -0,0 +1,49 @@ +package main + +import ( + "bufio" + "flag" + "fmt" + "log" + + "../" +) + +var ( + vmstr string + portstr string +) + +func init() { + flag.StringVar(&vmstr, "vm", "", "Hyper-V VM to connect to") + flag.StringVar(&portstr, "port", "23a432c2-537a-4291-bcb5-d62504644739", "Hyper-V sockets service/port") +} + +func main() { + log.SetFlags(log.LstdFlags) + flag.Parse() + + vmid, err := hvsock.GuidFromString(vmstr) + if err != nil { + log.Fatalln("Failed to parse GUID", vmstr, err) + } + svcid, err := hvsock.GuidFromString(portstr) + if err != nil { + log.Fatalln("Failed to parse GUID", portstr, err) + } + + c, err := hvsock.Dial(hvsock.HypervAddr{VmId: vmid, ServiceId: svcid}) + if err != nil { + log.Fatalln("Failed to Dial:\n", vmstr, portstr, err) + } + + fmt.Println("Send: hello") + l, err := fmt.Fprintf(c, "hello\n") + if err != nil { + log.Fatalln("Failed to send: ", err) + } + fmt.Println("Sent: %s bytes", l) + + message, _ := bufio.NewReader(c).ReadString('\n') + fmt.Println("From SVR: " + message) +} diff --git a/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/examples/hvgoecho.go b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/examples/hvgoecho.go new file mode 100644 index 000000000..f0ab0f4c0 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/examples/hvgoecho.go @@ -0,0 +1,131 @@ +package main + +import ( + "bufio" + "flag" + "fmt" + "io" + "log" + "net" + "strings" + + "../hvsock" +) + +var ( + clientStr string + serverMode bool + + svcid, _ = hvsock.GuidFromString("3049197C-9A4E-4FBF-9367-97F792F16994") +) + +func init() { + flag.StringVar(&clientStr, "c", "", "Client") + flag.BoolVar(&serverMode, "s", false, "Start as a Server") +} + +func server() { + l, err := hvsock.Listen(hvsock.HypervAddr{VmId: hvsock.GUID_WILDCARD, ServiceId: svcid}) + if err != nil { + log.Fatalln("Listen():", err) + } + defer func() { + l.Close() + }() + + for { + conn, err := l.Accept() + if err != nil { + log.Fatalln("Accept(): ", err) + } + fmt.Printf("Received message %s -> %s \n", conn.RemoteAddr(), conn.LocalAddr()) + + go handleRequest(conn) + } +} + +func handleRequest(c net.Conn) { + defer func() { + fmt.Printf("Closing\n") + err := c.Close() + if err != nil { + log.Fatalln("Close():", err) + } + }() + + n, err := io.Copy(c, c) + if err != nil { + log.Fatalln("Copy():", err) + } + fmt.Printf("Copied Bytes: %d\n", n) + + fmt.Printf("Sending BYE message\n") + // The '\n' is important as the client use ReadString() + _, err = fmt.Fprintf(c, "Got %d bytes. Bye\n", n) + if err != nil { + log.Fatalln("Failed to send: ", err) + } + fmt.Printf("Sent bye\n") +} + +func client(vmid hvsock.GUID) { + sa := hvsock.HypervAddr{VmId: vmid, ServiceId: svcid} + c, err := hvsock.Dial(sa) + if err != nil { + log.Fatalln("Failed to Dial:\n", sa.VmId.String(), sa.ServiceId.String(), err) + } + + defer func() { + fmt.Printf("Closing\n") + c.Close() + }() + + fmt.Printf("Send: hello\n") + // Note the '\n' is significant as we use ReadString below + l, err := fmt.Fprintf(c, "hello\n") + if err != nil { + log.Fatalln("Failed to send: ", err) + } + fmt.Printf("Sent: %d bytes\n", l) + + message, err := bufio.NewReader(c).ReadString('\n') + if err != nil { + log.Fatalln("Failed to receive: ", err) + } + fmt.Printf("From SVR: %s", message) + + fmt.Printf("CloseWrite()\n") + c.CloseWrite() + + fmt.Printf("Waiting for Bye message\n") + message, err = bufio.NewReader(c).ReadString('\n') + if err != nil { + log.Fatalln("Failed to receive: ", err) + } + fmt.Printf("From SVR: %s", message) +} + +func main() { + log.SetFlags(log.LstdFlags) + flag.Parse() + + if serverMode { + fmt.Printf("Starting server\n") + server() + } + + vmid := hvsock.GUID_ZERO + var err error + if strings.Contains(clientStr, "-") { + vmid, err = hvsock.GuidFromString(clientStr) + if err != nil { + log.Fatalln("Can't parse GUID: ", clientStr) + } + } else if clientStr == "parent" { + vmid = hvsock.GUID_PARENT + } else { + vmid = hvsock.GUID_LOOPBACK + } + fmt.Printf("Client connecting to %s", vmid.String()) + client(vmid) +} diff --git a/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/examples/hvgostress.go b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/examples/hvgostress.go new file mode 100644 index 000000000..ddb66dc71 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/examples/hvgostress.go @@ -0,0 +1,243 @@ +package main + +import ( + "bufio" + "flag" + "fmt" + "io" + "log" + "net" + "strings" + "sync" + "time" + + "crypto/md5" + "math/rand" + "sync/atomic" + + "../hvsock" +) + +var ( + clientStr string + serverMode bool + maxDataLen int + connections int + sleepTime int + verbose int + exitOnError bool + parallel int + svcid, _ = hvsock.GuidFromString("3049197C-9A4E-4FBF-9367-97F792F16994") + + connCounter int32 +) + +func init() { + flag.StringVar(&clientStr, "c", "", "Client") + flag.BoolVar(&serverMode, "s", false, "Start as a Server") + flag.IntVar(&maxDataLen, "l", 64*1024, "Maximum Length of data") + flag.IntVar(&connections, "i", 100, "Total number of connections") + flag.IntVar(&sleepTime, "w", 0, "Sleep time in seconds between new connections") + flag.IntVar(¶llel, "p", 1, "Run n connections in parallel") + flag.BoolVar(&exitOnError, "e", false, "Exit when an error occurs") + flag.IntVar(&verbose, "v", 0, "Set the verbosity level") + + rand.Seed(time.Now().UnixNano()) +} + +func main() { + log.SetFlags(log.LstdFlags) + flag.Parse() + + if verbose > 2 { + hvsock.Debug = true + } + + if serverMode { + fmt.Printf("Starting server\n") + server() + return + } + + // Client mode + vmid := hvsock.GUID_ZERO + var err error + if strings.Contains(clientStr, "-") { + vmid, err = hvsock.GuidFromString(clientStr) + if err != nil { + log.Fatalln("Can't parse GUID: ", clientStr) + } + } else if clientStr == "parent" { + vmid = hvsock.GUID_PARENT + } else { + vmid = hvsock.GUID_LOOPBACK + } + + if parallel <= 1 { + // No parallelism, run in the main thread. + fmt.Printf("Client connecting to %s\n", vmid.String()) + for i := 0; i < connections; i++ { + client(vmid, i) + time.Sleep(time.Duration(sleepTime) * time.Second) + } + return + } + + // Parallel clients + var wg sync.WaitGroup + for i := 0; i < parallel; i++ { + wg.Add(1) + go parClient(&wg, vmid) + } + wg.Wait() +} + +func server() { + l, err := hvsock.Listen(hvsock.HypervAddr{VmId: hvsock.GUID_WILDCARD, ServiceId: svcid}) + if err != nil { + log.Fatalln("Listen():", err) + } + defer func() { + l.Close() + }() + + connid := 0 + + for { + conn, err := l.Accept() + if err != nil { + log.Fatalf("Accept(): %s\n", err) + } + + prDebug("[%05d] accept(): %s -> %s \n", connid, conn.RemoteAddr(), conn.LocalAddr()) + go handleRequest(conn, connid) + connid++ + } +} + +func handleRequest(c net.Conn, connid int) { + defer func() { + prDebug("[%05d] Closing\n", connid) + err := c.Close() + if err != nil { + prError("[%05d] Close(): %s\n", connid, err) + } + }() + + n, err := io.Copy(c, c) + if err != nil { + prError("[%05d] Copy(): %s", connid, err) + return + } + prInfo("[%05d] Copied Bytes: %d\n", connid, n) + + if n == 0 { + return + } + + prDebug("[%05d] Sending BYE message\n", connid) + + // The '\n' is important as the client use ReadString() + _, err = fmt.Fprintf(c, "Got %d bytes. Bye\n", n) + if err != nil { + prError("[%05d] Failed to send: %s", connid, err) + return + } + prDebug("[%05d] Sent bye\n", connid) +} + +func parClient(wg *sync.WaitGroup, vmid hvsock.GUID) { + connid := int(atomic.AddInt32(&connCounter, 1)) + for connid < connections { + client(vmid, connid) + connid = int(atomic.AddInt32(&connCounter, 1)) + time.Sleep(time.Duration(sleepTime) * time.Second) + } + + wg.Done() +} + +func client(vmid hvsock.GUID, conid int) { + sa := hvsock.HypervAddr{VmId: vmid, ServiceId: svcid} + c, err := hvsock.Dial(sa) + if err != nil { + prError("[%05d] Failed to Dial: %s:%s %s\n", conid, sa.VmId.String(), sa.ServiceId.String(), err) + } + + defer c.Close() + + // Create buffer with random data and random length. + // Make sure the buffer is not zero-length + buflen := rand.Intn(maxDataLen-1) + 1 + txbuf := randBuf(buflen) + csum0 := md5.Sum(txbuf) + + prDebug("[%05d] TX: %d bytes, md5=%02x\n", conid, buflen, csum0) + + w := make(chan int) + go func() { + l, err := c.Write(txbuf) + if err != nil { + prError("[%05d] Failed to send: %s\n", conid, err) + } + if l != buflen { + prError("[%05d] Failed to send enough data: %d\n", conid, l) + } + + // Tell the other end that we are done + c.CloseWrite() + + w <- l + }() + + rxbuf := make([]byte, buflen) + + n, err := io.ReadFull(bufio.NewReader(c), rxbuf) + if err != nil { + prError("[%05d] Failed to receive: %s\n", conid, err) + return + } + csum1 := md5.Sum(rxbuf) + + totalSent := <-w + + prInfo("[%05d] RX: %d bytes, md5=%02x (sent=%d)\n", conid, n, csum1, totalSent) + if csum0 != csum1 { + prError("[%05d] Checksums don't match", conid) + } + + // Wait for Bye message + message, err := bufio.NewReader(c).ReadString('\n') + if err != nil { + prError("[%05d] Failed to receive bye: %s\n", conid, err) + } + prDebug("[%05d] From SVR: %s", conid, message) +} + +func randBuf(n int) []byte { + b := make([]byte, n) + for i := range b { + b[i] = byte(rand.Intn(255)) + } + return b +} + +func prError(format string, args ...interface{}) { + if exitOnError { + log.Fatalf(format, args...) + } else { + log.Printf(format, args...) + } +} + +func prInfo(format string, args ...interface{}) { + if verbose > 0 { + log.Printf(format, args...) + } +} + +func prDebug(format string, args ...interface{}) { + if verbose > 1 { + log.Printf(format, args...) + } +} diff --git a/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock.go b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock.go new file mode 100644 index 000000000..d8d7a49b3 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock.go @@ -0,0 +1,412 @@ +package hvsock + +import ( + "errors" + "fmt" + "io" + "log" + "net" + "sync" + "syscall" + + "encoding/binary" +) + +// This package provides a Go interface to Hyper-V sockets both on +// Windows and on Linux (assuming the appropriate Linux kernel patches +// have been applied). +// +// Unfortunately, it is not easy/possible to extend the existing Go +// socket implementations with new Address Families, so this module +// wraps directly around system calls (and handles Windows' +// asynchronous system calls). +// +// There is an additional wrinkle. Hyper-V sockets in currently +// shipping versions of Windows don't support graceful and/or +// unidirectional shutdown(). So we turn a stream based protocol into +// message based protocol which allows to send in-line "messages" to +// the other end. We then provide a stream based interface on top of +// that. Yuk. +// +// The message interface is pretty simple. We first send a 32bit +// message containing the size of the data in the following +// message. Messages are limited to 'maxmsgsize'. Special message +// (without data), `shutdownrd` and 'shutdownwr' are used to used to +// signal a shutdown to the other end. + +const ( + maxMsgSize = 32 * 1024 // Maximum message size +) + +// Hypper-V sockets use GUIDs for addresses and "ports" +type GUID [16]byte + +// Convert a GUID into a string +func (g *GUID) String() string { + /* XXX This assume little endian */ + return fmt.Sprintf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + g[3], g[2], g[1], g[0], + g[5], g[4], + g[7], g[6], + g[8], g[9], + g[10], g[11], g[12], g[13], g[14], g[15]) +} + +// Parse a GUID string +func GuidFromString(s string) (GUID, error) { + var g GUID + var err error + _, err = fmt.Sscanf(s, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + &g[3], &g[2], &g[1], &g[0], + &g[5], &g[4], + &g[7], &g[6], + &g[8], &g[9], + &g[10], &g[11], &g[12], &g[13], &g[14], &g[15]) + return g, err +} + +type HypervAddr struct { + VmId GUID + ServiceId GUID +} + +func (a HypervAddr) Network() string { return "hvsock" } + +func (a HypervAddr) String() string { + vmid := a.VmId.String() + svc := a.ServiceId.String() + + return vmid + ":" + svc +} + +var ( + Debug = false // Set to True to enable additional debug output + + GUID_ZERO, _ = GuidFromString("00000000-0000-0000-0000-000000000000") + GUID_WILDCARD, _ = GuidFromString("00000000-0000-0000-0000-000000000000") + GUID_BROADCAST, _ = GuidFromString("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF") + GUID_CHILDREN, _ = GuidFromString("90db8b89-0d35-4f79-8ce9-49ea0ac8b7cd") + GUID_LOOPBACK, _ = GuidFromString("e0e16197-dd56-4a10-9195-5ee7a155a838") + GUID_PARENT, _ = GuidFromString("a42e7cda-d03f-480c-9cc2-a4de20abb878") +) + +func Dial(raddr HypervAddr) (Conn, error) { + fd, err := syscall.Socket(AF_HYPERV, syscall.SOCK_STREAM, SHV_PROTO_RAW) + if err != nil { + return nil, err + } + + err = connect(fd, &raddr) + if err != nil { + return nil, err + } + + v, err := newHVsockConn(fd, HypervAddr{VmId: GUID_ZERO, ServiceId: GUID_ZERO}, raddr) + if err != nil { + return nil, err + } + v.wrlock = &sync.Mutex{} + return v, nil +} + +func Listen(addr HypervAddr) (net.Listener, error) { + + accept_fd, err := syscall.Socket(AF_HYPERV, syscall.SOCK_STREAM, SHV_PROTO_RAW) + if err != nil { + return nil, err + } + + err = bind(accept_fd, addr) + if err != nil { + return nil, err + } + + err = syscall.Listen(accept_fd, syscall.SOMAXCONN) + if err != nil { + return nil, err + } + + return &hvsockListener{accept_fd, addr}, nil +} + +const ( + shutdownrd = 0xdeadbeef // Message for CloseRead() + shutdownwr = 0xbeefdead // Message for CloseWrite() + closemsg = 0xdeaddead // Message for Close() +) + +// Conn is a hvsock connection which support half-close. +type Conn interface { + net.Conn + CloseRead() error + CloseWrite() error +} + +func (v *hvsockListener) Accept() (net.Conn, error) { + var raddr HypervAddr + fd, err := accept(v.accept_fd, &raddr) + if err != nil { + return nil, err + } + + a, err := newHVsockConn(fd, v.laddr, raddr) + if err != nil { + return nil, err + } + a.wrlock = &sync.Mutex{} + return a, nil +} + +func (v *hvsockListener) Close() error { + // Note this won't cause the Accept to unblock. + return syscall.Close(v.accept_fd) +} + +func (v *hvsockListener) Addr() net.Addr { + return HypervAddr{VmId: v.laddr.VmId, ServiceId: v.laddr.ServiceId} +} + +/* + * A wrapper around FileConn which supports CloseRead and CloseWrite + */ + +var ( + errSocketClosed = errors.New("HvSocket has already been closed") + errSocketWriteClosed = errors.New("HvSocket has been closed for write") + errSocketReadClosed = errors.New("HvSocket has been closed for read") + errSocketMsgSize = errors.New("HvSocket message was of wrong size") + errSocketMsgWrite = errors.New("HvSocket writing message") + errSocketNotEnoughData = errors.New("HvSocket not enough data written") + errSocketUnImplemented = errors.New("Function not implemented") +) + +type HVsockConn struct { + hvsockConn + + wrlock *sync.Mutex + + writeClosed bool + readClosed bool + + bytesToRead int +} + +func (v *HVsockConn) LocalAddr() net.Addr { + return v.local +} + +func (v *HVsockConn) RemoteAddr() net.Addr { + return v.remote +} + +func (v *HVsockConn) Close() error { + prDebug("Close\n") + + v.readClosed = true + v.writeClosed = true + + prDebug("TX: Close\n") + v.wrlock.Lock() + err := v.sendMsg(closemsg) + v.wrlock.Unlock() + if err != nil { + // chances are that the other end beat us to the close + prDebug("Mmmm. %s\n", err) + return v.close() + } + + // wait for reply/ignore errors + // we may get a EOF because the other end closed, + b := make([]byte, 4) + _, _ = v.read(b) + prDebug("close\n") + return v.close() +} + +func (v *HVsockConn) CloseRead() error { + if v.readClosed { + return errSocketReadClosed + } + + prDebug("TX: Shutdown Read\n") + v.wrlock.Lock() + err := v.sendMsg(shutdownrd) + v.wrlock.Unlock() + if err != nil { + return err + } + + v.readClosed = true + return nil +} + +func (v *HVsockConn) CloseWrite() error { + if v.writeClosed { + return errSocketWriteClosed + } + + prDebug("TX: Shutdown Write\n") + v.wrlock.Lock() + err := v.sendMsg(shutdownwr) + v.wrlock.Unlock() + if err != nil { + return err + } + + v.writeClosed = true + return nil +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +// Read into buffer. This function turns a stream interface into +// messages and also handles the inband control messages. +func (v *HVsockConn) Read(buf []byte) (int, error) { + if v.readClosed { + return 0, io.EOF + } + + if v.bytesToRead == 0 { + for { + // wait for next message + b := make([]byte, 4) + + n, err := v.read(b) + if err != nil { + return 0, err + } + + if n != 4 { + return n, errSocketMsgSize + } + + msg := int(binary.LittleEndian.Uint32(b)) + if msg == shutdownwr { + // The other end shutdown write. No point reading more + v.readClosed = true + prDebug("RX: ShutdownWrite\n") + return 0, io.EOF + } else if msg == shutdownrd { + // The other end shutdown read. No point writing more + v.writeClosed = true + prDebug("RX: ShutdownRead\n") + } else if msg == closemsg { + // Setting write close here forces a proper close + v.writeClosed = true + prDebug("RX: Close\n") + v.Close() + } else { + v.bytesToRead = msg + if v.bytesToRead == 0 { + // XXX Something is odd. If I don't have this here, this + // case is hit. However, with this code in place this + // case never get's hit. Suspect overly eager GC... + log.Printf("RX: Zero length %02x", b) + continue + } + break + } + } + } + + // If we get here, we know there is v.bytesToRead worth of + // data coming our way. Read it directly into to buffer passed + // in by the caller making sure we do not read mode than we + // should read by splicing the buffer. + toRead := min(len(buf), v.bytesToRead) + prDebug("READ: %d len=0x%x\n", int(v.fd), toRead) + n, err := v.read(buf[:toRead]) + if err != nil || n == 0 { + v.readClosed = true + return n, err + } + v.bytesToRead -= n + return n, nil +} + +func (v *HVsockConn) Write(buf []byte) (int, error) { + if v.writeClosed { + return 0, errSocketWriteClosed + } + + var err error + toWrite := len(buf) + written := 0 + + prDebug("WRITE: %d Total len=%x\n", int(v.fd), len(buf)) + + for toWrite > 0 { + if v.writeClosed { + return 0, errSocketWriteClosed + } + + // We write batches of MSG + data which need to be + // "atomic". We don't want to hold the lock for the + // entire Write() in case some other threads wants to + // send OOB data, e.g. for closing. + + v.wrlock.Lock() + + thisBatch := min(toWrite, maxMsgSize) + prDebug("WRITE: %d len=%x\n", int(v.fd), thisBatch) + // Write message header + err = v.sendMsg(uint32(thisBatch)) + if err != nil { + prDebug("Write MSG Error: %s\n", err) + goto ErrOut + } + + // Write data + n, err := v.write(buf[written : written+thisBatch]) + if err != nil { + prDebug("Write Error 3\n") + goto ErrOut + } + if n != thisBatch { + prDebug("Write Error 4\n") + err = errSocketNotEnoughData + goto ErrOut + } + toWrite -= n + written += n + v.wrlock.Unlock() + } + + return written, nil + +ErrOut: + v.wrlock.Unlock() + v.writeClosed = true + return 0, err +} + +// hvsockConn, SetDeadline(), SetReadDeadline(), and +// SetWriteDeadline() are OS specific. + +// Send a message to the other end +// The Lock must be held to call this functions +func (v *HVsockConn) sendMsg(msg uint32) error { + b := make([]byte, 4) + + binary.LittleEndian.PutUint32(b, msg) + n, err := v.write(b) + if err != nil { + prDebug("Write Error 1\n") + return err + } + if n != len(b) { + return errSocketMsgWrite + } + return nil +} + +func prDebug(format string, args ...interface{}) { + if Debug { + log.Printf(format, args...) + } +} diff --git a/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_darwin.go b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_darwin.go new file mode 100644 index 000000000..c448fb072 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_darwin.go @@ -0,0 +1,69 @@ +// Dummy implementation to compile on Mac OSX + +package hvsock +import ( + "errors" + "time" +) + +const ( + AF_HYPERV = 42 + SHV_PROTO_RAW = 1 +) + +type hvsockListener struct { + accept_fd int + laddr HypervAddr +} + +// +// System call wrapper +// +func connect(s int, a *HypervAddr) (err error) { + return errors.New("connect() not implemented") +} + +func bind(s int, a HypervAddr) error { + return errors.New("bind() not implemented") +} + +func accept(s int, a *HypervAddr) (int, error) { + return 0, errors.New("accept() not implemented") +} + +// Internal representation. Complex mostly due to asynch send()/recv() syscalls. +type hvsockConn struct { + fd int + local HypervAddr + remote HypervAddr +} + +// Main constructor +func newHVsockConn(fd int, local HypervAddr, remote HypervAddr) (*HVsockConn, error) { + v := &hvsockConn{local: local, remote: remote} + return &HVsockConn{hvsockConn: *v}, errors.New("newHVsockConn() not implemented") +} + +func (v *HVsockConn) close() error { + return errors.New("close() not implemented") +} + +func (v *HVsockConn) read(buf []byte) (int, error) { + return 0, errors.New("read() not implemented") +} + +func (v *HVsockConn) write(buf []byte) (int, error) { + return 0, errors.New("write() not implemented") +} + +func (v *HVsockConn) SetReadDeadline(t time.Time) error { + return nil // FIXME +} + +func (v *HVsockConn) SetWriteDeadline(t time.Time) error { + return nil // FIXME +} + +func (v *HVsockConn) SetDeadline(t time.Time) error { + return nil // FIXME +} diff --git a/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_linux.go b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_linux.go new file mode 100644 index 000000000..53d287c6f --- /dev/null +++ b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_linux.go @@ -0,0 +1,147 @@ +package hvsock + +/* +#include + +struct sockaddr_hv { + unsigned short shv_family; + unsigned short reserved; + unsigned char shv_vm_id[16]; + unsigned char shv_service_id[16]; +}; +int bind_sockaddr_hv(int fd, const struct sockaddr_hv *sa_hv) { + return bind(fd, (const struct sockaddr*)sa_hv, sizeof(*sa_hv)); +} +int connect_sockaddr_hv(int fd, const struct sockaddr_hv *sa_hv) { + return connect(fd, (const struct sockaddr*)sa_hv, sizeof(*sa_hv)); +} +int accept_hv(int fd, struct sockaddr_hv *sa_hv, socklen_t *sa_hv_len) { + return accept4(fd, (struct sockaddr *)sa_hv, sa_hv_len, 0); +} +*/ +import "C" + +import ( + "errors" + "fmt" + "os" + "strconv" + "time" +) + +const ( + AF_HYPERV = 43 + SHV_PROTO_RAW = 1 +) + +type hvsockListener struct { + accept_fd int + laddr HypervAddr +} + +// +// System call wrapper +// +func connect(s int, a *HypervAddr) (err error) { + sa := C.struct_sockaddr_hv{} + sa.shv_family = AF_HYPERV + sa.reserved = 0 + + for i := 0; i < 16; i++ { + sa.shv_vm_id[i] = C.uchar(a.VmId[i]) + } + for i := 0; i < 16; i++ { + sa.shv_service_id[i] = C.uchar(a.ServiceId[i]) + } + + if ret := C.connect_sockaddr_hv(C.int(s), &sa); ret != 0 { + return errors.New("connect() returned " + strconv.Itoa(int(ret))) + } + + return nil +} + +func bind(s int, a HypervAddr) error { + sa := C.struct_sockaddr_hv{} + sa.shv_family = AF_HYPERV + sa.reserved = 0 + + for i := 0; i < 16; i++ { + // XXX this should take the address from `a` but Linux + // currently only support 0s + sa.shv_vm_id[i] = C.uchar(GUID_ZERO[i]) + } + for i := 0; i < 16; i++ { + sa.shv_service_id[i] = C.uchar(a.ServiceId[i]) + } + + if ret := C.bind_sockaddr_hv(C.int(s), &sa); ret != 0 { + return errors.New("bind() returned " + strconv.Itoa(int(ret))) + } + + return nil +} + +func accept(s int, a *HypervAddr) (int, error) { + var accept_sa C.struct_sockaddr_hv + var accept_sa_len C.socklen_t + + accept_sa_len = C.sizeof_struct_sockaddr_hv + fd, err := C.accept_hv(C.int(s), &accept_sa, &accept_sa_len) + if err != nil { + return -1, err + } + + a.VmId = guidFromC(accept_sa.shv_vm_id) + a.ServiceId = guidFromC(accept_sa.shv_service_id) + + return int(fd), nil +} + +// Internal representation. Complex mostly due to asynch send()/recv() syscalls. +type hvsockConn struct { + fd int + hvsock *os.File + local HypervAddr + remote HypervAddr +} + +// Main constructor +func newHVsockConn(fd int, local HypervAddr, remote HypervAddr) (*HVsockConn, error) { + hvsock := os.NewFile(uintptr(fd), fmt.Sprintf("hvsock:%d", fd)) + v := &hvsockConn{fd: fd, hvsock: hvsock, local: local, remote: remote} + + return &HVsockConn{hvsockConn: *v}, nil +} + +func (v *HVsockConn) close() error { + return v.hvsock.Close() +} + +func (v *HVsockConn) read(buf []byte) (int, error) { + return v.hvsock.Read(buf) +} + +func (v *HVsockConn) write(buf []byte) (int, error) { + return v.hvsock.Write(buf) +} + +func (v *HVsockConn) SetReadDeadline(t time.Time) error { + return nil // FIXME +} + +func (v *HVsockConn) SetWriteDeadline(t time.Time) error { + return nil // FIXME +} + +func (v *HVsockConn) SetDeadline(t time.Time) error { + return nil // FIXME +} + +func guidFromC(cg [16]C.uchar) GUID { + var g GUID + for i := 0; i < 16; i++ { + g[i] = byte(cg[i]) + } + return g +} diff --git a/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_windows.go b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_windows.go new file mode 100644 index 000000000..973f3ff16 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/hvsock_windows.go @@ -0,0 +1,309 @@ +package hvsock + +import ( + "errors" + "io" + "log" + "sync" + "syscall" + "time" + "unsafe" +) + +// Make sure Winsock2 is initialised +func init() { + e := syscall.WSAStartup(uint32(0x202), &wsaData) + if e != nil { + log.Fatal("WSAStartup", e) + } +} + +const ( + AF_HYPERV = 34 + SHV_PROTO_RAW = 1 + socket_error = uintptr(^uint32(0)) +) + +// struck sockaddr equivalent +type rawSockaddrHyperv struct { + Family uint16 + Reserved uint16 + VmId GUID + ServiceId GUID +} + +type hvsockListener struct { + accept_fd syscall.Handle + laddr HypervAddr +} + +// Internal representation. Complex mostly due to asynch send()/recv() syscalls. +type hvsockConn struct { + fd syscall.Handle + local HypervAddr + remote HypervAddr + + wg sync.WaitGroup + closing bool + readDeadline time.Time + writeDeadline time.Time +} + +// Used for async system calls +const ( + cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1 + cFILE_SKIP_SET_EVENT_ON_HANDLE = 2 +) + +var ( + errTimeout = &timeoutError{} + + wsaData syscall.WSAData +) + +type timeoutError struct{} + +func (e *timeoutError) Error() string { return "i/o timeout" } +func (e *timeoutError) Timeout() bool { return true } +func (e *timeoutError) Temporary() bool { return true } + +// Main constructor +func newHVsockConn(h syscall.Handle, local HypervAddr, remote HypervAddr) (*HVsockConn, error) { + ioInitOnce.Do(initIo) + v := &hvsockConn{fd: h, local: local, remote: remote} + + _, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff) + if err != nil { + return nil, err + } + err = setFileCompletionNotificationModes(h, + cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS|cFILE_SKIP_SET_EVENT_ON_HANDLE) + if err != nil { + return nil, err + } + + return &HVsockConn{hvsockConn: *v}, nil +} + +// Utility function to build a struct sockaddr for syscalls. +func (a HypervAddr) sockaddr(sa *rawSockaddrHyperv) (unsafe.Pointer, int32, error) { + sa.Family = AF_HYPERV + sa.Reserved = 0 + for i := 0; i < len(sa.VmId); i++ { + sa.VmId[i] = a.VmId[i] + } + for i := 0; i < len(sa.ServiceId); i++ { + sa.ServiceId[i] = a.ServiceId[i] + } + + return unsafe.Pointer(sa), int32(unsafe.Sizeof(*sa)), nil +} + +func connect(s syscall.Handle, a *HypervAddr) (err error) { + var sa rawSockaddrHyperv + ptr, n, err := a.sockaddr(&sa) + if err != nil { + return err + } + + return sys_connect(s, ptr, n) +} + +func bind(s syscall.Handle, a HypervAddr) error { + var sa rawSockaddrHyperv + ptr, n, err := a.sockaddr(&sa) + if err != nil { + return err + } + + return sys_bind(s, ptr, n) +} + +func accept(s syscall.Handle, a *HypervAddr) (syscall.Handle, error) { + return 0, errors.New("accept(): Unimplemented") +} + +// +// File IO/Socket interface +// +func (s *HVsockConn) close() error { + s.closeHandle() + + return nil +} + +// Underlying raw read() function. +func (v *HVsockConn) read(buf []byte) (int, error) { + var b syscall.WSABuf + var bytes uint32 + var f uint32 + + b.Len = uint32(len(buf)) + b.Buf = &buf[0] + + c, err := v.prepareIo() + if err != nil { + return 0, err + } + + err = syscall.WSARecv(v.fd, &b, 1, &bytes, &f, &c.o, nil) + n, err := v.asyncIo(c, v.readDeadline, bytes, err) + + // Handle EOF conditions. + if err == nil && n == 0 && len(buf) != 0 { + return 0, io.EOF + } + if err == syscall.ERROR_BROKEN_PIPE { + return 0, io.EOF + } + + return n, err +} + +// Underlying raw write() function. +func (v *HVsockConn) write(buf []byte) (int, error) { + var b syscall.WSABuf + var f uint32 + var bytes uint32 + + if len(buf) == 0 { + return 0, nil + } + + f = 0 + b.Len = uint32(len(buf)) + b.Buf = &buf[0] + + c, err := v.prepareIo() + if err != nil { + return 0, err + } + err = syscall.WSASend(v.fd, &b, 1, &bytes, f, &c.o, nil) + return v.asyncIo(c, v.writeDeadline, bytes, err) +} + +func (v *HVsockConn) SetReadDeadline(t time.Time) error { + v.readDeadline = t + return nil +} + +func (v *HVsockConn) SetWriteDeadline(t time.Time) error { + v.writeDeadline = t + return nil +} + +func (v *HVsockConn) SetDeadline(t time.Time) error { + v.SetReadDeadline(t) + v.SetWriteDeadline(t) + return nil +} + +// The code below here is adjusted from: +// https://github.com/Microsoft/go-winio/blob/master/file.go + +var ioInitOnce sync.Once +var ioCompletionPort syscall.Handle + +// ioResult contains the result of an asynchronous IO operation +type ioResult struct { + bytes uint32 + err error +} + +type ioOperation struct { + o syscall.Overlapped + ch chan ioResult +} + +func initIo() { + h, err := createIoCompletionPort(syscall.InvalidHandle, 0, 0, 0xffffffff) + if err != nil { + panic(err) + } + ioCompletionPort = h + go ioCompletionProcessor(h) +} + +func (v *hvsockConn) closeHandle() { + if !v.closing { + // cancel all IO and wait for it to complete + v.closing = true + cancelIoEx(v.fd, nil) + v.wg.Wait() + // at this point, no new IO can start + syscall.Close(v.fd) + v.fd = 0 + } +} + +// prepareIo prepares for a new IO operation +func (s *hvsockConn) prepareIo() (*ioOperation, error) { + s.wg.Add(1) + if s.closing { + return nil, errSocketClosed + } + c := &ioOperation{} + c.ch = make(chan ioResult) + return c, nil +} + +// ioCompletionProcessor processes completed async IOs forever +func ioCompletionProcessor(h syscall.Handle) { + // Set the timer resolution to 1. This fixes a performance regression in golang 1.6. + timeBeginPeriod(1) + for { + var bytes uint32 + var key uintptr + var op *ioOperation + err := getQueuedCompletionStatus(h, &bytes, &key, &op, syscall.INFINITE) + if op == nil { + panic(err) + } + op.ch <- ioResult{bytes, err} + } +} + +// asyncIo processes the return value from ReadFile or WriteFile, blocking until +// the operation has actually completed. +func (v *hvsockConn) asyncIo(c *ioOperation, deadline time.Time, bytes uint32, err error) (int, error) { + if err != syscall.ERROR_IO_PENDING { + v.wg.Done() + return int(bytes), err + } + + var r ioResult + wait := true + timedout := false + if v.closing { + cancelIoEx(v.fd, &c.o) + } else if !deadline.IsZero() { + now := time.Now() + if !deadline.After(now) { + timedout = true + } else { + timeout := time.After(deadline.Sub(now)) + select { + case r = <-c.ch: + wait = false + case <-timeout: + timedout = true + } + } + } + if timedout { + cancelIoEx(v.fd, &c.o) + } + if wait { + r = <-c.ch + } + err = r.err + if err == syscall.ERROR_OPERATION_ABORTED { + if v.closing { + err = errSocketClosed + } else if timedout { + err = errTimeout + } + } + v.wg.Done() + return int(r.bytes), err +} diff --git a/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/zsyscall_windows.go b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/zsyscall_windows.go new file mode 100644 index 000000000..32fb2f253 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/hvsock/zsyscall_windows.go @@ -0,0 +1,100 @@ +package hvsock + +import ( + "syscall" + "unsafe" +) + +var ( + modws2_32 = syscall.NewLazyDLL("ws2_32.dll") + modwinmm = syscall.NewLazyDLL("winmm.dll") + modkernel32 = syscall.NewLazyDLL("kernel32.dll") + + procConnect = modws2_32.NewProc("connect") + procbind = modws2_32.NewProc("bind") + procCancelIoEx = modkernel32.NewProc("CancelIoEx") + procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") + procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") + procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes") + proctimeBeginPeriod = modwinmm.NewProc("timeBeginPeriod") +) + +func sys_connect(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) { + r1, _, e1 := syscall.Syscall(procConnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) + if r1 == socket_error { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + + return +} + +func sys_bind(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) { + r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) + if r1 == socket_error { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) { + r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0) + newport = syscall.Handle(r0) + if newport == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) { + r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func timeBeginPeriod(period uint32) (n int32) { + r0, _, _ := syscall.Syscall(proctimeBeginPeriod.Addr(), 1, uintptr(period), 0, 0) + n = int32(r0) + return +} diff --git a/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/vsock/vsock_linux.go b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/vsock/vsock_linux.go new file mode 100644 index 000000000..f8c38e00a --- /dev/null +++ b/alpine/packages/go/vendor/github.com/rneugeba/virtsock/go/vsock/vsock_linux.go @@ -0,0 +1,171 @@ +package vsock + +import ( + "errors" + "fmt" + "net" + "os" + "syscall" + "time" +) + +/* No way to teach net or syscall about vsock sockaddr, so go right to C */ + +/* +#include + +struct sockaddr_vm { + sa_family_t svm_family; + unsigned short svm_reserved1; + unsigned int svm_port; + unsigned int svm_cid; + unsigned char svm_zero[sizeof(struct sockaddr) - + sizeof(sa_family_t) - sizeof(unsigned short) - + sizeof(unsigned int) - sizeof(unsigned int)]; +}; + +int bind_sockaddr_vm(int fd, const struct sockaddr_vm *sa_vm) { + return bind(fd, (const struct sockaddr*)sa_vm, sizeof(*sa_vm)); +} +int connect_sockaddr_vm(int fd, const struct sockaddr_vm *sa_vm) { + return connect(fd, (const struct sockaddr*)sa_vm, sizeof(*sa_vm)); +} +int accept_vm(int fd, struct sockaddr_vm *sa_vm, socklen_t *sa_vm_len) { + return accept4(fd, (struct sockaddr *)sa_vm, sa_vm_len, 0); +} +*/ +import "C" + +const ( + AF_VSOCK = 40 + VSOCK_CID_ANY = 4294967295 /* 2^32-1 */ + VSOCK_CID_SELF = 3 +) + +// Listen returns a net.Listener which can accept connections on the given +// vhan port. +func Listen(port uint) (net.Listener, error) { + accept_fd, err := syscall.Socket(AF_VSOCK, syscall.SOCK_STREAM, 0) + if err != nil { + return nil, err + } + + sa := C.struct_sockaddr_vm{} + sa.svm_family = AF_VSOCK + sa.svm_port = C.uint(port) + sa.svm_cid = VSOCK_CID_ANY + + if ret := C.bind_sockaddr_vm(C.int(accept_fd), &sa); ret != 0 { + return nil, errors.New(fmt.Sprintf("failed bind vsock connection to %08x.%08x, returned %d", sa.svm_cid, sa.svm_port, ret)) + } + + err = syscall.Listen(accept_fd, syscall.SOMAXCONN) + if err != nil { + return nil, err + } + return &vsockListener{accept_fd, port}, nil +} + +// Conn is a vsock connection which support half-close. +type Conn interface { + net.Conn + CloseRead() error + CloseWrite() error +} + +type vsockListener struct { + accept_fd int + port uint +} + +func (v *vsockListener) Accept() (net.Conn, error) { + var accept_sa C.struct_sockaddr_vm + var accept_sa_len C.socklen_t + + accept_sa_len = C.sizeof_struct_sockaddr_vm + fd, err := C.accept_vm(C.int(v.accept_fd), &accept_sa, &accept_sa_len) + if err != nil { + return nil, err + } + return newVsockConn(uintptr(fd), v.port) +} + +func (v *vsockListener) Close() error { + // Note this won't cause the Accept to unblock. + return syscall.Close(v.accept_fd) +} + +type VsockAddr struct { + Port uint +} + +func (a VsockAddr) Network() string { + return "vsock" +} + +func (a VsockAddr) String() string { + return fmt.Sprintf("%08x", a.Port) +} + +func (v *vsockListener) Addr() net.Addr { + return VsockAddr{Port: v.port} +} + +// a wrapper around FileConn which supports CloseRead and CloseWrite +type vsockConn struct { + vsock *os.File + fd uintptr + local VsockAddr + remote VsockAddr +} + +type VsockConn struct { + vsockConn +} + +func newVsockConn(fd uintptr, localPort uint) (*VsockConn, error) { + vsock := os.NewFile(fd, fmt.Sprintf("vsock:%d", fd)) + local := VsockAddr{Port: localPort} + remote := VsockAddr{Port: uint(0)} // FIXME + return &VsockConn{vsockConn{vsock: vsock, fd: fd, local: local, remote: remote}}, nil +} + +func (v *VsockConn) LocalAddr() net.Addr { + return v.local +} + +func (v *VsockConn) RemoteAddr() net.Addr { + return v.remote +} + +func (v *VsockConn) CloseRead() error { + return syscall.Shutdown(int(v.fd), syscall.SHUT_RD) +} + +func (v *VsockConn) CloseWrite() error { + return syscall.Shutdown(int(v.fd), syscall.SHUT_WR) +} + +func (v *VsockConn) Close() error { + return v.vsock.Close() +} + +func (v *VsockConn) Read(buf []byte) (int, error) { + return v.vsock.Read(buf) +} + +func (v *VsockConn) Write(buf []byte) (int, error) { + return v.vsock.Write(buf) +} + +func (v *VsockConn) SetDeadline(t time.Time) error { + return nil // FIXME +} + +func (v *VsockConn) SetReadDeadline(t time.Time) error { + return nil // FIXME +} + +func (v *VsockConn) SetWriteDeadline(t time.Time) error { + return nil // FIXME +} diff --git a/alpine/packages/go/vendor/manifest b/alpine/packages/go/vendor/manifest new file mode 100644 index 000000000..2c83cb3d2 --- /dev/null +++ b/alpine/packages/go/vendor/manifest @@ -0,0 +1,14 @@ +{ + "version": 0, + "dependencies": [ + { + "importpath": "github.com/rneugeba/virtsock/go", + "repository": "https://github.com/rneugeba/virtsock", + "vcs": "git", + "revision": "359bc27daab86588bfc7a304e78c6758b098d8e5", + "branch": "master", + "path": "/go", + "notests": true + } + ] +} \ No newline at end of file From cdfc424823b688707b0d26722e2e8ff8415af8a9 Mon Sep 17 00:00:00 2001 From: Rolf Neugebauer Date: Thu, 19 May 2016 11:42:48 +0100 Subject: [PATCH 2/5] go: add the logrus package used by the proxy Signed-off-by: Rolf Neugebauer --- .../github.com/Sirupsen/logrus/.gitignore | 1 + .../github.com/Sirupsen/logrus/.travis.yml | 8 + .../github.com/Sirupsen/logrus/CHANGELOG.md | 47 +++ .../vendor/github.com/Sirupsen/logrus/LICENSE | 21 ++ .../github.com/Sirupsen/logrus/README.md | 357 ++++++++++++++++++ .../vendor/github.com/Sirupsen/logrus/doc.go | 26 ++ .../github.com/Sirupsen/logrus/entry.go | 264 +++++++++++++ .../Sirupsen/logrus/examples/basic/basic.go | 50 +++ .../Sirupsen/logrus/examples/hook/hook.go | 30 ++ .../github.com/Sirupsen/logrus/exported.go | 193 ++++++++++ .../github.com/Sirupsen/logrus/formatter.go | 48 +++ .../logrus/formatters/logstash/logstash.go | 56 +++ .../github.com/Sirupsen/logrus/hooks.go | 34 ++ .../logrus/hooks/airbrake/airbrake.go | 54 +++ .../Sirupsen/logrus/hooks/bugsnag/bugsnag.go | 68 ++++ .../logrus/hooks/papertrail/README.md | 28 ++ .../logrus/hooks/papertrail/papertrail.go | 55 +++ .../Sirupsen/logrus/hooks/sentry/README.md | 111 ++++++ .../Sirupsen/logrus/hooks/sentry/sentry.go | 137 +++++++ .../Sirupsen/logrus/hooks/syslog/README.md | 20 + .../Sirupsen/logrus/hooks/syslog/syslog.go | 59 +++ .../Sirupsen/logrus/json_formatter.go | 41 ++ .../github.com/Sirupsen/logrus/logger.go | 206 ++++++++++ .../github.com/Sirupsen/logrus/logrus.go | 98 +++++ .../Sirupsen/logrus/terminal_bsd.go | 9 + .../Sirupsen/logrus/terminal_linux.go | 12 + .../Sirupsen/logrus/terminal_notwindows.go | 21 ++ .../Sirupsen/logrus/terminal_windows.go | 27 ++ .../Sirupsen/logrus/text_formatter.go | 159 ++++++++ .../github.com/Sirupsen/logrus/writer.go | 31 ++ 30 files changed, 2271 insertions(+) create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/.gitignore create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/.travis.yml create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/CHANGELOG.md create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/LICENSE create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/README.md create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/doc.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/entry.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/examples/basic/basic.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/examples/hook/hook.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/exported.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/formatter.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/formatters/logstash/logstash.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/papertrail/README.md create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/sentry/README.md create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/json_formatter.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/logger.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/logrus.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_bsd.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_linux.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_windows.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/text_formatter.go create mode 100644 alpine/packages/go/vendor/github.com/Sirupsen/logrus/writer.go diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/.gitignore b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/.gitignore new file mode 100644 index 000000000..66be63a00 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/.gitignore @@ -0,0 +1 @@ +logrus diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/.travis.yml b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/.travis.yml new file mode 100644 index 000000000..2d8c08661 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/.travis.yml @@ -0,0 +1,8 @@ +language: go +go: + - 1.2 + - 1.3 + - 1.4 + - tip +install: + - go get -t ./... diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/CHANGELOG.md b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/CHANGELOG.md new file mode 100644 index 000000000..78f98959b --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/CHANGELOG.md @@ -0,0 +1,47 @@ +# 0.8.7 + +* logrus/core: fix possible race (#216) +* logrus/doc: small typo fixes and doc improvements + + +# 0.8.6 + +* hooks/raven: allow passing an initialized client + +# 0.8.5 + +* logrus/core: revert #208 + +# 0.8.4 + +* formatter/text: fix data race (#218) + +# 0.8.3 + +* logrus/core: fix entry log level (#208) +* logrus/core: improve performance of text formatter by 40% +* logrus/core: expose `LevelHooks` type +* logrus/core: add support for DragonflyBSD and NetBSD +* formatter/text: print structs more verbosely + +# 0.8.2 + +* logrus: fix more Fatal family functions + +# 0.8.1 + +* logrus: fix not exiting on `Fatalf` and `Fatalln` + +# 0.8.0 + +* logrus: defaults to stderr instead of stdout +* hooks/sentry: add special field for `*http.Request` +* formatter/text: ignore Windows for colors + +# 0.7.3 + +* formatter/\*: allow configuration of timestamp layout + +# 0.7.2 + +* formatter/text: Add configuration option for time format (#158) diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/LICENSE b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/LICENSE new file mode 100644 index 000000000..f090cb42f --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Simon Eskildsen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/README.md b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/README.md new file mode 100644 index 000000000..6fa6e2062 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/README.md @@ -0,0 +1,357 @@ +# Logrus :walrus: [![Build Status](https://travis-ci.org/Sirupsen/logrus.svg?branch=master)](https://travis-ci.org/Sirupsen/logrus) [![godoc reference](https://godoc.org/github.com/Sirupsen/logrus?status.png)][godoc] + +Logrus is a structured logger for Go (golang), completely API compatible with +the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not +yet stable (pre 1.0). Logrus itself is completely stable and has been used in +many large deployments. The core API is unlikely to change much but please +version control your Logrus to make sure you aren't fetching latest `master` on +every build.** + +Nicely color-coded in development (when a TTY is attached, otherwise just +plain text): + +![Colored](http://i.imgur.com/PY7qMwd.png) + +With `log.Formatter = new(logrus.JSONFormatter)`, for easy parsing by logstash +or Splunk: + +```json +{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the +ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} + +{"level":"warning","msg":"The group's number increased tremendously!", +"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"} + +{"animal":"walrus","level":"info","msg":"A giant walrus appears!", +"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"} + +{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.", +"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"} + +{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true, +"time":"2014-03-10 19:57:38.562543128 -0400 EDT"} +``` + +With the default `log.Formatter = new(&log.TextFormatter{})` when a TTY is not +attached, the output is compatible with the +[logfmt](http://godoc.org/github.com/kr/logfmt) format: + +```text +time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8 +time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10 +time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true +time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4 +time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009 +time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true +exit status 1 +``` + +#### Example + +The simplest way to use Logrus is simply the package-level exported logger: + +```go +package main + +import ( + log "github.com/Sirupsen/logrus" +) + +func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + }).Info("A walrus appears") +} +``` + +Note that it's completely api-compatible with the stdlib logger, so you can +replace your `log` imports everywhere with `log "github.com/Sirupsen/logrus"` +and you'll now have the flexibility of Logrus. You can customize it all you +want: + +```go +package main + +import ( + "os" + log "github.com/Sirupsen/logrus" + "github.com/Sirupsen/logrus/hooks/airbrake" +) + +func init() { + // Log as JSON instead of the default ASCII formatter. + log.SetFormatter(&log.JSONFormatter{}) + + // Use the Airbrake hook to report errors that have Error severity or above to + // an exception tracker. You can create custom hooks, see the Hooks section. + log.AddHook(airbrake.NewHook("https://example.com", "xyz", "development")) + + // Output to stderr instead of stdout, could also be a file. + log.SetOutput(os.Stderr) + + // Only log the warning severity or above. + log.SetLevel(log.WarnLevel) +} + +func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + "size": 10, + }).Info("A group of walrus emerges from the ocean") + + log.WithFields(log.Fields{ + "omg": true, + "number": 122, + }).Warn("The group's number increased tremendously!") + + log.WithFields(log.Fields{ + "omg": true, + "number": 100, + }).Fatal("The ice breaks!") + + // A common pattern is to re-use fields between logging statements by re-using + // the logrus.Entry returned from WithFields() + contextLogger := log.WithFields(log.Fields{ + "common": "this is a common field", + "other": "I also should be logged always", + }) + + contextLogger.Info("I'll be logged with common and other field") + contextLogger.Info("Me too") +} +``` + +For more advanced usage such as logging to multiple locations from the same +application, you can also create an instance of the `logrus` Logger: + +```go +package main + +import ( + "github.com/Sirupsen/logrus" +) + +// Create a new instance of the logger. You can have any number of instances. +var log = logrus.New() + +func main() { + // The API for setting attributes is a little different than the package level + // exported logger. See Godoc. + log.Out = os.Stderr + + log.WithFields(logrus.Fields{ + "animal": "walrus", + "size": 10, + }).Info("A group of walrus emerges from the ocean") +} +``` + +#### Fields + +Logrus encourages careful, structured logging though logging fields instead of +long, unparseable error messages. For example, instead of: `log.Fatalf("Failed +to send event %s to topic %s with key %d")`, you should log the much more +discoverable: + +```go +log.WithFields(log.Fields{ + "event": event, + "topic": topic, + "key": key, +}).Fatal("Failed to send event") +``` + +We've found this API forces you to think about logging in a way that produces +much more useful logging messages. We've been in countless situations where just +a single added field to a log statement that was already there would've saved us +hours. The `WithFields` call is optional. + +In general, with Logrus using any of the `printf`-family functions should be +seen as a hint you should add a field, however, you can still use the +`printf`-family functions with Logrus. + +#### Hooks + +You can add hooks for logging levels. For example to send errors to an exception +tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to +multiple places simultaneously, e.g. syslog. + +Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in +`init`: + +```go +import ( + log "github.com/Sirupsen/logrus" + "github.com/Sirupsen/logrus/hooks/airbrake" + logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog" + "log/syslog" +) + +func init() { + log.AddHook(airbrake.NewHook("https://example.com", "xyz", "development")) + + hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") + if err != nil { + log.Error("Unable to connect to local syslog daemon") + } else { + log.AddHook(hook) + } +} +``` + + +| Hook | Description | +| ----- | ----------- | +| [Airbrake](https://github.com/Sirupsen/logrus/blob/master/hooks/airbrake/airbrake.go) | Send errors to an exception tracking service compatible with the Airbrake API. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. | +| [Papertrail](https://github.com/Sirupsen/logrus/blob/master/hooks/papertrail/papertrail.go) | Send errors to the Papertrail hosted logging service via UDP. | +| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. | +| [BugSnag](https://github.com/Sirupsen/logrus/blob/master/hooks/bugsnag/bugsnag.go) | Send errors to the Bugsnag exception tracking service. | +| [Sentry](https://github.com/Sirupsen/logrus/blob/master/hooks/sentry/sentry.go) | Send errors to the Sentry error logging and aggregation service. | +| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. | +| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) | +| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. | +| [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` | +| [Graylog](https://github.com/gemnasium/logrus-hooks/tree/master/graylog) | Hook for logging to [Graylog](http://graylog2.org/) | +| [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) | +| [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem | +| [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger | +| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail | +| [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar | +| [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd | +| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb | + +#### Level logging + +Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic. + +```go +log.Debug("Useful debugging information.") +log.Info("Something noteworthy happened!") +log.Warn("You should probably take a look at this.") +log.Error("Something failed but I'm not quitting.") +// Calls os.Exit(1) after logging +log.Fatal("Bye.") +// Calls panic() after logging +log.Panic("I'm bailing.") +``` + +You can set the logging level on a `Logger`, then it will only log entries with +that severity or anything above it: + +```go +// Will log anything that is info or above (warn, error, fatal, panic). Default. +log.SetLevel(log.InfoLevel) +``` + +It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose +environment if your application has that. + +#### Entries + +Besides the fields added with `WithField` or `WithFields` some fields are +automatically added to all logging events: + +1. `time`. The timestamp when the entry was created. +2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after + the `AddFields` call. E.g. `Failed to send event.` +3. `level`. The logging level. E.g. `info`. + +#### Environments + +Logrus has no notion of environment. + +If you wish for hooks and formatters to only be used in specific environments, +you should handle that yourself. For example, if your application has a global +variable `Environment`, which is a string representation of the environment you +could do: + +```go +import ( + log "github.com/Sirupsen/logrus" +) + +init() { + // do something here to set environment depending on an environment variable + // or command-line flag + if Environment == "production" { + log.SetFormatter(&log.JSONFormatter{}) + } else { + // The TextFormatter is default, you don't actually have to do this. + log.SetFormatter(&log.TextFormatter{}) + } +} +``` + +This configuration is how `logrus` was intended to be used, but JSON in +production is mostly only useful if you do log aggregation with tools like +Splunk or Logstash. + +#### Formatters + +The built-in logging formatters are: + +* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise + without colors. + * *Note:* to force colored output when there is no TTY, set the `ForceColors` + field to `true`. To force no colored output even if there is a TTY set the + `DisableColors` field to `true` +* `logrus.JSONFormatter`. Logs fields as JSON. +* `logrus_logstash.LogstashFormatter`. Logs fields as Logstash Events (http://logstash.net). + + ```go + logrus.SetFormatter(&logrus_logstash.LogstashFormatter{Type: “application_name"}) + ``` + +Third party logging formatters: + +* [`zalgo`](https://github.com/aybabtme/logzalgo): invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦. + +You can define your formatter by implementing the `Formatter` interface, +requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a +`Fields` type (`map[string]interface{}`) with all your fields as well as the +default ones (see Entries section above): + +```go +type MyJSONFormatter struct { +} + +log.SetFormatter(new(MyJSONFormatter)) + +func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) { + // Note this doesn't include Time, Level and Message which are available on + // the Entry. Consult `godoc` on information about those fields or read the + // source of the official loggers. + serialized, err := json.Marshal(entry.Data) + if err != nil { + return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) + } + return append(serialized, '\n'), nil +} +``` + +#### Logger as an `io.Writer` + +Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it. + +```go +w := logger.Writer() +defer w.Close() + +srv := http.Server{ + // create a stdlib log.Logger that writes to + // logrus.Logger. + ErrorLog: log.New(w, "", 0), +} +``` + +Each line written to that writer will be printed the usual way, using formatters +and hooks. The level for those entries is `info`. + +#### Rotation + +Log rotation is not provided with Logrus. Log rotation should be done by an +external program (like `logrotate(8)`) that can compress and delete old log +entries. It should not be a feature of the application-level logger. + + +[godoc]: https://godoc.org/github.com/Sirupsen/logrus diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/doc.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/doc.go new file mode 100644 index 000000000..dddd5f877 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/doc.go @@ -0,0 +1,26 @@ +/* +Package logrus is a structured logger for Go, completely API compatible with the standard library logger. + + +The simplest way to use Logrus is simply the package-level exported logger: + + package main + + import ( + log "github.com/Sirupsen/logrus" + ) + + func main() { + log.WithFields(log.Fields{ + "animal": "walrus", + "number": 1, + "size": 10, + }).Info("A walrus appears") + } + +Output: + time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 + +For a full guide visit https://github.com/Sirupsen/logrus +*/ +package logrus diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/entry.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/entry.go new file mode 100644 index 000000000..9ae900bc5 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/entry.go @@ -0,0 +1,264 @@ +package logrus + +import ( + "bytes" + "fmt" + "io" + "os" + "time" +) + +// Defines the key when adding errors using WithError. +var ErrorKey = "error" + +// An entry is the final or intermediate Logrus logging entry. It contains all +// the fields passed with WithField{,s}. It's finally logged when Debug, Info, +// Warn, Error, Fatal or Panic is called on it. These objects can be reused and +// passed around as much as you wish to avoid field duplication. +type Entry struct { + Logger *Logger + + // Contains all the fields set by the user. + Data Fields + + // Time at which the log entry was created + Time time.Time + + // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic + Level Level + + // Message passed to Debug, Info, Warn, Error, Fatal or Panic + Message string +} + +func NewEntry(logger *Logger) *Entry { + return &Entry{ + Logger: logger, + // Default is three fields, give a little extra room + Data: make(Fields, 5), + } +} + +// Returns a reader for the entry, which is a proxy to the formatter. +func (entry *Entry) Reader() (*bytes.Buffer, error) { + serialized, err := entry.Logger.Formatter.Format(entry) + return bytes.NewBuffer(serialized), err +} + +// Returns the string representation from the reader and ultimately the +// formatter. +func (entry *Entry) String() (string, error) { + reader, err := entry.Reader() + if err != nil { + return "", err + } + + return reader.String(), err +} + +// Add an error as single field (using the key defined in ErrorKey) to the Entry. +func (entry *Entry) WithError(err error) *Entry { + return entry.WithField(ErrorKey, err) +} + +// Add a single field to the Entry. +func (entry *Entry) WithField(key string, value interface{}) *Entry { + return entry.WithFields(Fields{key: value}) +} + +// Add a map of fields to the Entry. +func (entry *Entry) WithFields(fields Fields) *Entry { + data := Fields{} + for k, v := range entry.Data { + data[k] = v + } + for k, v := range fields { + data[k] = v + } + return &Entry{Logger: entry.Logger, Data: data} +} + +// This function is not declared with a pointer value because otherwise +// race conditions will occur when using multiple goroutines +func (entry Entry) log(level Level, msg string) { + entry.Time = time.Now() + entry.Level = level + entry.Message = msg + + if err := entry.Logger.Hooks.Fire(level, &entry); err != nil { + entry.Logger.mu.Lock() + fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) + entry.Logger.mu.Unlock() + } + + reader, err := entry.Reader() + if err != nil { + entry.Logger.mu.Lock() + fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) + entry.Logger.mu.Unlock() + } + + entry.Logger.mu.Lock() + defer entry.Logger.mu.Unlock() + + _, err = io.Copy(entry.Logger.Out, reader) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) + } + + // To avoid Entry#log() returning a value that only would make sense for + // panic() to use in Entry#Panic(), we avoid the allocation by checking + // directly here. + if level <= PanicLevel { + panic(&entry) + } +} + +func (entry *Entry) Debug(args ...interface{}) { + if entry.Logger.Level >= DebugLevel { + entry.log(DebugLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Print(args ...interface{}) { + entry.Info(args...) +} + +func (entry *Entry) Info(args ...interface{}) { + if entry.Logger.Level >= InfoLevel { + entry.log(InfoLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Warn(args ...interface{}) { + if entry.Logger.Level >= WarnLevel { + entry.log(WarnLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Warning(args ...interface{}) { + entry.Warn(args...) +} + +func (entry *Entry) Error(args ...interface{}) { + if entry.Logger.Level >= ErrorLevel { + entry.log(ErrorLevel, fmt.Sprint(args...)) + } +} + +func (entry *Entry) Fatal(args ...interface{}) { + if entry.Logger.Level >= FatalLevel { + entry.log(FatalLevel, fmt.Sprint(args...)) + } + os.Exit(1) +} + +func (entry *Entry) Panic(args ...interface{}) { + if entry.Logger.Level >= PanicLevel { + entry.log(PanicLevel, fmt.Sprint(args...)) + } + panic(fmt.Sprint(args...)) +} + +// Entry Printf family functions + +func (entry *Entry) Debugf(format string, args ...interface{}) { + if entry.Logger.Level >= DebugLevel { + entry.Debug(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Infof(format string, args ...interface{}) { + if entry.Logger.Level >= InfoLevel { + entry.Info(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Printf(format string, args ...interface{}) { + entry.Infof(format, args...) +} + +func (entry *Entry) Warnf(format string, args ...interface{}) { + if entry.Logger.Level >= WarnLevel { + entry.Warn(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Warningf(format string, args ...interface{}) { + entry.Warnf(format, args...) +} + +func (entry *Entry) Errorf(format string, args ...interface{}) { + if entry.Logger.Level >= ErrorLevel { + entry.Error(fmt.Sprintf(format, args...)) + } +} + +func (entry *Entry) Fatalf(format string, args ...interface{}) { + if entry.Logger.Level >= FatalLevel { + entry.Fatal(fmt.Sprintf(format, args...)) + } + os.Exit(1) +} + +func (entry *Entry) Panicf(format string, args ...interface{}) { + if entry.Logger.Level >= PanicLevel { + entry.Panic(fmt.Sprintf(format, args...)) + } +} + +// Entry Println family functions + +func (entry *Entry) Debugln(args ...interface{}) { + if entry.Logger.Level >= DebugLevel { + entry.Debug(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Infoln(args ...interface{}) { + if entry.Logger.Level >= InfoLevel { + entry.Info(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Println(args ...interface{}) { + entry.Infoln(args...) +} + +func (entry *Entry) Warnln(args ...interface{}) { + if entry.Logger.Level >= WarnLevel { + entry.Warn(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Warningln(args ...interface{}) { + entry.Warnln(args...) +} + +func (entry *Entry) Errorln(args ...interface{}) { + if entry.Logger.Level >= ErrorLevel { + entry.Error(entry.sprintlnn(args...)) + } +} + +func (entry *Entry) Fatalln(args ...interface{}) { + if entry.Logger.Level >= FatalLevel { + entry.Fatal(entry.sprintlnn(args...)) + } + os.Exit(1) +} + +func (entry *Entry) Panicln(args ...interface{}) { + if entry.Logger.Level >= PanicLevel { + entry.Panic(entry.sprintlnn(args...)) + } +} + +// Sprintlnn => Sprint no newline. This is to get the behavior of how +// fmt.Sprintln where spaces are always added between operands, regardless of +// their type. Instead of vendoring the Sprintln implementation to spare a +// string allocation, we do the simplest thing. +func (entry *Entry) sprintlnn(args ...interface{}) string { + msg := fmt.Sprintln(args...) + return msg[:len(msg)-1] +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/examples/basic/basic.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/examples/basic/basic.go new file mode 100644 index 000000000..a1623ec00 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/examples/basic/basic.go @@ -0,0 +1,50 @@ +package main + +import ( + "github.com/Sirupsen/logrus" +) + +var log = logrus.New() + +func init() { + log.Formatter = new(logrus.JSONFormatter) + log.Formatter = new(logrus.TextFormatter) // default + log.Level = logrus.DebugLevel +} + +func main() { + defer func() { + err := recover() + if err != nil { + log.WithFields(logrus.Fields{ + "omg": true, + "err": err, + "number": 100, + }).Fatal("The ice breaks!") + } + }() + + log.WithFields(logrus.Fields{ + "animal": "walrus", + "number": 8, + }).Debug("Started observing beach") + + log.WithFields(logrus.Fields{ + "animal": "walrus", + "size": 10, + }).Info("A group of walrus emerges from the ocean") + + log.WithFields(logrus.Fields{ + "omg": true, + "number": 122, + }).Warn("The group's number increased tremendously!") + + log.WithFields(logrus.Fields{ + "temperature": -4, + }).Debug("Temperature changes") + + log.WithFields(logrus.Fields{ + "animal": "orca", + "size": 9009, + }).Panic("It's over 9000!") +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/examples/hook/hook.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/examples/hook/hook.go new file mode 100644 index 000000000..cb5759a35 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/examples/hook/hook.go @@ -0,0 +1,30 @@ +package main + +import ( + "github.com/Sirupsen/logrus" + "github.com/Sirupsen/logrus/hooks/airbrake" +) + +var log = logrus.New() + +func init() { + log.Formatter = new(logrus.TextFormatter) // default + log.Hooks.Add(airbrake.NewHook("https://example.com", "xyz", "development")) +} + +func main() { + log.WithFields(logrus.Fields{ + "animal": "walrus", + "size": 10, + }).Info("A group of walrus emerges from the ocean") + + log.WithFields(logrus.Fields{ + "omg": true, + "number": 122, + }).Warn("The group's number increased tremendously!") + + log.WithFields(logrus.Fields{ + "omg": true, + "number": 100, + }).Fatal("The ice breaks!") +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/exported.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/exported.go new file mode 100644 index 000000000..9a0120ac1 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/exported.go @@ -0,0 +1,193 @@ +package logrus + +import ( + "io" +) + +var ( + // std is the name of the standard logger in stdlib `log` + std = New() +) + +func StandardLogger() *Logger { + return std +} + +// SetOutput sets the standard logger output. +func SetOutput(out io.Writer) { + std.mu.Lock() + defer std.mu.Unlock() + std.Out = out +} + +// SetFormatter sets the standard logger formatter. +func SetFormatter(formatter Formatter) { + std.mu.Lock() + defer std.mu.Unlock() + std.Formatter = formatter +} + +// SetLevel sets the standard logger level. +func SetLevel(level Level) { + std.mu.Lock() + defer std.mu.Unlock() + std.Level = level +} + +// GetLevel returns the standard logger level. +func GetLevel() Level { + std.mu.Lock() + defer std.mu.Unlock() + return std.Level +} + +// AddHook adds a hook to the standard logger hooks. +func AddHook(hook Hook) { + std.mu.Lock() + defer std.mu.Unlock() + std.Hooks.Add(hook) +} + +// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key. +func WithError(err error) *Entry { + return std.WithField(ErrorKey, err) +} + +// WithField creates an entry from the standard logger and adds a field to +// it. If you want multiple fields, use `WithFields`. +// +// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal +// or Panic on the Entry it returns. +func WithField(key string, value interface{}) *Entry { + return std.WithField(key, value) +} + +// WithFields creates an entry from the standard logger and adds multiple +// fields to it. This is simply a helper for `WithField`, invoking it +// once for each field. +// +// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal +// or Panic on the Entry it returns. +func WithFields(fields Fields) *Entry { + return std.WithFields(fields) +} + +// Debug logs a message at level Debug on the standard logger. +func Debug(args ...interface{}) { + std.Debug(args...) +} + +// Print logs a message at level Info on the standard logger. +func Print(args ...interface{}) { + std.Print(args...) +} + +// Info logs a message at level Info on the standard logger. +func Info(args ...interface{}) { + std.Info(args...) +} + +// Warn logs a message at level Warn on the standard logger. +func Warn(args ...interface{}) { + std.Warn(args...) +} + +// Warning logs a message at level Warn on the standard logger. +func Warning(args ...interface{}) { + std.Warning(args...) +} + +// Error logs a message at level Error on the standard logger. +func Error(args ...interface{}) { + std.Error(args...) +} + +// Panic logs a message at level Panic on the standard logger. +func Panic(args ...interface{}) { + std.Panic(args...) +} + +// Fatal logs a message at level Fatal on the standard logger. +func Fatal(args ...interface{}) { + std.Fatal(args...) +} + +// Debugf logs a message at level Debug on the standard logger. +func Debugf(format string, args ...interface{}) { + std.Debugf(format, args...) +} + +// Printf logs a message at level Info on the standard logger. +func Printf(format string, args ...interface{}) { + std.Printf(format, args...) +} + +// Infof logs a message at level Info on the standard logger. +func Infof(format string, args ...interface{}) { + std.Infof(format, args...) +} + +// Warnf logs a message at level Warn on the standard logger. +func Warnf(format string, args ...interface{}) { + std.Warnf(format, args...) +} + +// Warningf logs a message at level Warn on the standard logger. +func Warningf(format string, args ...interface{}) { + std.Warningf(format, args...) +} + +// Errorf logs a message at level Error on the standard logger. +func Errorf(format string, args ...interface{}) { + std.Errorf(format, args...) +} + +// Panicf logs a message at level Panic on the standard logger. +func Panicf(format string, args ...interface{}) { + std.Panicf(format, args...) +} + +// Fatalf logs a message at level Fatal on the standard logger. +func Fatalf(format string, args ...interface{}) { + std.Fatalf(format, args...) +} + +// Debugln logs a message at level Debug on the standard logger. +func Debugln(args ...interface{}) { + std.Debugln(args...) +} + +// Println logs a message at level Info on the standard logger. +func Println(args ...interface{}) { + std.Println(args...) +} + +// Infoln logs a message at level Info on the standard logger. +func Infoln(args ...interface{}) { + std.Infoln(args...) +} + +// Warnln logs a message at level Warn on the standard logger. +func Warnln(args ...interface{}) { + std.Warnln(args...) +} + +// Warningln logs a message at level Warn on the standard logger. +func Warningln(args ...interface{}) { + std.Warningln(args...) +} + +// Errorln logs a message at level Error on the standard logger. +func Errorln(args ...interface{}) { + std.Errorln(args...) +} + +// Panicln logs a message at level Panic on the standard logger. +func Panicln(args ...interface{}) { + std.Panicln(args...) +} + +// Fatalln logs a message at level Fatal on the standard logger. +func Fatalln(args ...interface{}) { + std.Fatalln(args...) +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/formatter.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/formatter.go new file mode 100644 index 000000000..104d689f1 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/formatter.go @@ -0,0 +1,48 @@ +package logrus + +import "time" + +const DefaultTimestampFormat = time.RFC3339 + +// The Formatter interface is used to implement a custom Formatter. It takes an +// `Entry`. It exposes all the fields, including the default ones: +// +// * `entry.Data["msg"]`. The message passed from Info, Warn, Error .. +// * `entry.Data["time"]`. The timestamp. +// * `entry.Data["level"]. The level the entry was logged at. +// +// Any additional fields added with `WithField` or `WithFields` are also in +// `entry.Data`. Format is expected to return an array of bytes which are then +// logged to `logger.Out`. +type Formatter interface { + Format(*Entry) ([]byte, error) +} + +// This is to not silently overwrite `time`, `msg` and `level` fields when +// dumping it. If this code wasn't there doing: +// +// logrus.WithField("level", 1).Info("hello") +// +// Would just silently drop the user provided level. Instead with this code +// it'll logged as: +// +// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."} +// +// It's not exported because it's still using Data in an opinionated way. It's to +// avoid code duplication between the two default formatters. +func prefixFieldClashes(data Fields) { + _, ok := data["time"] + if ok { + data["fields.time"] = data["time"] + } + + _, ok = data["msg"] + if ok { + data["fields.msg"] = data["msg"] + } + + _, ok = data["level"] + if ok { + data["fields.level"] = data["level"] + } +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/formatters/logstash/logstash.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/formatters/logstash/logstash.go new file mode 100644 index 000000000..8ea93ddf2 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/formatters/logstash/logstash.go @@ -0,0 +1,56 @@ +package logstash + +import ( + "encoding/json" + "fmt" + + "github.com/Sirupsen/logrus" +) + +// Formatter generates json in logstash format. +// Logstash site: http://logstash.net/ +type LogstashFormatter struct { + Type string // if not empty use for logstash type field. + + // TimestampFormat sets the format used for timestamps. + TimestampFormat string +} + +func (f *LogstashFormatter) Format(entry *logrus.Entry) ([]byte, error) { + entry.Data["@version"] = 1 + + if f.TimestampFormat == "" { + f.TimestampFormat = logrus.DefaultTimestampFormat + } + + entry.Data["@timestamp"] = entry.Time.Format(f.TimestampFormat) + + // set message field + v, ok := entry.Data["message"] + if ok { + entry.Data["fields.message"] = v + } + entry.Data["message"] = entry.Message + + // set level field + v, ok = entry.Data["level"] + if ok { + entry.Data["fields.level"] = v + } + entry.Data["level"] = entry.Level.String() + + // set type field + if f.Type != "" { + v, ok = entry.Data["type"] + if ok { + entry.Data["fields.type"] = v + } + entry.Data["type"] = f.Type + } + + serialized, err := json.Marshal(entry.Data) + if err != nil { + return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) + } + return append(serialized, '\n'), nil +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks.go new file mode 100644 index 000000000..3f151cdc3 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks.go @@ -0,0 +1,34 @@ +package logrus + +// A hook to be fired when logging on the logging levels returned from +// `Levels()` on your implementation of the interface. Note that this is not +// fired in a goroutine or a channel with workers, you should handle such +// functionality yourself if your call is non-blocking and you don't wish for +// the logging calls for levels returned from `Levels()` to block. +type Hook interface { + Levels() []Level + Fire(*Entry) error +} + +// Internal type for storing the hooks on a logger instance. +type LevelHooks map[Level][]Hook + +// Add a hook to an instance of logger. This is called with +// `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface. +func (hooks LevelHooks) Add(hook Hook) { + for _, level := range hook.Levels() { + hooks[level] = append(hooks[level], hook) + } +} + +// Fire all the hooks for the passed level. Used by `entry.log` to fire +// appropriate hooks for a log entry. +func (hooks LevelHooks) Fire(level Level, entry *Entry) error { + for _, hook := range hooks[level] { + if err := hook.Fire(entry); err != nil { + return err + } + } + + return nil +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go new file mode 100644 index 000000000..b0502c335 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go @@ -0,0 +1,54 @@ +package airbrake + +import ( + "errors" + "fmt" + + "github.com/Sirupsen/logrus" + "github.com/tobi/airbrake-go" +) + +// AirbrakeHook to send exceptions to an exception-tracking service compatible +// with the Airbrake API. +type airbrakeHook struct { + APIKey string + Endpoint string + Environment string +} + +func NewHook(endpoint, apiKey, env string) *airbrakeHook { + return &airbrakeHook{ + APIKey: apiKey, + Endpoint: endpoint, + Environment: env, + } +} + +func (hook *airbrakeHook) Fire(entry *logrus.Entry) error { + airbrake.ApiKey = hook.APIKey + airbrake.Endpoint = hook.Endpoint + airbrake.Environment = hook.Environment + + var notifyErr error + err, ok := entry.Data["error"].(error) + if ok { + notifyErr = err + } else { + notifyErr = errors.New(entry.Message) + } + + airErr := airbrake.Notify(notifyErr) + if airErr != nil { + return fmt.Errorf("Failed to send error to Airbrake: %s", airErr) + } + + return nil +} + +func (hook *airbrakeHook) Levels() []logrus.Level { + return []logrus.Level{ + logrus.ErrorLevel, + logrus.FatalLevel, + logrus.PanicLevel, + } +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go new file mode 100644 index 000000000..d20a0f54a --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go @@ -0,0 +1,68 @@ +package logrus_bugsnag + +import ( + "errors" + + "github.com/Sirupsen/logrus" + "github.com/bugsnag/bugsnag-go" +) + +type bugsnagHook struct{} + +// ErrBugsnagUnconfigured is returned if NewBugsnagHook is called before +// bugsnag.Configure. Bugsnag must be configured before the hook. +var ErrBugsnagUnconfigured = errors.New("bugsnag must be configured before installing this logrus hook") + +// ErrBugsnagSendFailed indicates that the hook failed to submit an error to +// bugsnag. The error was successfully generated, but `bugsnag.Notify()` +// failed. +type ErrBugsnagSendFailed struct { + err error +} + +func (e ErrBugsnagSendFailed) Error() string { + return "failed to send error to Bugsnag: " + e.err.Error() +} + +// NewBugsnagHook initializes a logrus hook which sends exceptions to an +// exception-tracking service compatible with the Bugsnag API. Before using +// this hook, you must call bugsnag.Configure(). The returned object should be +// registered with a log via `AddHook()` +// +// Entries that trigger an Error, Fatal or Panic should now include an "error" +// field to send to Bugsnag. +func NewBugsnagHook() (*bugsnagHook, error) { + if bugsnag.Config.APIKey == "" { + return nil, ErrBugsnagUnconfigured + } + return &bugsnagHook{}, nil +} + +// Fire forwards an error to Bugsnag. Given a logrus.Entry, it extracts the +// "error" field (or the Message if the error isn't present) and sends it off. +func (hook *bugsnagHook) Fire(entry *logrus.Entry) error { + var notifyErr error + err, ok := entry.Data["error"].(error) + if ok { + notifyErr = err + } else { + notifyErr = errors.New(entry.Message) + } + + bugsnagErr := bugsnag.Notify(notifyErr) + if bugsnagErr != nil { + return ErrBugsnagSendFailed{bugsnagErr} + } + + return nil +} + +// Levels enumerates the log levels on which the error should be forwarded to +// bugsnag: everything at or above the "Error" level. +func (hook *bugsnagHook) Levels() []logrus.Level { + return []logrus.Level{ + logrus.ErrorLevel, + logrus.FatalLevel, + logrus.PanicLevel, + } +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/papertrail/README.md b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/papertrail/README.md new file mode 100644 index 000000000..ae61e9229 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/papertrail/README.md @@ -0,0 +1,28 @@ +# Papertrail Hook for Logrus :walrus: + +[Papertrail](https://papertrailapp.com) provides hosted log management. Once stored in Papertrail, you can [group](http://help.papertrailapp.com/kb/how-it-works/groups/) your logs on various dimensions, [search](http://help.papertrailapp.com/kb/how-it-works/search-syntax) them, and trigger [alerts](http://help.papertrailapp.com/kb/how-it-works/alerts). + +In most deployments, you'll want to send logs to Papertrail via their [remote_syslog](http://help.papertrailapp.com/kb/configuration/configuring-centralized-logging-from-text-log-files-in-unix/) daemon, which requires no application-specific configuration. This hook is intended for relatively low-volume logging, likely in managed cloud hosting deployments where installing `remote_syslog` is not possible. + +## Usage + +You can find your Papertrail UDP port on your [Papertrail account page](https://papertrailapp.com/account/destinations). Substitute it below for `YOUR_PAPERTRAIL_UDP_PORT`. + +For `YOUR_APP_NAME`, substitute a short string that will readily identify your application or service in the logs. + +```go +import ( + "log/syslog" + "github.com/Sirupsen/logrus" + "github.com/Sirupsen/logrus/hooks/papertrail" +) + +func main() { + log := logrus.New() + hook, err := logrus_papertrail.NewPapertrailHook("logs.papertrailapp.com", YOUR_PAPERTRAIL_UDP_PORT, YOUR_APP_NAME) + + if err == nil { + log.Hooks.Add(hook) + } +} +``` diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go new file mode 100644 index 000000000..c0f10c1bd --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go @@ -0,0 +1,55 @@ +package logrus_papertrail + +import ( + "fmt" + "net" + "os" + "time" + + "github.com/Sirupsen/logrus" +) + +const ( + format = "Jan 2 15:04:05" +) + +// PapertrailHook to send logs to a logging service compatible with the Papertrail API. +type PapertrailHook struct { + Host string + Port int + AppName string + UDPConn net.Conn +} + +// NewPapertrailHook creates a hook to be added to an instance of logger. +func NewPapertrailHook(host string, port int, appName string) (*PapertrailHook, error) { + conn, err := net.Dial("udp", fmt.Sprintf("%s:%d", host, port)) + return &PapertrailHook{host, port, appName, conn}, err +} + +// Fire is called when a log event is fired. +func (hook *PapertrailHook) Fire(entry *logrus.Entry) error { + date := time.Now().Format(format) + msg, _ := entry.String() + payload := fmt.Sprintf("<22> %s %s: %s", date, hook.AppName, msg) + + bytesWritten, err := hook.UDPConn.Write([]byte(payload)) + if err != nil { + fmt.Fprintf(os.Stderr, "Unable to send log line to Papertrail via UDP. Wrote %d bytes before error: %v", bytesWritten, err) + return err + } + + return nil +} + +// Levels returns the available logging levels. +func (hook *PapertrailHook) Levels() []logrus.Level { + return []logrus.Level{ + logrus.PanicLevel, + logrus.FatalLevel, + logrus.ErrorLevel, + logrus.WarnLevel, + logrus.InfoLevel, + logrus.DebugLevel, + } +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/sentry/README.md b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/sentry/README.md new file mode 100644 index 000000000..31de6540a --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/sentry/README.md @@ -0,0 +1,111 @@ +# Sentry Hook for Logrus :walrus: + +[Sentry](https://getsentry.com) provides both self-hosted and hosted +solutions for exception tracking. +Both client and server are +[open source](https://github.com/getsentry/sentry). + +## Usage + +Every sentry application defined on the server gets a different +[DSN](https://www.getsentry.com/docs/). In the example below replace +`YOUR_DSN` with the one created for your application. + +```go +import ( + "github.com/Sirupsen/logrus" + "github.com/Sirupsen/logrus/hooks/sentry" +) + +func main() { + log := logrus.New() + hook, err := logrus_sentry.NewSentryHook(YOUR_DSN, []logrus.Level{ + logrus.PanicLevel, + logrus.FatalLevel, + logrus.ErrorLevel, + }) + + if err == nil { + log.Hooks.Add(hook) + } +} +``` + +If you wish to initialize a SentryHook with tags, you can use the `NewWithTagsSentryHook` constructor to provide default tags: + +```go +tags := map[string]string{ + "site": "example.com", +} +levels := []logrus.Level{ + logrus.PanicLevel, + logrus.FatalLevel, + logrus.ErrorLevel, +} +hook, err := logrus_sentry.NewWithTagsSentryHook(YOUR_DSN, tags, levels) + +``` + +If you wish to initialize a SentryHook with an already initialized raven client, you can use +the `NewWithClientSentryHook` constructor: + +```go +import ( + "github.com/Sirupsen/logrus" + "github.com/Sirupsen/logrus/hooks/sentry" + "github.com/getsentry/raven-go" +) + +func main() { + log := logrus.New() + + client, err := raven.New(YOUR_DSN) + if err != nil { + log.Fatal(err) + } + + hook, err := logrus_sentry.NewWithClientSentryHook(client, []logrus.Level{ + logrus.PanicLevel, + logrus.FatalLevel, + logrus.ErrorLevel, + }) + + if err == nil { + log.Hooks.Add(hook) + } +} + +hook, err := NewWithClientSentryHook(client, []logrus.Level{ + logrus.ErrorLevel, +}) +``` + +## Special fields + +Some logrus fields have a special meaning in this hook, +these are `server_name`, `logger` and `http_request`. +When logs are sent to sentry these fields are treated differently. +- `server_name` (also known as hostname) is the name of the server which +is logging the event (hostname.example.com) +- `logger` is the part of the application which is logging the event. +In go this usually means setting it to the name of the package. +- `http_request` is the in-coming request(*http.Request). The detailed request data are sent to Sentry. + +## Timeout + +`Timeout` is the time the sentry hook will wait for a response +from the sentry server. + +If this time elapses with no response from +the server an error will be returned. + +If `Timeout` is set to 0 the SentryHook will not wait for a reply +and will assume a correct delivery. + +The SentryHook has a default timeout of `100 milliseconds` when created +with a call to `NewSentryHook`. This can be changed by assigning a value to the `Timeout` field: + +```go +hook, _ := logrus_sentry.NewSentryHook(...) +hook.Timeout = 20*time.Second +``` diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry.go new file mode 100644 index 000000000..cf88098a8 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry.go @@ -0,0 +1,137 @@ +package logrus_sentry + +import ( + "fmt" + "net/http" + "time" + + "github.com/Sirupsen/logrus" + "github.com/getsentry/raven-go" +) + +var ( + severityMap = map[logrus.Level]raven.Severity{ + logrus.DebugLevel: raven.DEBUG, + logrus.InfoLevel: raven.INFO, + logrus.WarnLevel: raven.WARNING, + logrus.ErrorLevel: raven.ERROR, + logrus.FatalLevel: raven.FATAL, + logrus.PanicLevel: raven.FATAL, + } +) + +func getAndDel(d logrus.Fields, key string) (string, bool) { + var ( + ok bool + v interface{} + val string + ) + if v, ok = d[key]; !ok { + return "", false + } + + if val, ok = v.(string); !ok { + return "", false + } + delete(d, key) + return val, true +} + +func getAndDelRequest(d logrus.Fields, key string) (*http.Request, bool) { + var ( + ok bool + v interface{} + req *http.Request + ) + if v, ok = d[key]; !ok { + return nil, false + } + if req, ok = v.(*http.Request); !ok || req == nil { + return nil, false + } + delete(d, key) + return req, true +} + +// SentryHook delivers logs to a sentry server. +type SentryHook struct { + // Timeout sets the time to wait for a delivery error from the sentry server. + // If this is set to zero the server will not wait for any response and will + // consider the message correctly sent + Timeout time.Duration + + client *raven.Client + levels []logrus.Level +} + +// NewSentryHook creates a hook to be added to an instance of logger +// and initializes the raven client. +// This method sets the timeout to 100 milliseconds. +func NewSentryHook(DSN string, levels []logrus.Level) (*SentryHook, error) { + client, err := raven.New(DSN) + if err != nil { + return nil, err + } + return &SentryHook{100 * time.Millisecond, client, levels}, nil +} + +// NewWithTagsSentryHook creates a hook with tags to be added to an instance +// of logger and initializes the raven client. This method sets the timeout to +// 100 milliseconds. +func NewWithTagsSentryHook(DSN string, tags map[string]string, levels []logrus.Level) (*SentryHook, error) { + client, err := raven.NewWithTags(DSN, tags) + if err != nil { + return nil, err + } + return &SentryHook{100 * time.Millisecond, client, levels}, nil +} + +// NewWithClientSentryHook creates a hook using an initialized raven client. +// This method sets the timeout to 100 milliseconds. +func NewWithClientSentryHook(client *raven.Client, levels []logrus.Level) (*SentryHook, error) { + return &SentryHook{100 * time.Millisecond, client, levels}, nil +} + +// Called when an event should be sent to sentry +// Special fields that sentry uses to give more information to the server +// are extracted from entry.Data (if they are found) +// These fields are: logger, server_name and http_request +func (hook *SentryHook) Fire(entry *logrus.Entry) error { + packet := &raven.Packet{ + Message: entry.Message, + Timestamp: raven.Timestamp(entry.Time), + Level: severityMap[entry.Level], + Platform: "go", + } + + d := entry.Data + + if logger, ok := getAndDel(d, "logger"); ok { + packet.Logger = logger + } + if serverName, ok := getAndDel(d, "server_name"); ok { + packet.ServerName = serverName + } + if req, ok := getAndDelRequest(d, "http_request"); ok { + packet.Interfaces = append(packet.Interfaces, raven.NewHttp(req)) + } + packet.Extra = map[string]interface{}(d) + + _, errCh := hook.client.Capture(packet, nil) + timeout := hook.Timeout + if timeout != 0 { + timeoutCh := time.After(timeout) + select { + case err := <-errCh: + return err + case <-timeoutCh: + return fmt.Errorf("no response from sentry server in %s", timeout) + } + } + return nil +} + +// Levels returns the available logging levels. +func (hook *SentryHook) Levels() []logrus.Level { + return hook.levels +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md new file mode 100644 index 000000000..4dbb8e729 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md @@ -0,0 +1,20 @@ +# Syslog Hooks for Logrus :walrus: + +## Usage + +```go +import ( + "log/syslog" + "github.com/Sirupsen/logrus" + logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog" +) + +func main() { + log := logrus.New() + hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") + + if err == nil { + log.Hooks.Add(hook) + } +} +``` diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go new file mode 100644 index 000000000..b6fa37462 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go @@ -0,0 +1,59 @@ +package logrus_syslog + +import ( + "fmt" + "github.com/Sirupsen/logrus" + "log/syslog" + "os" +) + +// SyslogHook to send logs via syslog. +type SyslogHook struct { + Writer *syslog.Writer + SyslogNetwork string + SyslogRaddr string +} + +// Creates a hook to be added to an instance of logger. This is called with +// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")` +// `if err == nil { log.Hooks.Add(hook) }` +func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) { + w, err := syslog.Dial(network, raddr, priority, tag) + return &SyslogHook{w, network, raddr}, err +} + +func (hook *SyslogHook) Fire(entry *logrus.Entry) error { + line, err := entry.String() + if err != nil { + fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err) + return err + } + + switch entry.Level { + case logrus.PanicLevel: + return hook.Writer.Crit(line) + case logrus.FatalLevel: + return hook.Writer.Crit(line) + case logrus.ErrorLevel: + return hook.Writer.Err(line) + case logrus.WarnLevel: + return hook.Writer.Warning(line) + case logrus.InfoLevel: + return hook.Writer.Info(line) + case logrus.DebugLevel: + return hook.Writer.Debug(line) + default: + return nil + } +} + +func (hook *SyslogHook) Levels() []logrus.Level { + return []logrus.Level{ + logrus.PanicLevel, + logrus.FatalLevel, + logrus.ErrorLevel, + logrus.WarnLevel, + logrus.InfoLevel, + logrus.DebugLevel, + } +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/json_formatter.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/json_formatter.go new file mode 100644 index 000000000..2ad6dc5cf --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/json_formatter.go @@ -0,0 +1,41 @@ +package logrus + +import ( + "encoding/json" + "fmt" +) + +type JSONFormatter struct { + // TimestampFormat sets the format used for marshaling timestamps. + TimestampFormat string +} + +func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { + data := make(Fields, len(entry.Data)+3) + for k, v := range entry.Data { + switch v := v.(type) { + case error: + // Otherwise errors are ignored by `encoding/json` + // https://github.com/Sirupsen/logrus/issues/137 + data[k] = v.Error() + default: + data[k] = v + } + } + prefixFieldClashes(data) + + timestampFormat := f.TimestampFormat + if timestampFormat == "" { + timestampFormat = DefaultTimestampFormat + } + + data["time"] = entry.Time.Format(timestampFormat) + data["msg"] = entry.Message + data["level"] = entry.Level.String() + + serialized, err := json.Marshal(data) + if err != nil { + return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) + } + return append(serialized, '\n'), nil +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/logger.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/logger.go new file mode 100644 index 000000000..fd9804c64 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/logger.go @@ -0,0 +1,206 @@ +package logrus + +import ( + "io" + "os" + "sync" +) + +type Logger struct { + // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a + // file, or leave it default which is `os.Stderr`. You can also set this to + // something more adventorous, such as logging to Kafka. + Out io.Writer + // Hooks for the logger instance. These allow firing events based on logging + // levels and log entries. For example, to send errors to an error tracking + // service, log to StatsD or dump the core on fatal errors. + Hooks LevelHooks + // All log entries pass through the formatter before logged to Out. The + // included formatters are `TextFormatter` and `JSONFormatter` for which + // TextFormatter is the default. In development (when a TTY is attached) it + // logs with colors, but to a file it wouldn't. You can easily implement your + // own that implements the `Formatter` interface, see the `README` or included + // formatters for examples. + Formatter Formatter + // The logging level the logger should log at. This is typically (and defaults + // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be + // logged. `logrus.Debug` is useful in + Level Level + // Used to sync writing to the log. + mu sync.Mutex +} + +// Creates a new logger. Configuration should be set by changing `Formatter`, +// `Out` and `Hooks` directly on the default logger instance. You can also just +// instantiate your own: +// +// var log = &Logger{ +// Out: os.Stderr, +// Formatter: new(JSONFormatter), +// Hooks: make(LevelHooks), +// Level: logrus.DebugLevel, +// } +// +// It's recommended to make this a global instance called `log`. +func New() *Logger { + return &Logger{ + Out: os.Stderr, + Formatter: new(TextFormatter), + Hooks: make(LevelHooks), + Level: InfoLevel, + } +} + +// Adds a field to the log entry, note that you it doesn't log until you call +// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry. +// If you want multiple fields, use `WithFields`. +func (logger *Logger) WithField(key string, value interface{}) *Entry { + return NewEntry(logger).WithField(key, value) +} + +// Adds a struct of fields to the log entry. All it does is call `WithField` for +// each `Field`. +func (logger *Logger) WithFields(fields Fields) *Entry { + return NewEntry(logger).WithFields(fields) +} + +func (logger *Logger) Debugf(format string, args ...interface{}) { + if logger.Level >= DebugLevel { + NewEntry(logger).Debugf(format, args...) + } +} + +func (logger *Logger) Infof(format string, args ...interface{}) { + if logger.Level >= InfoLevel { + NewEntry(logger).Infof(format, args...) + } +} + +func (logger *Logger) Printf(format string, args ...interface{}) { + NewEntry(logger).Printf(format, args...) +} + +func (logger *Logger) Warnf(format string, args ...interface{}) { + if logger.Level >= WarnLevel { + NewEntry(logger).Warnf(format, args...) + } +} + +func (logger *Logger) Warningf(format string, args ...interface{}) { + if logger.Level >= WarnLevel { + NewEntry(logger).Warnf(format, args...) + } +} + +func (logger *Logger) Errorf(format string, args ...interface{}) { + if logger.Level >= ErrorLevel { + NewEntry(logger).Errorf(format, args...) + } +} + +func (logger *Logger) Fatalf(format string, args ...interface{}) { + if logger.Level >= FatalLevel { + NewEntry(logger).Fatalf(format, args...) + } + os.Exit(1) +} + +func (logger *Logger) Panicf(format string, args ...interface{}) { + if logger.Level >= PanicLevel { + NewEntry(logger).Panicf(format, args...) + } +} + +func (logger *Logger) Debug(args ...interface{}) { + if logger.Level >= DebugLevel { + NewEntry(logger).Debug(args...) + } +} + +func (logger *Logger) Info(args ...interface{}) { + if logger.Level >= InfoLevel { + NewEntry(logger).Info(args...) + } +} + +func (logger *Logger) Print(args ...interface{}) { + NewEntry(logger).Info(args...) +} + +func (logger *Logger) Warn(args ...interface{}) { + if logger.Level >= WarnLevel { + NewEntry(logger).Warn(args...) + } +} + +func (logger *Logger) Warning(args ...interface{}) { + if logger.Level >= WarnLevel { + NewEntry(logger).Warn(args...) + } +} + +func (logger *Logger) Error(args ...interface{}) { + if logger.Level >= ErrorLevel { + NewEntry(logger).Error(args...) + } +} + +func (logger *Logger) Fatal(args ...interface{}) { + if logger.Level >= FatalLevel { + NewEntry(logger).Fatal(args...) + } + os.Exit(1) +} + +func (logger *Logger) Panic(args ...interface{}) { + if logger.Level >= PanicLevel { + NewEntry(logger).Panic(args...) + } +} + +func (logger *Logger) Debugln(args ...interface{}) { + if logger.Level >= DebugLevel { + NewEntry(logger).Debugln(args...) + } +} + +func (logger *Logger) Infoln(args ...interface{}) { + if logger.Level >= InfoLevel { + NewEntry(logger).Infoln(args...) + } +} + +func (logger *Logger) Println(args ...interface{}) { + NewEntry(logger).Println(args...) +} + +func (logger *Logger) Warnln(args ...interface{}) { + if logger.Level >= WarnLevel { + NewEntry(logger).Warnln(args...) + } +} + +func (logger *Logger) Warningln(args ...interface{}) { + if logger.Level >= WarnLevel { + NewEntry(logger).Warnln(args...) + } +} + +func (logger *Logger) Errorln(args ...interface{}) { + if logger.Level >= ErrorLevel { + NewEntry(logger).Errorln(args...) + } +} + +func (logger *Logger) Fatalln(args ...interface{}) { + if logger.Level >= FatalLevel { + NewEntry(logger).Fatalln(args...) + } + os.Exit(1) +} + +func (logger *Logger) Panicln(args ...interface{}) { + if logger.Level >= PanicLevel { + NewEntry(logger).Panicln(args...) + } +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/logrus.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/logrus.go new file mode 100644 index 000000000..0c09fbc26 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/logrus.go @@ -0,0 +1,98 @@ +package logrus + +import ( + "fmt" + "log" +) + +// Fields type, used to pass to `WithFields`. +type Fields map[string]interface{} + +// Level type +type Level uint8 + +// Convert the Level to a string. E.g. PanicLevel becomes "panic". +func (level Level) String() string { + switch level { + case DebugLevel: + return "debug" + case InfoLevel: + return "info" + case WarnLevel: + return "warning" + case ErrorLevel: + return "error" + case FatalLevel: + return "fatal" + case PanicLevel: + return "panic" + } + + return "unknown" +} + +// ParseLevel takes a string level and returns the Logrus log level constant. +func ParseLevel(lvl string) (Level, error) { + switch lvl { + case "panic": + return PanicLevel, nil + case "fatal": + return FatalLevel, nil + case "error": + return ErrorLevel, nil + case "warn", "warning": + return WarnLevel, nil + case "info": + return InfoLevel, nil + case "debug": + return DebugLevel, nil + } + + var l Level + return l, fmt.Errorf("not a valid logrus Level: %q", lvl) +} + +// These are the different logging levels. You can set the logging level to log +// on your instance of logger, obtained with `logrus.New()`. +const ( + // PanicLevel level, highest level of severity. Logs and then calls panic with the + // message passed to Debug, Info, ... + PanicLevel Level = iota + // FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the + // logging level is set to Panic. + FatalLevel + // ErrorLevel level. Logs. Used for errors that should definitely be noted. + // Commonly used for hooks to send errors to an error tracking service. + ErrorLevel + // WarnLevel level. Non-critical entries that deserve eyes. + WarnLevel + // InfoLevel level. General operational entries about what's going on inside the + // application. + InfoLevel + // DebugLevel level. Usually only enabled when debugging. Very verbose logging. + DebugLevel +) + +// Won't compile if StdLogger can't be realized by a log.Logger +var ( + _ StdLogger = &log.Logger{} + _ StdLogger = &Entry{} + _ StdLogger = &Logger{} +) + +// StdLogger is what your logrus-enabled library should take, that way +// it'll accept a stdlib logger and a logrus logger. There's no standard +// interface, this is the closest we get, unfortunately. +type StdLogger interface { + Print(...interface{}) + Printf(string, ...interface{}) + Println(...interface{}) + + Fatal(...interface{}) + Fatalf(string, ...interface{}) + Fatalln(...interface{}) + + Panic(...interface{}) + Panicf(string, ...interface{}) + Panicln(...interface{}) +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_bsd.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_bsd.go new file mode 100644 index 000000000..71f8d67a5 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_bsd.go @@ -0,0 +1,9 @@ +// +build darwin freebsd openbsd netbsd dragonfly + +package logrus + +import "syscall" + +const ioctlReadTermios = syscall.TIOCGETA + +type Termios syscall.Termios diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_linux.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_linux.go new file mode 100644 index 000000000..a2c0b40db --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_linux.go @@ -0,0 +1,12 @@ +// Based on ssh/terminal: +// Copyright 2013 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 logrus + +import "syscall" + +const ioctlReadTermios = syscall.TCGETS + +type Termios syscall.Termios diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go new file mode 100644 index 000000000..4bb537602 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go @@ -0,0 +1,21 @@ +// Based on ssh/terminal: +// Copyright 2011 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. + +// +build linux darwin freebsd openbsd netbsd dragonfly + +package logrus + +import ( + "syscall" + "unsafe" +) + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal() bool { + fd := syscall.Stdout + var termios Termios + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) + return err == 0 +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_windows.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_windows.go new file mode 100644 index 000000000..2e09f6f7e --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/terminal_windows.go @@ -0,0 +1,27 @@ +// Based on ssh/terminal: +// Copyright 2011 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. + +// +build windows + +package logrus + +import ( + "syscall" + "unsafe" +) + +var kernel32 = syscall.NewLazyDLL("kernel32.dll") + +var ( + procGetConsoleMode = kernel32.NewProc("GetConsoleMode") +) + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal() bool { + fd := syscall.Stdout + var st uint32 + r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) + return r != 0 && e == 0 +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/text_formatter.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/text_formatter.go new file mode 100644 index 000000000..17cc29848 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/text_formatter.go @@ -0,0 +1,159 @@ +package logrus + +import ( + "bytes" + "fmt" + "runtime" + "sort" + "strings" + "time" +) + +const ( + nocolor = 0 + red = 31 + green = 32 + yellow = 33 + blue = 34 + gray = 37 +) + +var ( + baseTimestamp time.Time + isTerminal bool +) + +func init() { + baseTimestamp = time.Now() + isTerminal = IsTerminal() +} + +func miniTS() int { + return int(time.Since(baseTimestamp) / time.Second) +} + +type TextFormatter struct { + // Set to true to bypass checking for a TTY before outputting colors. + ForceColors bool + + // Force disabling colors. + DisableColors bool + + // Disable timestamp logging. useful when output is redirected to logging + // system that already adds timestamps. + DisableTimestamp bool + + // Enable logging the full timestamp when a TTY is attached instead of just + // the time passed since beginning of execution. + FullTimestamp bool + + // TimestampFormat to use for display when a full timestamp is printed + TimestampFormat string + + // The fields are sorted by default for a consistent output. For applications + // that log extremely frequently and don't use the JSON formatter this may not + // be desired. + DisableSorting bool +} + +func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { + var keys []string = make([]string, 0, len(entry.Data)) + for k := range entry.Data { + keys = append(keys, k) + } + + if !f.DisableSorting { + sort.Strings(keys) + } + + b := &bytes.Buffer{} + + prefixFieldClashes(entry.Data) + + isColorTerminal := isTerminal && (runtime.GOOS != "windows") + isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors + + timestampFormat := f.TimestampFormat + if timestampFormat == "" { + timestampFormat = DefaultTimestampFormat + } + if isColored { + f.printColored(b, entry, keys, timestampFormat) + } else { + if !f.DisableTimestamp { + f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat)) + } + f.appendKeyValue(b, "level", entry.Level.String()) + f.appendKeyValue(b, "msg", entry.Message) + for _, key := range keys { + f.appendKeyValue(b, key, entry.Data[key]) + } + } + + b.WriteByte('\n') + return b.Bytes(), nil +} + +func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) { + var levelColor int + switch entry.Level { + case DebugLevel: + levelColor = gray + case WarnLevel: + levelColor = yellow + case ErrorLevel, FatalLevel, PanicLevel: + levelColor = red + default: + levelColor = blue + } + + levelText := strings.ToUpper(entry.Level.String())[0:4] + + if !f.FullTimestamp { + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message) + } else { + fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message) + } + for _, k := range keys { + v := entry.Data[k] + fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%+v", levelColor, k, v) + } +} + +func needsQuoting(text string) bool { + for _, ch := range text { + if !((ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9') || + ch == '-' || ch == '.') { + return false + } + } + return true +} + +func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) { + + b.WriteString(key) + b.WriteByte('=') + + switch value := value.(type) { + case string: + if needsQuoting(value) { + b.WriteString(value) + } else { + fmt.Fprintf(b, "%q", value) + } + case error: + errmsg := value.Error() + if needsQuoting(errmsg) { + b.WriteString(errmsg) + } else { + fmt.Fprintf(b, "%q", value) + } + default: + fmt.Fprint(b, value) + } + + b.WriteByte(' ') +} diff --git a/alpine/packages/go/vendor/github.com/Sirupsen/logrus/writer.go b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/writer.go new file mode 100644 index 000000000..1e30b1c75 --- /dev/null +++ b/alpine/packages/go/vendor/github.com/Sirupsen/logrus/writer.go @@ -0,0 +1,31 @@ +package logrus + +import ( + "bufio" + "io" + "runtime" +) + +func (logger *Logger) Writer() *io.PipeWriter { + reader, writer := io.Pipe() + + go logger.writerScanner(reader) + runtime.SetFinalizer(writer, writerFinalizer) + + return writer +} + +func (logger *Logger) writerScanner(reader *io.PipeReader) { + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + logger.Print(scanner.Text()) + } + if err := scanner.Err(); err != nil { + logger.Errorf("Error while reading from Writer: %s", err) + } + reader.Close() +} + +func writerFinalizer(writer *io.PipeWriter) { + writer.Close() +} From 245fa32d28770c73c56f4d7f2206e4aab53cba91 Mon Sep 17 00:00:00 2001 From: Rolf Neugebauer Date: Tue, 17 May 2016 17:57:59 +0100 Subject: [PATCH 3/5] diagnostics: add support for hyper-V sockets Use the new shared vendor'ed packages Signed-off-by: Rolf Neugebauer --- alpine/packages/diagnostics/.gitignore | 1 + alpine/packages/diagnostics/Makefile | 9 +- alpine/packages/diagnostics/main.go | 11 +- .../vendor/github.com/djs55/vsock/vsock.go | 171 ------------------ alpine/packages/diagnostics/vendor/manifest | 13 -- 5 files changed, 18 insertions(+), 187 deletions(-) delete mode 100644 alpine/packages/diagnostics/vendor/github.com/djs55/vsock/vsock.go delete mode 100644 alpine/packages/diagnostics/vendor/manifest diff --git a/alpine/packages/diagnostics/.gitignore b/alpine/packages/diagnostics/.gitignore index 4c3c66566..1802b3c31 100644 --- a/alpine/packages/diagnostics/.gitignore +++ b/alpine/packages/diagnostics/.gitignore @@ -1 +1,2 @@ diagnostics-server +/vendor \ No newline at end of file diff --git a/alpine/packages/diagnostics/Makefile b/alpine/packages/diagnostics/Makefile index 8d0ed40f5..0f2f03a8b 100644 --- a/alpine/packages/diagnostics/Makefile +++ b/alpine/packages/diagnostics/Makefile @@ -1,10 +1,15 @@ all: diagnostics-server -diagnostics-server: Dockerfile main.go +.PHONY: vendor +vendor: + mkdir -p ./vendor + cp -r ../go/vendor/* ./vendor/ + +diagnostics-server: Dockerfile main.go vendor docker build --build-arg GOOS=$(OS) --build-arg GOARCH=$(ARCH) -t diagnostics:build . docker run --rm diagnostics:build cat /go/bin/diagnostics > diagnostics-server chmod 755 diagnostics-server clean: - rm -f diagnostics-server + rm -rf diagnostics-server vendor docker images -q diagnostics:build | xargs docker rmi -f diff --git a/alpine/packages/diagnostics/main.go b/alpine/packages/diagnostics/main.go index 8094aa391..313066c65 100644 --- a/alpine/packages/diagnostics/main.go +++ b/alpine/packages/diagnostics/main.go @@ -10,7 +10,9 @@ import ( "path" "strings" "time" - "github.com/djs55/vsock" + + "github.com/rneugeba/virtsock/go/vsock" + "github.com/rneugeba/virtsock/go/hvsock" ) func run(timeout time.Duration, w *tar.Writer, command string, args ...string) { @@ -115,6 +117,13 @@ func main() { } else { listeners = append(listeners, vsock) } + svcid, _ := hvsock.GuidFromString("445BA2CB-E69B-4912-8B42-D7F494D007EA") + hvsock, err := hvsock.Listen(hvsock.HypervAddr{VmId: hvsock.GUID_WILDCARD, ServiceId: svcid}) + if err != nil { + log.Printf("Failed to bind to hvsock port: %#v", err) + } else { + listeners = append(listeners, hvsock) + } for _, l := range listeners { go func(l net.Listener) { diff --git a/alpine/packages/diagnostics/vendor/github.com/djs55/vsock/vsock.go b/alpine/packages/diagnostics/vendor/github.com/djs55/vsock/vsock.go deleted file mode 100644 index f8c38e00a..000000000 --- a/alpine/packages/diagnostics/vendor/github.com/djs55/vsock/vsock.go +++ /dev/null @@ -1,171 +0,0 @@ -package vsock - -import ( - "errors" - "fmt" - "net" - "os" - "syscall" - "time" -) - -/* No way to teach net or syscall about vsock sockaddr, so go right to C */ - -/* -#include - -struct sockaddr_vm { - sa_family_t svm_family; - unsigned short svm_reserved1; - unsigned int svm_port; - unsigned int svm_cid; - unsigned char svm_zero[sizeof(struct sockaddr) - - sizeof(sa_family_t) - sizeof(unsigned short) - - sizeof(unsigned int) - sizeof(unsigned int)]; -}; - -int bind_sockaddr_vm(int fd, const struct sockaddr_vm *sa_vm) { - return bind(fd, (const struct sockaddr*)sa_vm, sizeof(*sa_vm)); -} -int connect_sockaddr_vm(int fd, const struct sockaddr_vm *sa_vm) { - return connect(fd, (const struct sockaddr*)sa_vm, sizeof(*sa_vm)); -} -int accept_vm(int fd, struct sockaddr_vm *sa_vm, socklen_t *sa_vm_len) { - return accept4(fd, (struct sockaddr *)sa_vm, sa_vm_len, 0); -} -*/ -import "C" - -const ( - AF_VSOCK = 40 - VSOCK_CID_ANY = 4294967295 /* 2^32-1 */ - VSOCK_CID_SELF = 3 -) - -// Listen returns a net.Listener which can accept connections on the given -// vhan port. -func Listen(port uint) (net.Listener, error) { - accept_fd, err := syscall.Socket(AF_VSOCK, syscall.SOCK_STREAM, 0) - if err != nil { - return nil, err - } - - sa := C.struct_sockaddr_vm{} - sa.svm_family = AF_VSOCK - sa.svm_port = C.uint(port) - sa.svm_cid = VSOCK_CID_ANY - - if ret := C.bind_sockaddr_vm(C.int(accept_fd), &sa); ret != 0 { - return nil, errors.New(fmt.Sprintf("failed bind vsock connection to %08x.%08x, returned %d", sa.svm_cid, sa.svm_port, ret)) - } - - err = syscall.Listen(accept_fd, syscall.SOMAXCONN) - if err != nil { - return nil, err - } - return &vsockListener{accept_fd, port}, nil -} - -// Conn is a vsock connection which support half-close. -type Conn interface { - net.Conn - CloseRead() error - CloseWrite() error -} - -type vsockListener struct { - accept_fd int - port uint -} - -func (v *vsockListener) Accept() (net.Conn, error) { - var accept_sa C.struct_sockaddr_vm - var accept_sa_len C.socklen_t - - accept_sa_len = C.sizeof_struct_sockaddr_vm - fd, err := C.accept_vm(C.int(v.accept_fd), &accept_sa, &accept_sa_len) - if err != nil { - return nil, err - } - return newVsockConn(uintptr(fd), v.port) -} - -func (v *vsockListener) Close() error { - // Note this won't cause the Accept to unblock. - return syscall.Close(v.accept_fd) -} - -type VsockAddr struct { - Port uint -} - -func (a VsockAddr) Network() string { - return "vsock" -} - -func (a VsockAddr) String() string { - return fmt.Sprintf("%08x", a.Port) -} - -func (v *vsockListener) Addr() net.Addr { - return VsockAddr{Port: v.port} -} - -// a wrapper around FileConn which supports CloseRead and CloseWrite -type vsockConn struct { - vsock *os.File - fd uintptr - local VsockAddr - remote VsockAddr -} - -type VsockConn struct { - vsockConn -} - -func newVsockConn(fd uintptr, localPort uint) (*VsockConn, error) { - vsock := os.NewFile(fd, fmt.Sprintf("vsock:%d", fd)) - local := VsockAddr{Port: localPort} - remote := VsockAddr{Port: uint(0)} // FIXME - return &VsockConn{vsockConn{vsock: vsock, fd: fd, local: local, remote: remote}}, nil -} - -func (v *VsockConn) LocalAddr() net.Addr { - return v.local -} - -func (v *VsockConn) RemoteAddr() net.Addr { - return v.remote -} - -func (v *VsockConn) CloseRead() error { - return syscall.Shutdown(int(v.fd), syscall.SHUT_RD) -} - -func (v *VsockConn) CloseWrite() error { - return syscall.Shutdown(int(v.fd), syscall.SHUT_WR) -} - -func (v *VsockConn) Close() error { - return v.vsock.Close() -} - -func (v *VsockConn) Read(buf []byte) (int, error) { - return v.vsock.Read(buf) -} - -func (v *VsockConn) Write(buf []byte) (int, error) { - return v.vsock.Write(buf) -} - -func (v *VsockConn) SetDeadline(t time.Time) error { - return nil // FIXME -} - -func (v *VsockConn) SetReadDeadline(t time.Time) error { - return nil // FIXME -} - -func (v *VsockConn) SetWriteDeadline(t time.Time) error { - return nil // FIXME -} diff --git a/alpine/packages/diagnostics/vendor/manifest b/alpine/packages/diagnostics/vendor/manifest deleted file mode 100644 index 27f87a766..000000000 --- a/alpine/packages/diagnostics/vendor/manifest +++ /dev/null @@ -1,13 +0,0 @@ -{ - "version": 0, - "dependencies": [ - { - "importpath": "github.com/djs55/vsock", - "repository": "ssh://github.com/djs55/vsock", - "vcs": "git", - "revision": "7ea787de194e9a251ea746cf37f464c1e6cb822a", - "branch": "master", - "notests": true - } - ] -} \ No newline at end of file From 6c2056055c876d44f0d5eae281bfd05d99ea7111 Mon Sep 17 00:00:00 2001 From: Rolf Neugebauer Date: Thu, 19 May 2016 11:47:29 +0100 Subject: [PATCH 4/5] proxy: use share vendored go packages Signed-off-by: Rolf Neugebauer --- alpine/packages/proxy/.gitignore | 1 + alpine/packages/proxy/Makefile | 9 +- alpine/packages/proxy/libproxy/proxy.go | 2 +- alpine/packages/proxy/main.go | 2 +- .../github.com/Sirupsen/logrus/.gitignore | 1 - .../github.com/Sirupsen/logrus/.travis.yml | 8 - .../github.com/Sirupsen/logrus/CHANGELOG.md | 47 --- .../vendor/github.com/Sirupsen/logrus/LICENSE | 21 -- .../github.com/Sirupsen/logrus/README.md | 357 ------------------ .../vendor/github.com/Sirupsen/logrus/doc.go | 26 -- .../github.com/Sirupsen/logrus/entry.go | 264 ------------- .../Sirupsen/logrus/examples/basic/basic.go | 50 --- .../Sirupsen/logrus/examples/hook/hook.go | 30 -- .../github.com/Sirupsen/logrus/exported.go | 193 ---------- .../github.com/Sirupsen/logrus/formatter.go | 48 --- .../logrus/formatters/logstash/logstash.go | 56 --- .../github.com/Sirupsen/logrus/hooks.go | 34 -- .../logrus/hooks/airbrake/airbrake.go | 54 --- .../Sirupsen/logrus/hooks/bugsnag/bugsnag.go | 68 ---- .../logrus/hooks/papertrail/README.md | 28 -- .../logrus/hooks/papertrail/papertrail.go | 55 --- .../Sirupsen/logrus/hooks/sentry/README.md | 111 ------ .../Sirupsen/logrus/hooks/sentry/sentry.go | 137 ------- .../Sirupsen/logrus/hooks/syslog/README.md | 20 - .../Sirupsen/logrus/hooks/syslog/syslog.go | 59 --- .../Sirupsen/logrus/json_formatter.go | 41 -- .../github.com/Sirupsen/logrus/logger.go | 206 ---------- .../github.com/Sirupsen/logrus/logrus.go | 98 ----- .../Sirupsen/logrus/terminal_bsd.go | 9 - .../Sirupsen/logrus/terminal_linux.go | 12 - .../Sirupsen/logrus/terminal_notwindows.go | 21 -- .../Sirupsen/logrus/terminal_windows.go | 27 -- .../Sirupsen/logrus/text_formatter.go | 159 -------- .../github.com/Sirupsen/logrus/writer.go | 31 -- .../vendor/github.com/djs55/vsock/vsock.go | 171 --------- alpine/packages/proxy/vendor/manifest | 13 - 36 files changed, 10 insertions(+), 2459 deletions(-) delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/.gitignore delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/.travis.yml delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/CHANGELOG.md delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/LICENSE delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/README.md delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/doc.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/entry.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/examples/basic/basic.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/examples/hook/hook.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/exported.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/formatter.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/formatters/logstash/logstash.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/papertrail/README.md delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/sentry/README.md delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/json_formatter.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/logger.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/logrus.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_bsd.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_linux.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_windows.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/text_formatter.go delete mode 100644 alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/writer.go delete mode 100644 alpine/packages/proxy/vendor/github.com/djs55/vsock/vsock.go delete mode 100644 alpine/packages/proxy/vendor/manifest diff --git a/alpine/packages/proxy/.gitignore b/alpine/packages/proxy/.gitignore index c659c4f4f..a2b263ccc 100644 --- a/alpine/packages/proxy/.gitignore +++ b/alpine/packages/proxy/.gitignore @@ -1 +1,2 @@ /proxy +/vendor \ No newline at end of file diff --git a/alpine/packages/proxy/Makefile b/alpine/packages/proxy/Makefile index 5c041595d..0c386db49 100644 --- a/alpine/packages/proxy/Makefile +++ b/alpine/packages/proxy/Makefile @@ -1,10 +1,15 @@ all: proxy -proxy: Dockerfile main.go proxy.go +.PHONY: vendor +vendor: + mkdir -p ./vendor + cp -r ../go/vendor/* ./vendor/ + +proxy: Dockerfile main.go proxy.go vendor docker build --build-arg GOOS=$(OS) --build-arg GOARCH=$(ARCH) -t proxy:build . docker run --rm proxy:build cat /go/bin/proxy > proxy chmod 755 proxy clean: - rm -f proxy + rm -rf proxy vendor docker images -q proxy:build | xargs docker rmi -f diff --git a/alpine/packages/proxy/libproxy/proxy.go b/alpine/packages/proxy/libproxy/proxy.go index 472a0a5db..14053c1a2 100644 --- a/alpine/packages/proxy/libproxy/proxy.go +++ b/alpine/packages/proxy/libproxy/proxy.go @@ -4,7 +4,7 @@ package libproxy import ( "fmt" - "github.com/djs55/vsock" + "github.com/rneugeba/virtsock/go/vsock" "net" ) diff --git a/alpine/packages/proxy/main.go b/alpine/packages/proxy/main.go index aa44b2b8f..c3519b17f 100644 --- a/alpine/packages/proxy/main.go +++ b/alpine/packages/proxy/main.go @@ -8,7 +8,7 @@ import ( "os" "proxy/libproxy" "strings" - "github.com/djs55/vsock" + "github.com/rneugeba/virtsock/go/vsock" ) func main() { diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/.gitignore b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/.gitignore deleted file mode 100644 index 66be63a00..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/.gitignore +++ /dev/null @@ -1 +0,0 @@ -logrus diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/.travis.yml b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/.travis.yml deleted file mode 100644 index 2d8c08661..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: go -go: - - 1.2 - - 1.3 - - 1.4 - - tip -install: - - go get -t ./... diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/CHANGELOG.md b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/CHANGELOG.md deleted file mode 100644 index 78f98959b..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/CHANGELOG.md +++ /dev/null @@ -1,47 +0,0 @@ -# 0.8.7 - -* logrus/core: fix possible race (#216) -* logrus/doc: small typo fixes and doc improvements - - -# 0.8.6 - -* hooks/raven: allow passing an initialized client - -# 0.8.5 - -* logrus/core: revert #208 - -# 0.8.4 - -* formatter/text: fix data race (#218) - -# 0.8.3 - -* logrus/core: fix entry log level (#208) -* logrus/core: improve performance of text formatter by 40% -* logrus/core: expose `LevelHooks` type -* logrus/core: add support for DragonflyBSD and NetBSD -* formatter/text: print structs more verbosely - -# 0.8.2 - -* logrus: fix more Fatal family functions - -# 0.8.1 - -* logrus: fix not exiting on `Fatalf` and `Fatalln` - -# 0.8.0 - -* logrus: defaults to stderr instead of stdout -* hooks/sentry: add special field for `*http.Request` -* formatter/text: ignore Windows for colors - -# 0.7.3 - -* formatter/\*: allow configuration of timestamp layout - -# 0.7.2 - -* formatter/text: Add configuration option for time format (#158) diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/LICENSE b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/LICENSE deleted file mode 100644 index f090cb42f..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Simon Eskildsen - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/README.md b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/README.md deleted file mode 100644 index 6fa6e2062..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/README.md +++ /dev/null @@ -1,357 +0,0 @@ -# Logrus :walrus: [![Build Status](https://travis-ci.org/Sirupsen/logrus.svg?branch=master)](https://travis-ci.org/Sirupsen/logrus) [![godoc reference](https://godoc.org/github.com/Sirupsen/logrus?status.png)][godoc] - -Logrus is a structured logger for Go (golang), completely API compatible with -the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not -yet stable (pre 1.0). Logrus itself is completely stable and has been used in -many large deployments. The core API is unlikely to change much but please -version control your Logrus to make sure you aren't fetching latest `master` on -every build.** - -Nicely color-coded in development (when a TTY is attached, otherwise just -plain text): - -![Colored](http://i.imgur.com/PY7qMwd.png) - -With `log.Formatter = new(logrus.JSONFormatter)`, for easy parsing by logstash -or Splunk: - -```json -{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the -ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} - -{"level":"warning","msg":"The group's number increased tremendously!", -"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"} - -{"animal":"walrus","level":"info","msg":"A giant walrus appears!", -"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"} - -{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.", -"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"} - -{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true, -"time":"2014-03-10 19:57:38.562543128 -0400 EDT"} -``` - -With the default `log.Formatter = new(&log.TextFormatter{})` when a TTY is not -attached, the output is compatible with the -[logfmt](http://godoc.org/github.com/kr/logfmt) format: - -```text -time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8 -time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10 -time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true -time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4 -time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009 -time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true -exit status 1 -``` - -#### Example - -The simplest way to use Logrus is simply the package-level exported logger: - -```go -package main - -import ( - log "github.com/Sirupsen/logrus" -) - -func main() { - log.WithFields(log.Fields{ - "animal": "walrus", - }).Info("A walrus appears") -} -``` - -Note that it's completely api-compatible with the stdlib logger, so you can -replace your `log` imports everywhere with `log "github.com/Sirupsen/logrus"` -and you'll now have the flexibility of Logrus. You can customize it all you -want: - -```go -package main - -import ( - "os" - log "github.com/Sirupsen/logrus" - "github.com/Sirupsen/logrus/hooks/airbrake" -) - -func init() { - // Log as JSON instead of the default ASCII formatter. - log.SetFormatter(&log.JSONFormatter{}) - - // Use the Airbrake hook to report errors that have Error severity or above to - // an exception tracker. You can create custom hooks, see the Hooks section. - log.AddHook(airbrake.NewHook("https://example.com", "xyz", "development")) - - // Output to stderr instead of stdout, could also be a file. - log.SetOutput(os.Stderr) - - // Only log the warning severity or above. - log.SetLevel(log.WarnLevel) -} - -func main() { - log.WithFields(log.Fields{ - "animal": "walrus", - "size": 10, - }).Info("A group of walrus emerges from the ocean") - - log.WithFields(log.Fields{ - "omg": true, - "number": 122, - }).Warn("The group's number increased tremendously!") - - log.WithFields(log.Fields{ - "omg": true, - "number": 100, - }).Fatal("The ice breaks!") - - // A common pattern is to re-use fields between logging statements by re-using - // the logrus.Entry returned from WithFields() - contextLogger := log.WithFields(log.Fields{ - "common": "this is a common field", - "other": "I also should be logged always", - }) - - contextLogger.Info("I'll be logged with common and other field") - contextLogger.Info("Me too") -} -``` - -For more advanced usage such as logging to multiple locations from the same -application, you can also create an instance of the `logrus` Logger: - -```go -package main - -import ( - "github.com/Sirupsen/logrus" -) - -// Create a new instance of the logger. You can have any number of instances. -var log = logrus.New() - -func main() { - // The API for setting attributes is a little different than the package level - // exported logger. See Godoc. - log.Out = os.Stderr - - log.WithFields(logrus.Fields{ - "animal": "walrus", - "size": 10, - }).Info("A group of walrus emerges from the ocean") -} -``` - -#### Fields - -Logrus encourages careful, structured logging though logging fields instead of -long, unparseable error messages. For example, instead of: `log.Fatalf("Failed -to send event %s to topic %s with key %d")`, you should log the much more -discoverable: - -```go -log.WithFields(log.Fields{ - "event": event, - "topic": topic, - "key": key, -}).Fatal("Failed to send event") -``` - -We've found this API forces you to think about logging in a way that produces -much more useful logging messages. We've been in countless situations where just -a single added field to a log statement that was already there would've saved us -hours. The `WithFields` call is optional. - -In general, with Logrus using any of the `printf`-family functions should be -seen as a hint you should add a field, however, you can still use the -`printf`-family functions with Logrus. - -#### Hooks - -You can add hooks for logging levels. For example to send errors to an exception -tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to -multiple places simultaneously, e.g. syslog. - -Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in -`init`: - -```go -import ( - log "github.com/Sirupsen/logrus" - "github.com/Sirupsen/logrus/hooks/airbrake" - logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog" - "log/syslog" -) - -func init() { - log.AddHook(airbrake.NewHook("https://example.com", "xyz", "development")) - - hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") - if err != nil { - log.Error("Unable to connect to local syslog daemon") - } else { - log.AddHook(hook) - } -} -``` - - -| Hook | Description | -| ----- | ----------- | -| [Airbrake](https://github.com/Sirupsen/logrus/blob/master/hooks/airbrake/airbrake.go) | Send errors to an exception tracking service compatible with the Airbrake API. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. | -| [Papertrail](https://github.com/Sirupsen/logrus/blob/master/hooks/papertrail/papertrail.go) | Send errors to the Papertrail hosted logging service via UDP. | -| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. | -| [BugSnag](https://github.com/Sirupsen/logrus/blob/master/hooks/bugsnag/bugsnag.go) | Send errors to the Bugsnag exception tracking service. | -| [Sentry](https://github.com/Sirupsen/logrus/blob/master/hooks/sentry/sentry.go) | Send errors to the Sentry error logging and aggregation service. | -| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. | -| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) | -| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. | -| [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` | -| [Graylog](https://github.com/gemnasium/logrus-hooks/tree/master/graylog) | Hook for logging to [Graylog](http://graylog2.org/) | -| [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) | -| [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem | -| [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger | -| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail | -| [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar | -| [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd | -| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb | - -#### Level logging - -Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic. - -```go -log.Debug("Useful debugging information.") -log.Info("Something noteworthy happened!") -log.Warn("You should probably take a look at this.") -log.Error("Something failed but I'm not quitting.") -// Calls os.Exit(1) after logging -log.Fatal("Bye.") -// Calls panic() after logging -log.Panic("I'm bailing.") -``` - -You can set the logging level on a `Logger`, then it will only log entries with -that severity or anything above it: - -```go -// Will log anything that is info or above (warn, error, fatal, panic). Default. -log.SetLevel(log.InfoLevel) -``` - -It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose -environment if your application has that. - -#### Entries - -Besides the fields added with `WithField` or `WithFields` some fields are -automatically added to all logging events: - -1. `time`. The timestamp when the entry was created. -2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after - the `AddFields` call. E.g. `Failed to send event.` -3. `level`. The logging level. E.g. `info`. - -#### Environments - -Logrus has no notion of environment. - -If you wish for hooks and formatters to only be used in specific environments, -you should handle that yourself. For example, if your application has a global -variable `Environment`, which is a string representation of the environment you -could do: - -```go -import ( - log "github.com/Sirupsen/logrus" -) - -init() { - // do something here to set environment depending on an environment variable - // or command-line flag - if Environment == "production" { - log.SetFormatter(&log.JSONFormatter{}) - } else { - // The TextFormatter is default, you don't actually have to do this. - log.SetFormatter(&log.TextFormatter{}) - } -} -``` - -This configuration is how `logrus` was intended to be used, but JSON in -production is mostly only useful if you do log aggregation with tools like -Splunk or Logstash. - -#### Formatters - -The built-in logging formatters are: - -* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise - without colors. - * *Note:* to force colored output when there is no TTY, set the `ForceColors` - field to `true`. To force no colored output even if there is a TTY set the - `DisableColors` field to `true` -* `logrus.JSONFormatter`. Logs fields as JSON. -* `logrus_logstash.LogstashFormatter`. Logs fields as Logstash Events (http://logstash.net). - - ```go - logrus.SetFormatter(&logrus_logstash.LogstashFormatter{Type: “application_name"}) - ``` - -Third party logging formatters: - -* [`zalgo`](https://github.com/aybabtme/logzalgo): invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦. - -You can define your formatter by implementing the `Formatter` interface, -requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a -`Fields` type (`map[string]interface{}`) with all your fields as well as the -default ones (see Entries section above): - -```go -type MyJSONFormatter struct { -} - -log.SetFormatter(new(MyJSONFormatter)) - -func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) { - // Note this doesn't include Time, Level and Message which are available on - // the Entry. Consult `godoc` on information about those fields or read the - // source of the official loggers. - serialized, err := json.Marshal(entry.Data) - if err != nil { - return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) - } - return append(serialized, '\n'), nil -} -``` - -#### Logger as an `io.Writer` - -Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it. - -```go -w := logger.Writer() -defer w.Close() - -srv := http.Server{ - // create a stdlib log.Logger that writes to - // logrus.Logger. - ErrorLog: log.New(w, "", 0), -} -``` - -Each line written to that writer will be printed the usual way, using formatters -and hooks. The level for those entries is `info`. - -#### Rotation - -Log rotation is not provided with Logrus. Log rotation should be done by an -external program (like `logrotate(8)`) that can compress and delete old log -entries. It should not be a feature of the application-level logger. - - -[godoc]: https://godoc.org/github.com/Sirupsen/logrus diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/doc.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/doc.go deleted file mode 100644 index dddd5f877..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/doc.go +++ /dev/null @@ -1,26 +0,0 @@ -/* -Package logrus is a structured logger for Go, completely API compatible with the standard library logger. - - -The simplest way to use Logrus is simply the package-level exported logger: - - package main - - import ( - log "github.com/Sirupsen/logrus" - ) - - func main() { - log.WithFields(log.Fields{ - "animal": "walrus", - "number": 1, - "size": 10, - }).Info("A walrus appears") - } - -Output: - time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 - -For a full guide visit https://github.com/Sirupsen/logrus -*/ -package logrus diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/entry.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/entry.go deleted file mode 100644 index 9ae900bc5..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/entry.go +++ /dev/null @@ -1,264 +0,0 @@ -package logrus - -import ( - "bytes" - "fmt" - "io" - "os" - "time" -) - -// Defines the key when adding errors using WithError. -var ErrorKey = "error" - -// An entry is the final or intermediate Logrus logging entry. It contains all -// the fields passed with WithField{,s}. It's finally logged when Debug, Info, -// Warn, Error, Fatal or Panic is called on it. These objects can be reused and -// passed around as much as you wish to avoid field duplication. -type Entry struct { - Logger *Logger - - // Contains all the fields set by the user. - Data Fields - - // Time at which the log entry was created - Time time.Time - - // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic - Level Level - - // Message passed to Debug, Info, Warn, Error, Fatal or Panic - Message string -} - -func NewEntry(logger *Logger) *Entry { - return &Entry{ - Logger: logger, - // Default is three fields, give a little extra room - Data: make(Fields, 5), - } -} - -// Returns a reader for the entry, which is a proxy to the formatter. -func (entry *Entry) Reader() (*bytes.Buffer, error) { - serialized, err := entry.Logger.Formatter.Format(entry) - return bytes.NewBuffer(serialized), err -} - -// Returns the string representation from the reader and ultimately the -// formatter. -func (entry *Entry) String() (string, error) { - reader, err := entry.Reader() - if err != nil { - return "", err - } - - return reader.String(), err -} - -// Add an error as single field (using the key defined in ErrorKey) to the Entry. -func (entry *Entry) WithError(err error) *Entry { - return entry.WithField(ErrorKey, err) -} - -// Add a single field to the Entry. -func (entry *Entry) WithField(key string, value interface{}) *Entry { - return entry.WithFields(Fields{key: value}) -} - -// Add a map of fields to the Entry. -func (entry *Entry) WithFields(fields Fields) *Entry { - data := Fields{} - for k, v := range entry.Data { - data[k] = v - } - for k, v := range fields { - data[k] = v - } - return &Entry{Logger: entry.Logger, Data: data} -} - -// This function is not declared with a pointer value because otherwise -// race conditions will occur when using multiple goroutines -func (entry Entry) log(level Level, msg string) { - entry.Time = time.Now() - entry.Level = level - entry.Message = msg - - if err := entry.Logger.Hooks.Fire(level, &entry); err != nil { - entry.Logger.mu.Lock() - fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) - entry.Logger.mu.Unlock() - } - - reader, err := entry.Reader() - if err != nil { - entry.Logger.mu.Lock() - fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) - entry.Logger.mu.Unlock() - } - - entry.Logger.mu.Lock() - defer entry.Logger.mu.Unlock() - - _, err = io.Copy(entry.Logger.Out, reader) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) - } - - // To avoid Entry#log() returning a value that only would make sense for - // panic() to use in Entry#Panic(), we avoid the allocation by checking - // directly here. - if level <= PanicLevel { - panic(&entry) - } -} - -func (entry *Entry) Debug(args ...interface{}) { - if entry.Logger.Level >= DebugLevel { - entry.log(DebugLevel, fmt.Sprint(args...)) - } -} - -func (entry *Entry) Print(args ...interface{}) { - entry.Info(args...) -} - -func (entry *Entry) Info(args ...interface{}) { - if entry.Logger.Level >= InfoLevel { - entry.log(InfoLevel, fmt.Sprint(args...)) - } -} - -func (entry *Entry) Warn(args ...interface{}) { - if entry.Logger.Level >= WarnLevel { - entry.log(WarnLevel, fmt.Sprint(args...)) - } -} - -func (entry *Entry) Warning(args ...interface{}) { - entry.Warn(args...) -} - -func (entry *Entry) Error(args ...interface{}) { - if entry.Logger.Level >= ErrorLevel { - entry.log(ErrorLevel, fmt.Sprint(args...)) - } -} - -func (entry *Entry) Fatal(args ...interface{}) { - if entry.Logger.Level >= FatalLevel { - entry.log(FatalLevel, fmt.Sprint(args...)) - } - os.Exit(1) -} - -func (entry *Entry) Panic(args ...interface{}) { - if entry.Logger.Level >= PanicLevel { - entry.log(PanicLevel, fmt.Sprint(args...)) - } - panic(fmt.Sprint(args...)) -} - -// Entry Printf family functions - -func (entry *Entry) Debugf(format string, args ...interface{}) { - if entry.Logger.Level >= DebugLevel { - entry.Debug(fmt.Sprintf(format, args...)) - } -} - -func (entry *Entry) Infof(format string, args ...interface{}) { - if entry.Logger.Level >= InfoLevel { - entry.Info(fmt.Sprintf(format, args...)) - } -} - -func (entry *Entry) Printf(format string, args ...interface{}) { - entry.Infof(format, args...) -} - -func (entry *Entry) Warnf(format string, args ...interface{}) { - if entry.Logger.Level >= WarnLevel { - entry.Warn(fmt.Sprintf(format, args...)) - } -} - -func (entry *Entry) Warningf(format string, args ...interface{}) { - entry.Warnf(format, args...) -} - -func (entry *Entry) Errorf(format string, args ...interface{}) { - if entry.Logger.Level >= ErrorLevel { - entry.Error(fmt.Sprintf(format, args...)) - } -} - -func (entry *Entry) Fatalf(format string, args ...interface{}) { - if entry.Logger.Level >= FatalLevel { - entry.Fatal(fmt.Sprintf(format, args...)) - } - os.Exit(1) -} - -func (entry *Entry) Panicf(format string, args ...interface{}) { - if entry.Logger.Level >= PanicLevel { - entry.Panic(fmt.Sprintf(format, args...)) - } -} - -// Entry Println family functions - -func (entry *Entry) Debugln(args ...interface{}) { - if entry.Logger.Level >= DebugLevel { - entry.Debug(entry.sprintlnn(args...)) - } -} - -func (entry *Entry) Infoln(args ...interface{}) { - if entry.Logger.Level >= InfoLevel { - entry.Info(entry.sprintlnn(args...)) - } -} - -func (entry *Entry) Println(args ...interface{}) { - entry.Infoln(args...) -} - -func (entry *Entry) Warnln(args ...interface{}) { - if entry.Logger.Level >= WarnLevel { - entry.Warn(entry.sprintlnn(args...)) - } -} - -func (entry *Entry) Warningln(args ...interface{}) { - entry.Warnln(args...) -} - -func (entry *Entry) Errorln(args ...interface{}) { - if entry.Logger.Level >= ErrorLevel { - entry.Error(entry.sprintlnn(args...)) - } -} - -func (entry *Entry) Fatalln(args ...interface{}) { - if entry.Logger.Level >= FatalLevel { - entry.Fatal(entry.sprintlnn(args...)) - } - os.Exit(1) -} - -func (entry *Entry) Panicln(args ...interface{}) { - if entry.Logger.Level >= PanicLevel { - entry.Panic(entry.sprintlnn(args...)) - } -} - -// Sprintlnn => Sprint no newline. This is to get the behavior of how -// fmt.Sprintln where spaces are always added between operands, regardless of -// their type. Instead of vendoring the Sprintln implementation to spare a -// string allocation, we do the simplest thing. -func (entry *Entry) sprintlnn(args ...interface{}) string { - msg := fmt.Sprintln(args...) - return msg[:len(msg)-1] -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/examples/basic/basic.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/examples/basic/basic.go deleted file mode 100644 index a1623ec00..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/examples/basic/basic.go +++ /dev/null @@ -1,50 +0,0 @@ -package main - -import ( - "github.com/Sirupsen/logrus" -) - -var log = logrus.New() - -func init() { - log.Formatter = new(logrus.JSONFormatter) - log.Formatter = new(logrus.TextFormatter) // default - log.Level = logrus.DebugLevel -} - -func main() { - defer func() { - err := recover() - if err != nil { - log.WithFields(logrus.Fields{ - "omg": true, - "err": err, - "number": 100, - }).Fatal("The ice breaks!") - } - }() - - log.WithFields(logrus.Fields{ - "animal": "walrus", - "number": 8, - }).Debug("Started observing beach") - - log.WithFields(logrus.Fields{ - "animal": "walrus", - "size": 10, - }).Info("A group of walrus emerges from the ocean") - - log.WithFields(logrus.Fields{ - "omg": true, - "number": 122, - }).Warn("The group's number increased tremendously!") - - log.WithFields(logrus.Fields{ - "temperature": -4, - }).Debug("Temperature changes") - - log.WithFields(logrus.Fields{ - "animal": "orca", - "size": 9009, - }).Panic("It's over 9000!") -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/examples/hook/hook.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/examples/hook/hook.go deleted file mode 100644 index cb5759a35..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/examples/hook/hook.go +++ /dev/null @@ -1,30 +0,0 @@ -package main - -import ( - "github.com/Sirupsen/logrus" - "github.com/Sirupsen/logrus/hooks/airbrake" -) - -var log = logrus.New() - -func init() { - log.Formatter = new(logrus.TextFormatter) // default - log.Hooks.Add(airbrake.NewHook("https://example.com", "xyz", "development")) -} - -func main() { - log.WithFields(logrus.Fields{ - "animal": "walrus", - "size": 10, - }).Info("A group of walrus emerges from the ocean") - - log.WithFields(logrus.Fields{ - "omg": true, - "number": 122, - }).Warn("The group's number increased tremendously!") - - log.WithFields(logrus.Fields{ - "omg": true, - "number": 100, - }).Fatal("The ice breaks!") -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/exported.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/exported.go deleted file mode 100644 index 9a0120ac1..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/exported.go +++ /dev/null @@ -1,193 +0,0 @@ -package logrus - -import ( - "io" -) - -var ( - // std is the name of the standard logger in stdlib `log` - std = New() -) - -func StandardLogger() *Logger { - return std -} - -// SetOutput sets the standard logger output. -func SetOutput(out io.Writer) { - std.mu.Lock() - defer std.mu.Unlock() - std.Out = out -} - -// SetFormatter sets the standard logger formatter. -func SetFormatter(formatter Formatter) { - std.mu.Lock() - defer std.mu.Unlock() - std.Formatter = formatter -} - -// SetLevel sets the standard logger level. -func SetLevel(level Level) { - std.mu.Lock() - defer std.mu.Unlock() - std.Level = level -} - -// GetLevel returns the standard logger level. -func GetLevel() Level { - std.mu.Lock() - defer std.mu.Unlock() - return std.Level -} - -// AddHook adds a hook to the standard logger hooks. -func AddHook(hook Hook) { - std.mu.Lock() - defer std.mu.Unlock() - std.Hooks.Add(hook) -} - -// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key. -func WithError(err error) *Entry { - return std.WithField(ErrorKey, err) -} - -// WithField creates an entry from the standard logger and adds a field to -// it. If you want multiple fields, use `WithFields`. -// -// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal -// or Panic on the Entry it returns. -func WithField(key string, value interface{}) *Entry { - return std.WithField(key, value) -} - -// WithFields creates an entry from the standard logger and adds multiple -// fields to it. This is simply a helper for `WithField`, invoking it -// once for each field. -// -// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal -// or Panic on the Entry it returns. -func WithFields(fields Fields) *Entry { - return std.WithFields(fields) -} - -// Debug logs a message at level Debug on the standard logger. -func Debug(args ...interface{}) { - std.Debug(args...) -} - -// Print logs a message at level Info on the standard logger. -func Print(args ...interface{}) { - std.Print(args...) -} - -// Info logs a message at level Info on the standard logger. -func Info(args ...interface{}) { - std.Info(args...) -} - -// Warn logs a message at level Warn on the standard logger. -func Warn(args ...interface{}) { - std.Warn(args...) -} - -// Warning logs a message at level Warn on the standard logger. -func Warning(args ...interface{}) { - std.Warning(args...) -} - -// Error logs a message at level Error on the standard logger. -func Error(args ...interface{}) { - std.Error(args...) -} - -// Panic logs a message at level Panic on the standard logger. -func Panic(args ...interface{}) { - std.Panic(args...) -} - -// Fatal logs a message at level Fatal on the standard logger. -func Fatal(args ...interface{}) { - std.Fatal(args...) -} - -// Debugf logs a message at level Debug on the standard logger. -func Debugf(format string, args ...interface{}) { - std.Debugf(format, args...) -} - -// Printf logs a message at level Info on the standard logger. -func Printf(format string, args ...interface{}) { - std.Printf(format, args...) -} - -// Infof logs a message at level Info on the standard logger. -func Infof(format string, args ...interface{}) { - std.Infof(format, args...) -} - -// Warnf logs a message at level Warn on the standard logger. -func Warnf(format string, args ...interface{}) { - std.Warnf(format, args...) -} - -// Warningf logs a message at level Warn on the standard logger. -func Warningf(format string, args ...interface{}) { - std.Warningf(format, args...) -} - -// Errorf logs a message at level Error on the standard logger. -func Errorf(format string, args ...interface{}) { - std.Errorf(format, args...) -} - -// Panicf logs a message at level Panic on the standard logger. -func Panicf(format string, args ...interface{}) { - std.Panicf(format, args...) -} - -// Fatalf logs a message at level Fatal on the standard logger. -func Fatalf(format string, args ...interface{}) { - std.Fatalf(format, args...) -} - -// Debugln logs a message at level Debug on the standard logger. -func Debugln(args ...interface{}) { - std.Debugln(args...) -} - -// Println logs a message at level Info on the standard logger. -func Println(args ...interface{}) { - std.Println(args...) -} - -// Infoln logs a message at level Info on the standard logger. -func Infoln(args ...interface{}) { - std.Infoln(args...) -} - -// Warnln logs a message at level Warn on the standard logger. -func Warnln(args ...interface{}) { - std.Warnln(args...) -} - -// Warningln logs a message at level Warn on the standard logger. -func Warningln(args ...interface{}) { - std.Warningln(args...) -} - -// Errorln logs a message at level Error on the standard logger. -func Errorln(args ...interface{}) { - std.Errorln(args...) -} - -// Panicln logs a message at level Panic on the standard logger. -func Panicln(args ...interface{}) { - std.Panicln(args...) -} - -// Fatalln logs a message at level Fatal on the standard logger. -func Fatalln(args ...interface{}) { - std.Fatalln(args...) -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/formatter.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/formatter.go deleted file mode 100644 index 104d689f1..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/formatter.go +++ /dev/null @@ -1,48 +0,0 @@ -package logrus - -import "time" - -const DefaultTimestampFormat = time.RFC3339 - -// The Formatter interface is used to implement a custom Formatter. It takes an -// `Entry`. It exposes all the fields, including the default ones: -// -// * `entry.Data["msg"]`. The message passed from Info, Warn, Error .. -// * `entry.Data["time"]`. The timestamp. -// * `entry.Data["level"]. The level the entry was logged at. -// -// Any additional fields added with `WithField` or `WithFields` are also in -// `entry.Data`. Format is expected to return an array of bytes which are then -// logged to `logger.Out`. -type Formatter interface { - Format(*Entry) ([]byte, error) -} - -// This is to not silently overwrite `time`, `msg` and `level` fields when -// dumping it. If this code wasn't there doing: -// -// logrus.WithField("level", 1).Info("hello") -// -// Would just silently drop the user provided level. Instead with this code -// it'll logged as: -// -// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."} -// -// It's not exported because it's still using Data in an opinionated way. It's to -// avoid code duplication between the two default formatters. -func prefixFieldClashes(data Fields) { - _, ok := data["time"] - if ok { - data["fields.time"] = data["time"] - } - - _, ok = data["msg"] - if ok { - data["fields.msg"] = data["msg"] - } - - _, ok = data["level"] - if ok { - data["fields.level"] = data["level"] - } -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/formatters/logstash/logstash.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/formatters/logstash/logstash.go deleted file mode 100644 index 8ea93ddf2..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/formatters/logstash/logstash.go +++ /dev/null @@ -1,56 +0,0 @@ -package logstash - -import ( - "encoding/json" - "fmt" - - "github.com/Sirupsen/logrus" -) - -// Formatter generates json in logstash format. -// Logstash site: http://logstash.net/ -type LogstashFormatter struct { - Type string // if not empty use for logstash type field. - - // TimestampFormat sets the format used for timestamps. - TimestampFormat string -} - -func (f *LogstashFormatter) Format(entry *logrus.Entry) ([]byte, error) { - entry.Data["@version"] = 1 - - if f.TimestampFormat == "" { - f.TimestampFormat = logrus.DefaultTimestampFormat - } - - entry.Data["@timestamp"] = entry.Time.Format(f.TimestampFormat) - - // set message field - v, ok := entry.Data["message"] - if ok { - entry.Data["fields.message"] = v - } - entry.Data["message"] = entry.Message - - // set level field - v, ok = entry.Data["level"] - if ok { - entry.Data["fields.level"] = v - } - entry.Data["level"] = entry.Level.String() - - // set type field - if f.Type != "" { - v, ok = entry.Data["type"] - if ok { - entry.Data["fields.type"] = v - } - entry.Data["type"] = f.Type - } - - serialized, err := json.Marshal(entry.Data) - if err != nil { - return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) - } - return append(serialized, '\n'), nil -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks.go deleted file mode 100644 index 3f151cdc3..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks.go +++ /dev/null @@ -1,34 +0,0 @@ -package logrus - -// A hook to be fired when logging on the logging levels returned from -// `Levels()` on your implementation of the interface. Note that this is not -// fired in a goroutine or a channel with workers, you should handle such -// functionality yourself if your call is non-blocking and you don't wish for -// the logging calls for levels returned from `Levels()` to block. -type Hook interface { - Levels() []Level - Fire(*Entry) error -} - -// Internal type for storing the hooks on a logger instance. -type LevelHooks map[Level][]Hook - -// Add a hook to an instance of logger. This is called with -// `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface. -func (hooks LevelHooks) Add(hook Hook) { - for _, level := range hook.Levels() { - hooks[level] = append(hooks[level], hook) - } -} - -// Fire all the hooks for the passed level. Used by `entry.log` to fire -// appropriate hooks for a log entry. -func (hooks LevelHooks) Fire(level Level, entry *Entry) error { - for _, hook := range hooks[level] { - if err := hook.Fire(entry); err != nil { - return err - } - } - - return nil -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go deleted file mode 100644 index b0502c335..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go +++ /dev/null @@ -1,54 +0,0 @@ -package airbrake - -import ( - "errors" - "fmt" - - "github.com/Sirupsen/logrus" - "github.com/tobi/airbrake-go" -) - -// AirbrakeHook to send exceptions to an exception-tracking service compatible -// with the Airbrake API. -type airbrakeHook struct { - APIKey string - Endpoint string - Environment string -} - -func NewHook(endpoint, apiKey, env string) *airbrakeHook { - return &airbrakeHook{ - APIKey: apiKey, - Endpoint: endpoint, - Environment: env, - } -} - -func (hook *airbrakeHook) Fire(entry *logrus.Entry) error { - airbrake.ApiKey = hook.APIKey - airbrake.Endpoint = hook.Endpoint - airbrake.Environment = hook.Environment - - var notifyErr error - err, ok := entry.Data["error"].(error) - if ok { - notifyErr = err - } else { - notifyErr = errors.New(entry.Message) - } - - airErr := airbrake.Notify(notifyErr) - if airErr != nil { - return fmt.Errorf("Failed to send error to Airbrake: %s", airErr) - } - - return nil -} - -func (hook *airbrakeHook) Levels() []logrus.Level { - return []logrus.Level{ - logrus.ErrorLevel, - logrus.FatalLevel, - logrus.PanicLevel, - } -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go deleted file mode 100644 index d20a0f54a..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go +++ /dev/null @@ -1,68 +0,0 @@ -package logrus_bugsnag - -import ( - "errors" - - "github.com/Sirupsen/logrus" - "github.com/bugsnag/bugsnag-go" -) - -type bugsnagHook struct{} - -// ErrBugsnagUnconfigured is returned if NewBugsnagHook is called before -// bugsnag.Configure. Bugsnag must be configured before the hook. -var ErrBugsnagUnconfigured = errors.New("bugsnag must be configured before installing this logrus hook") - -// ErrBugsnagSendFailed indicates that the hook failed to submit an error to -// bugsnag. The error was successfully generated, but `bugsnag.Notify()` -// failed. -type ErrBugsnagSendFailed struct { - err error -} - -func (e ErrBugsnagSendFailed) Error() string { - return "failed to send error to Bugsnag: " + e.err.Error() -} - -// NewBugsnagHook initializes a logrus hook which sends exceptions to an -// exception-tracking service compatible with the Bugsnag API. Before using -// this hook, you must call bugsnag.Configure(). The returned object should be -// registered with a log via `AddHook()` -// -// Entries that trigger an Error, Fatal or Panic should now include an "error" -// field to send to Bugsnag. -func NewBugsnagHook() (*bugsnagHook, error) { - if bugsnag.Config.APIKey == "" { - return nil, ErrBugsnagUnconfigured - } - return &bugsnagHook{}, nil -} - -// Fire forwards an error to Bugsnag. Given a logrus.Entry, it extracts the -// "error" field (or the Message if the error isn't present) and sends it off. -func (hook *bugsnagHook) Fire(entry *logrus.Entry) error { - var notifyErr error - err, ok := entry.Data["error"].(error) - if ok { - notifyErr = err - } else { - notifyErr = errors.New(entry.Message) - } - - bugsnagErr := bugsnag.Notify(notifyErr) - if bugsnagErr != nil { - return ErrBugsnagSendFailed{bugsnagErr} - } - - return nil -} - -// Levels enumerates the log levels on which the error should be forwarded to -// bugsnag: everything at or above the "Error" level. -func (hook *bugsnagHook) Levels() []logrus.Level { - return []logrus.Level{ - logrus.ErrorLevel, - logrus.FatalLevel, - logrus.PanicLevel, - } -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/papertrail/README.md b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/papertrail/README.md deleted file mode 100644 index ae61e9229..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/papertrail/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Papertrail Hook for Logrus :walrus: - -[Papertrail](https://papertrailapp.com) provides hosted log management. Once stored in Papertrail, you can [group](http://help.papertrailapp.com/kb/how-it-works/groups/) your logs on various dimensions, [search](http://help.papertrailapp.com/kb/how-it-works/search-syntax) them, and trigger [alerts](http://help.papertrailapp.com/kb/how-it-works/alerts). - -In most deployments, you'll want to send logs to Papertrail via their [remote_syslog](http://help.papertrailapp.com/kb/configuration/configuring-centralized-logging-from-text-log-files-in-unix/) daemon, which requires no application-specific configuration. This hook is intended for relatively low-volume logging, likely in managed cloud hosting deployments where installing `remote_syslog` is not possible. - -## Usage - -You can find your Papertrail UDP port on your [Papertrail account page](https://papertrailapp.com/account/destinations). Substitute it below for `YOUR_PAPERTRAIL_UDP_PORT`. - -For `YOUR_APP_NAME`, substitute a short string that will readily identify your application or service in the logs. - -```go -import ( - "log/syslog" - "github.com/Sirupsen/logrus" - "github.com/Sirupsen/logrus/hooks/papertrail" -) - -func main() { - log := logrus.New() - hook, err := logrus_papertrail.NewPapertrailHook("logs.papertrailapp.com", YOUR_PAPERTRAIL_UDP_PORT, YOUR_APP_NAME) - - if err == nil { - log.Hooks.Add(hook) - } -} -``` diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go deleted file mode 100644 index c0f10c1bd..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go +++ /dev/null @@ -1,55 +0,0 @@ -package logrus_papertrail - -import ( - "fmt" - "net" - "os" - "time" - - "github.com/Sirupsen/logrus" -) - -const ( - format = "Jan 2 15:04:05" -) - -// PapertrailHook to send logs to a logging service compatible with the Papertrail API. -type PapertrailHook struct { - Host string - Port int - AppName string - UDPConn net.Conn -} - -// NewPapertrailHook creates a hook to be added to an instance of logger. -func NewPapertrailHook(host string, port int, appName string) (*PapertrailHook, error) { - conn, err := net.Dial("udp", fmt.Sprintf("%s:%d", host, port)) - return &PapertrailHook{host, port, appName, conn}, err -} - -// Fire is called when a log event is fired. -func (hook *PapertrailHook) Fire(entry *logrus.Entry) error { - date := time.Now().Format(format) - msg, _ := entry.String() - payload := fmt.Sprintf("<22> %s %s: %s", date, hook.AppName, msg) - - bytesWritten, err := hook.UDPConn.Write([]byte(payload)) - if err != nil { - fmt.Fprintf(os.Stderr, "Unable to send log line to Papertrail via UDP. Wrote %d bytes before error: %v", bytesWritten, err) - return err - } - - return nil -} - -// Levels returns the available logging levels. -func (hook *PapertrailHook) Levels() []logrus.Level { - return []logrus.Level{ - logrus.PanicLevel, - logrus.FatalLevel, - logrus.ErrorLevel, - logrus.WarnLevel, - logrus.InfoLevel, - logrus.DebugLevel, - } -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/sentry/README.md b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/sentry/README.md deleted file mode 100644 index 31de6540a..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/sentry/README.md +++ /dev/null @@ -1,111 +0,0 @@ -# Sentry Hook for Logrus :walrus: - -[Sentry](https://getsentry.com) provides both self-hosted and hosted -solutions for exception tracking. -Both client and server are -[open source](https://github.com/getsentry/sentry). - -## Usage - -Every sentry application defined on the server gets a different -[DSN](https://www.getsentry.com/docs/). In the example below replace -`YOUR_DSN` with the one created for your application. - -```go -import ( - "github.com/Sirupsen/logrus" - "github.com/Sirupsen/logrus/hooks/sentry" -) - -func main() { - log := logrus.New() - hook, err := logrus_sentry.NewSentryHook(YOUR_DSN, []logrus.Level{ - logrus.PanicLevel, - logrus.FatalLevel, - logrus.ErrorLevel, - }) - - if err == nil { - log.Hooks.Add(hook) - } -} -``` - -If you wish to initialize a SentryHook with tags, you can use the `NewWithTagsSentryHook` constructor to provide default tags: - -```go -tags := map[string]string{ - "site": "example.com", -} -levels := []logrus.Level{ - logrus.PanicLevel, - logrus.FatalLevel, - logrus.ErrorLevel, -} -hook, err := logrus_sentry.NewWithTagsSentryHook(YOUR_DSN, tags, levels) - -``` - -If you wish to initialize a SentryHook with an already initialized raven client, you can use -the `NewWithClientSentryHook` constructor: - -```go -import ( - "github.com/Sirupsen/logrus" - "github.com/Sirupsen/logrus/hooks/sentry" - "github.com/getsentry/raven-go" -) - -func main() { - log := logrus.New() - - client, err := raven.New(YOUR_DSN) - if err != nil { - log.Fatal(err) - } - - hook, err := logrus_sentry.NewWithClientSentryHook(client, []logrus.Level{ - logrus.PanicLevel, - logrus.FatalLevel, - logrus.ErrorLevel, - }) - - if err == nil { - log.Hooks.Add(hook) - } -} - -hook, err := NewWithClientSentryHook(client, []logrus.Level{ - logrus.ErrorLevel, -}) -``` - -## Special fields - -Some logrus fields have a special meaning in this hook, -these are `server_name`, `logger` and `http_request`. -When logs are sent to sentry these fields are treated differently. -- `server_name` (also known as hostname) is the name of the server which -is logging the event (hostname.example.com) -- `logger` is the part of the application which is logging the event. -In go this usually means setting it to the name of the package. -- `http_request` is the in-coming request(*http.Request). The detailed request data are sent to Sentry. - -## Timeout - -`Timeout` is the time the sentry hook will wait for a response -from the sentry server. - -If this time elapses with no response from -the server an error will be returned. - -If `Timeout` is set to 0 the SentryHook will not wait for a reply -and will assume a correct delivery. - -The SentryHook has a default timeout of `100 milliseconds` when created -with a call to `NewSentryHook`. This can be changed by assigning a value to the `Timeout` field: - -```go -hook, _ := logrus_sentry.NewSentryHook(...) -hook.Timeout = 20*time.Second -``` diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry.go deleted file mode 100644 index cf88098a8..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/sentry/sentry.go +++ /dev/null @@ -1,137 +0,0 @@ -package logrus_sentry - -import ( - "fmt" - "net/http" - "time" - - "github.com/Sirupsen/logrus" - "github.com/getsentry/raven-go" -) - -var ( - severityMap = map[logrus.Level]raven.Severity{ - logrus.DebugLevel: raven.DEBUG, - logrus.InfoLevel: raven.INFO, - logrus.WarnLevel: raven.WARNING, - logrus.ErrorLevel: raven.ERROR, - logrus.FatalLevel: raven.FATAL, - logrus.PanicLevel: raven.FATAL, - } -) - -func getAndDel(d logrus.Fields, key string) (string, bool) { - var ( - ok bool - v interface{} - val string - ) - if v, ok = d[key]; !ok { - return "", false - } - - if val, ok = v.(string); !ok { - return "", false - } - delete(d, key) - return val, true -} - -func getAndDelRequest(d logrus.Fields, key string) (*http.Request, bool) { - var ( - ok bool - v interface{} - req *http.Request - ) - if v, ok = d[key]; !ok { - return nil, false - } - if req, ok = v.(*http.Request); !ok || req == nil { - return nil, false - } - delete(d, key) - return req, true -} - -// SentryHook delivers logs to a sentry server. -type SentryHook struct { - // Timeout sets the time to wait for a delivery error from the sentry server. - // If this is set to zero the server will not wait for any response and will - // consider the message correctly sent - Timeout time.Duration - - client *raven.Client - levels []logrus.Level -} - -// NewSentryHook creates a hook to be added to an instance of logger -// and initializes the raven client. -// This method sets the timeout to 100 milliseconds. -func NewSentryHook(DSN string, levels []logrus.Level) (*SentryHook, error) { - client, err := raven.New(DSN) - if err != nil { - return nil, err - } - return &SentryHook{100 * time.Millisecond, client, levels}, nil -} - -// NewWithTagsSentryHook creates a hook with tags to be added to an instance -// of logger and initializes the raven client. This method sets the timeout to -// 100 milliseconds. -func NewWithTagsSentryHook(DSN string, tags map[string]string, levels []logrus.Level) (*SentryHook, error) { - client, err := raven.NewWithTags(DSN, tags) - if err != nil { - return nil, err - } - return &SentryHook{100 * time.Millisecond, client, levels}, nil -} - -// NewWithClientSentryHook creates a hook using an initialized raven client. -// This method sets the timeout to 100 milliseconds. -func NewWithClientSentryHook(client *raven.Client, levels []logrus.Level) (*SentryHook, error) { - return &SentryHook{100 * time.Millisecond, client, levels}, nil -} - -// Called when an event should be sent to sentry -// Special fields that sentry uses to give more information to the server -// are extracted from entry.Data (if they are found) -// These fields are: logger, server_name and http_request -func (hook *SentryHook) Fire(entry *logrus.Entry) error { - packet := &raven.Packet{ - Message: entry.Message, - Timestamp: raven.Timestamp(entry.Time), - Level: severityMap[entry.Level], - Platform: "go", - } - - d := entry.Data - - if logger, ok := getAndDel(d, "logger"); ok { - packet.Logger = logger - } - if serverName, ok := getAndDel(d, "server_name"); ok { - packet.ServerName = serverName - } - if req, ok := getAndDelRequest(d, "http_request"); ok { - packet.Interfaces = append(packet.Interfaces, raven.NewHttp(req)) - } - packet.Extra = map[string]interface{}(d) - - _, errCh := hook.client.Capture(packet, nil) - timeout := hook.Timeout - if timeout != 0 { - timeoutCh := time.After(timeout) - select { - case err := <-errCh: - return err - case <-timeoutCh: - return fmt.Errorf("no response from sentry server in %s", timeout) - } - } - return nil -} - -// Levels returns the available logging levels. -func (hook *SentryHook) Levels() []logrus.Level { - return hook.levels -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md deleted file mode 100644 index 4dbb8e729..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/syslog/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Syslog Hooks for Logrus :walrus: - -## Usage - -```go -import ( - "log/syslog" - "github.com/Sirupsen/logrus" - logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog" -) - -func main() { - log := logrus.New() - hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") - - if err == nil { - log.Hooks.Add(hook) - } -} -``` diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go deleted file mode 100644 index b6fa37462..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/hooks/syslog/syslog.go +++ /dev/null @@ -1,59 +0,0 @@ -package logrus_syslog - -import ( - "fmt" - "github.com/Sirupsen/logrus" - "log/syslog" - "os" -) - -// SyslogHook to send logs via syslog. -type SyslogHook struct { - Writer *syslog.Writer - SyslogNetwork string - SyslogRaddr string -} - -// Creates a hook to be added to an instance of logger. This is called with -// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")` -// `if err == nil { log.Hooks.Add(hook) }` -func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) { - w, err := syslog.Dial(network, raddr, priority, tag) - return &SyslogHook{w, network, raddr}, err -} - -func (hook *SyslogHook) Fire(entry *logrus.Entry) error { - line, err := entry.String() - if err != nil { - fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err) - return err - } - - switch entry.Level { - case logrus.PanicLevel: - return hook.Writer.Crit(line) - case logrus.FatalLevel: - return hook.Writer.Crit(line) - case logrus.ErrorLevel: - return hook.Writer.Err(line) - case logrus.WarnLevel: - return hook.Writer.Warning(line) - case logrus.InfoLevel: - return hook.Writer.Info(line) - case logrus.DebugLevel: - return hook.Writer.Debug(line) - default: - return nil - } -} - -func (hook *SyslogHook) Levels() []logrus.Level { - return []logrus.Level{ - logrus.PanicLevel, - logrus.FatalLevel, - logrus.ErrorLevel, - logrus.WarnLevel, - logrus.InfoLevel, - logrus.DebugLevel, - } -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/json_formatter.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/json_formatter.go deleted file mode 100644 index 2ad6dc5cf..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/json_formatter.go +++ /dev/null @@ -1,41 +0,0 @@ -package logrus - -import ( - "encoding/json" - "fmt" -) - -type JSONFormatter struct { - // TimestampFormat sets the format used for marshaling timestamps. - TimestampFormat string -} - -func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { - data := make(Fields, len(entry.Data)+3) - for k, v := range entry.Data { - switch v := v.(type) { - case error: - // Otherwise errors are ignored by `encoding/json` - // https://github.com/Sirupsen/logrus/issues/137 - data[k] = v.Error() - default: - data[k] = v - } - } - prefixFieldClashes(data) - - timestampFormat := f.TimestampFormat - if timestampFormat == "" { - timestampFormat = DefaultTimestampFormat - } - - data["time"] = entry.Time.Format(timestampFormat) - data["msg"] = entry.Message - data["level"] = entry.Level.String() - - serialized, err := json.Marshal(data) - if err != nil { - return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) - } - return append(serialized, '\n'), nil -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/logger.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/logger.go deleted file mode 100644 index fd9804c64..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/logger.go +++ /dev/null @@ -1,206 +0,0 @@ -package logrus - -import ( - "io" - "os" - "sync" -) - -type Logger struct { - // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a - // file, or leave it default which is `os.Stderr`. You can also set this to - // something more adventorous, such as logging to Kafka. - Out io.Writer - // Hooks for the logger instance. These allow firing events based on logging - // levels and log entries. For example, to send errors to an error tracking - // service, log to StatsD or dump the core on fatal errors. - Hooks LevelHooks - // All log entries pass through the formatter before logged to Out. The - // included formatters are `TextFormatter` and `JSONFormatter` for which - // TextFormatter is the default. In development (when a TTY is attached) it - // logs with colors, but to a file it wouldn't. You can easily implement your - // own that implements the `Formatter` interface, see the `README` or included - // formatters for examples. - Formatter Formatter - // The logging level the logger should log at. This is typically (and defaults - // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be - // logged. `logrus.Debug` is useful in - Level Level - // Used to sync writing to the log. - mu sync.Mutex -} - -// Creates a new logger. Configuration should be set by changing `Formatter`, -// `Out` and `Hooks` directly on the default logger instance. You can also just -// instantiate your own: -// -// var log = &Logger{ -// Out: os.Stderr, -// Formatter: new(JSONFormatter), -// Hooks: make(LevelHooks), -// Level: logrus.DebugLevel, -// } -// -// It's recommended to make this a global instance called `log`. -func New() *Logger { - return &Logger{ - Out: os.Stderr, - Formatter: new(TextFormatter), - Hooks: make(LevelHooks), - Level: InfoLevel, - } -} - -// Adds a field to the log entry, note that you it doesn't log until you call -// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry. -// If you want multiple fields, use `WithFields`. -func (logger *Logger) WithField(key string, value interface{}) *Entry { - return NewEntry(logger).WithField(key, value) -} - -// Adds a struct of fields to the log entry. All it does is call `WithField` for -// each `Field`. -func (logger *Logger) WithFields(fields Fields) *Entry { - return NewEntry(logger).WithFields(fields) -} - -func (logger *Logger) Debugf(format string, args ...interface{}) { - if logger.Level >= DebugLevel { - NewEntry(logger).Debugf(format, args...) - } -} - -func (logger *Logger) Infof(format string, args ...interface{}) { - if logger.Level >= InfoLevel { - NewEntry(logger).Infof(format, args...) - } -} - -func (logger *Logger) Printf(format string, args ...interface{}) { - NewEntry(logger).Printf(format, args...) -} - -func (logger *Logger) Warnf(format string, args ...interface{}) { - if logger.Level >= WarnLevel { - NewEntry(logger).Warnf(format, args...) - } -} - -func (logger *Logger) Warningf(format string, args ...interface{}) { - if logger.Level >= WarnLevel { - NewEntry(logger).Warnf(format, args...) - } -} - -func (logger *Logger) Errorf(format string, args ...interface{}) { - if logger.Level >= ErrorLevel { - NewEntry(logger).Errorf(format, args...) - } -} - -func (logger *Logger) Fatalf(format string, args ...interface{}) { - if logger.Level >= FatalLevel { - NewEntry(logger).Fatalf(format, args...) - } - os.Exit(1) -} - -func (logger *Logger) Panicf(format string, args ...interface{}) { - if logger.Level >= PanicLevel { - NewEntry(logger).Panicf(format, args...) - } -} - -func (logger *Logger) Debug(args ...interface{}) { - if logger.Level >= DebugLevel { - NewEntry(logger).Debug(args...) - } -} - -func (logger *Logger) Info(args ...interface{}) { - if logger.Level >= InfoLevel { - NewEntry(logger).Info(args...) - } -} - -func (logger *Logger) Print(args ...interface{}) { - NewEntry(logger).Info(args...) -} - -func (logger *Logger) Warn(args ...interface{}) { - if logger.Level >= WarnLevel { - NewEntry(logger).Warn(args...) - } -} - -func (logger *Logger) Warning(args ...interface{}) { - if logger.Level >= WarnLevel { - NewEntry(logger).Warn(args...) - } -} - -func (logger *Logger) Error(args ...interface{}) { - if logger.Level >= ErrorLevel { - NewEntry(logger).Error(args...) - } -} - -func (logger *Logger) Fatal(args ...interface{}) { - if logger.Level >= FatalLevel { - NewEntry(logger).Fatal(args...) - } - os.Exit(1) -} - -func (logger *Logger) Panic(args ...interface{}) { - if logger.Level >= PanicLevel { - NewEntry(logger).Panic(args...) - } -} - -func (logger *Logger) Debugln(args ...interface{}) { - if logger.Level >= DebugLevel { - NewEntry(logger).Debugln(args...) - } -} - -func (logger *Logger) Infoln(args ...interface{}) { - if logger.Level >= InfoLevel { - NewEntry(logger).Infoln(args...) - } -} - -func (logger *Logger) Println(args ...interface{}) { - NewEntry(logger).Println(args...) -} - -func (logger *Logger) Warnln(args ...interface{}) { - if logger.Level >= WarnLevel { - NewEntry(logger).Warnln(args...) - } -} - -func (logger *Logger) Warningln(args ...interface{}) { - if logger.Level >= WarnLevel { - NewEntry(logger).Warnln(args...) - } -} - -func (logger *Logger) Errorln(args ...interface{}) { - if logger.Level >= ErrorLevel { - NewEntry(logger).Errorln(args...) - } -} - -func (logger *Logger) Fatalln(args ...interface{}) { - if logger.Level >= FatalLevel { - NewEntry(logger).Fatalln(args...) - } - os.Exit(1) -} - -func (logger *Logger) Panicln(args ...interface{}) { - if logger.Level >= PanicLevel { - NewEntry(logger).Panicln(args...) - } -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/logrus.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/logrus.go deleted file mode 100644 index 0c09fbc26..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/logrus.go +++ /dev/null @@ -1,98 +0,0 @@ -package logrus - -import ( - "fmt" - "log" -) - -// Fields type, used to pass to `WithFields`. -type Fields map[string]interface{} - -// Level type -type Level uint8 - -// Convert the Level to a string. E.g. PanicLevel becomes "panic". -func (level Level) String() string { - switch level { - case DebugLevel: - return "debug" - case InfoLevel: - return "info" - case WarnLevel: - return "warning" - case ErrorLevel: - return "error" - case FatalLevel: - return "fatal" - case PanicLevel: - return "panic" - } - - return "unknown" -} - -// ParseLevel takes a string level and returns the Logrus log level constant. -func ParseLevel(lvl string) (Level, error) { - switch lvl { - case "panic": - return PanicLevel, nil - case "fatal": - return FatalLevel, nil - case "error": - return ErrorLevel, nil - case "warn", "warning": - return WarnLevel, nil - case "info": - return InfoLevel, nil - case "debug": - return DebugLevel, nil - } - - var l Level - return l, fmt.Errorf("not a valid logrus Level: %q", lvl) -} - -// These are the different logging levels. You can set the logging level to log -// on your instance of logger, obtained with `logrus.New()`. -const ( - // PanicLevel level, highest level of severity. Logs and then calls panic with the - // message passed to Debug, Info, ... - PanicLevel Level = iota - // FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the - // logging level is set to Panic. - FatalLevel - // ErrorLevel level. Logs. Used for errors that should definitely be noted. - // Commonly used for hooks to send errors to an error tracking service. - ErrorLevel - // WarnLevel level. Non-critical entries that deserve eyes. - WarnLevel - // InfoLevel level. General operational entries about what's going on inside the - // application. - InfoLevel - // DebugLevel level. Usually only enabled when debugging. Very verbose logging. - DebugLevel -) - -// Won't compile if StdLogger can't be realized by a log.Logger -var ( - _ StdLogger = &log.Logger{} - _ StdLogger = &Entry{} - _ StdLogger = &Logger{} -) - -// StdLogger is what your logrus-enabled library should take, that way -// it'll accept a stdlib logger and a logrus logger. There's no standard -// interface, this is the closest we get, unfortunately. -type StdLogger interface { - Print(...interface{}) - Printf(string, ...interface{}) - Println(...interface{}) - - Fatal(...interface{}) - Fatalf(string, ...interface{}) - Fatalln(...interface{}) - - Panic(...interface{}) - Panicf(string, ...interface{}) - Panicln(...interface{}) -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_bsd.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_bsd.go deleted file mode 100644 index 71f8d67a5..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_bsd.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build darwin freebsd openbsd netbsd dragonfly - -package logrus - -import "syscall" - -const ioctlReadTermios = syscall.TIOCGETA - -type Termios syscall.Termios diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_linux.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_linux.go deleted file mode 100644 index a2c0b40db..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_linux.go +++ /dev/null @@ -1,12 +0,0 @@ -// Based on ssh/terminal: -// Copyright 2013 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 logrus - -import "syscall" - -const ioctlReadTermios = syscall.TCGETS - -type Termios syscall.Termios diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go deleted file mode 100644 index 4bb537602..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go +++ /dev/null @@ -1,21 +0,0 @@ -// Based on ssh/terminal: -// Copyright 2011 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. - -// +build linux darwin freebsd openbsd netbsd dragonfly - -package logrus - -import ( - "syscall" - "unsafe" -) - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal() bool { - fd := syscall.Stdout - var termios Termios - _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) - return err == 0 -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_windows.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_windows.go deleted file mode 100644 index 2e09f6f7e..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/terminal_windows.go +++ /dev/null @@ -1,27 +0,0 @@ -// Based on ssh/terminal: -// Copyright 2011 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. - -// +build windows - -package logrus - -import ( - "syscall" - "unsafe" -) - -var kernel32 = syscall.NewLazyDLL("kernel32.dll") - -var ( - procGetConsoleMode = kernel32.NewProc("GetConsoleMode") -) - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal() bool { - fd := syscall.Stdout - var st uint32 - r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) - return r != 0 && e == 0 -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/text_formatter.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/text_formatter.go deleted file mode 100644 index 17cc29848..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/text_formatter.go +++ /dev/null @@ -1,159 +0,0 @@ -package logrus - -import ( - "bytes" - "fmt" - "runtime" - "sort" - "strings" - "time" -) - -const ( - nocolor = 0 - red = 31 - green = 32 - yellow = 33 - blue = 34 - gray = 37 -) - -var ( - baseTimestamp time.Time - isTerminal bool -) - -func init() { - baseTimestamp = time.Now() - isTerminal = IsTerminal() -} - -func miniTS() int { - return int(time.Since(baseTimestamp) / time.Second) -} - -type TextFormatter struct { - // Set to true to bypass checking for a TTY before outputting colors. - ForceColors bool - - // Force disabling colors. - DisableColors bool - - // Disable timestamp logging. useful when output is redirected to logging - // system that already adds timestamps. - DisableTimestamp bool - - // Enable logging the full timestamp when a TTY is attached instead of just - // the time passed since beginning of execution. - FullTimestamp bool - - // TimestampFormat to use for display when a full timestamp is printed - TimestampFormat string - - // The fields are sorted by default for a consistent output. For applications - // that log extremely frequently and don't use the JSON formatter this may not - // be desired. - DisableSorting bool -} - -func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { - var keys []string = make([]string, 0, len(entry.Data)) - for k := range entry.Data { - keys = append(keys, k) - } - - if !f.DisableSorting { - sort.Strings(keys) - } - - b := &bytes.Buffer{} - - prefixFieldClashes(entry.Data) - - isColorTerminal := isTerminal && (runtime.GOOS != "windows") - isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors - - timestampFormat := f.TimestampFormat - if timestampFormat == "" { - timestampFormat = DefaultTimestampFormat - } - if isColored { - f.printColored(b, entry, keys, timestampFormat) - } else { - if !f.DisableTimestamp { - f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat)) - } - f.appendKeyValue(b, "level", entry.Level.String()) - f.appendKeyValue(b, "msg", entry.Message) - for _, key := range keys { - f.appendKeyValue(b, key, entry.Data[key]) - } - } - - b.WriteByte('\n') - return b.Bytes(), nil -} - -func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) { - var levelColor int - switch entry.Level { - case DebugLevel: - levelColor = gray - case WarnLevel: - levelColor = yellow - case ErrorLevel, FatalLevel, PanicLevel: - levelColor = red - default: - levelColor = blue - } - - levelText := strings.ToUpper(entry.Level.String())[0:4] - - if !f.FullTimestamp { - fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message) - } else { - fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message) - } - for _, k := range keys { - v := entry.Data[k] - fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%+v", levelColor, k, v) - } -} - -func needsQuoting(text string) bool { - for _, ch := range text { - if !((ch >= 'a' && ch <= 'z') || - (ch >= 'A' && ch <= 'Z') || - (ch >= '0' && ch <= '9') || - ch == '-' || ch == '.') { - return false - } - } - return true -} - -func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) { - - b.WriteString(key) - b.WriteByte('=') - - switch value := value.(type) { - case string: - if needsQuoting(value) { - b.WriteString(value) - } else { - fmt.Fprintf(b, "%q", value) - } - case error: - errmsg := value.Error() - if needsQuoting(errmsg) { - b.WriteString(errmsg) - } else { - fmt.Fprintf(b, "%q", value) - } - default: - fmt.Fprint(b, value) - } - - b.WriteByte(' ') -} diff --git a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/writer.go b/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/writer.go deleted file mode 100644 index 1e30b1c75..000000000 --- a/alpine/packages/proxy/vendor/github.com/Sirupsen/logrus/writer.go +++ /dev/null @@ -1,31 +0,0 @@ -package logrus - -import ( - "bufio" - "io" - "runtime" -) - -func (logger *Logger) Writer() *io.PipeWriter { - reader, writer := io.Pipe() - - go logger.writerScanner(reader) - runtime.SetFinalizer(writer, writerFinalizer) - - return writer -} - -func (logger *Logger) writerScanner(reader *io.PipeReader) { - scanner := bufio.NewScanner(reader) - for scanner.Scan() { - logger.Print(scanner.Text()) - } - if err := scanner.Err(); err != nil { - logger.Errorf("Error while reading from Writer: %s", err) - } - reader.Close() -} - -func writerFinalizer(writer *io.PipeWriter) { - writer.Close() -} diff --git a/alpine/packages/proxy/vendor/github.com/djs55/vsock/vsock.go b/alpine/packages/proxy/vendor/github.com/djs55/vsock/vsock.go deleted file mode 100644 index f8c38e00a..000000000 --- a/alpine/packages/proxy/vendor/github.com/djs55/vsock/vsock.go +++ /dev/null @@ -1,171 +0,0 @@ -package vsock - -import ( - "errors" - "fmt" - "net" - "os" - "syscall" - "time" -) - -/* No way to teach net or syscall about vsock sockaddr, so go right to C */ - -/* -#include - -struct sockaddr_vm { - sa_family_t svm_family; - unsigned short svm_reserved1; - unsigned int svm_port; - unsigned int svm_cid; - unsigned char svm_zero[sizeof(struct sockaddr) - - sizeof(sa_family_t) - sizeof(unsigned short) - - sizeof(unsigned int) - sizeof(unsigned int)]; -}; - -int bind_sockaddr_vm(int fd, const struct sockaddr_vm *sa_vm) { - return bind(fd, (const struct sockaddr*)sa_vm, sizeof(*sa_vm)); -} -int connect_sockaddr_vm(int fd, const struct sockaddr_vm *sa_vm) { - return connect(fd, (const struct sockaddr*)sa_vm, sizeof(*sa_vm)); -} -int accept_vm(int fd, struct sockaddr_vm *sa_vm, socklen_t *sa_vm_len) { - return accept4(fd, (struct sockaddr *)sa_vm, sa_vm_len, 0); -} -*/ -import "C" - -const ( - AF_VSOCK = 40 - VSOCK_CID_ANY = 4294967295 /* 2^32-1 */ - VSOCK_CID_SELF = 3 -) - -// Listen returns a net.Listener which can accept connections on the given -// vhan port. -func Listen(port uint) (net.Listener, error) { - accept_fd, err := syscall.Socket(AF_VSOCK, syscall.SOCK_STREAM, 0) - if err != nil { - return nil, err - } - - sa := C.struct_sockaddr_vm{} - sa.svm_family = AF_VSOCK - sa.svm_port = C.uint(port) - sa.svm_cid = VSOCK_CID_ANY - - if ret := C.bind_sockaddr_vm(C.int(accept_fd), &sa); ret != 0 { - return nil, errors.New(fmt.Sprintf("failed bind vsock connection to %08x.%08x, returned %d", sa.svm_cid, sa.svm_port, ret)) - } - - err = syscall.Listen(accept_fd, syscall.SOMAXCONN) - if err != nil { - return nil, err - } - return &vsockListener{accept_fd, port}, nil -} - -// Conn is a vsock connection which support half-close. -type Conn interface { - net.Conn - CloseRead() error - CloseWrite() error -} - -type vsockListener struct { - accept_fd int - port uint -} - -func (v *vsockListener) Accept() (net.Conn, error) { - var accept_sa C.struct_sockaddr_vm - var accept_sa_len C.socklen_t - - accept_sa_len = C.sizeof_struct_sockaddr_vm - fd, err := C.accept_vm(C.int(v.accept_fd), &accept_sa, &accept_sa_len) - if err != nil { - return nil, err - } - return newVsockConn(uintptr(fd), v.port) -} - -func (v *vsockListener) Close() error { - // Note this won't cause the Accept to unblock. - return syscall.Close(v.accept_fd) -} - -type VsockAddr struct { - Port uint -} - -func (a VsockAddr) Network() string { - return "vsock" -} - -func (a VsockAddr) String() string { - return fmt.Sprintf("%08x", a.Port) -} - -func (v *vsockListener) Addr() net.Addr { - return VsockAddr{Port: v.port} -} - -// a wrapper around FileConn which supports CloseRead and CloseWrite -type vsockConn struct { - vsock *os.File - fd uintptr - local VsockAddr - remote VsockAddr -} - -type VsockConn struct { - vsockConn -} - -func newVsockConn(fd uintptr, localPort uint) (*VsockConn, error) { - vsock := os.NewFile(fd, fmt.Sprintf("vsock:%d", fd)) - local := VsockAddr{Port: localPort} - remote := VsockAddr{Port: uint(0)} // FIXME - return &VsockConn{vsockConn{vsock: vsock, fd: fd, local: local, remote: remote}}, nil -} - -func (v *VsockConn) LocalAddr() net.Addr { - return v.local -} - -func (v *VsockConn) RemoteAddr() net.Addr { - return v.remote -} - -func (v *VsockConn) CloseRead() error { - return syscall.Shutdown(int(v.fd), syscall.SHUT_RD) -} - -func (v *VsockConn) CloseWrite() error { - return syscall.Shutdown(int(v.fd), syscall.SHUT_WR) -} - -func (v *VsockConn) Close() error { - return v.vsock.Close() -} - -func (v *VsockConn) Read(buf []byte) (int, error) { - return v.vsock.Read(buf) -} - -func (v *VsockConn) Write(buf []byte) (int, error) { - return v.vsock.Write(buf) -} - -func (v *VsockConn) SetDeadline(t time.Time) error { - return nil // FIXME -} - -func (v *VsockConn) SetReadDeadline(t time.Time) error { - return nil // FIXME -} - -func (v *VsockConn) SetWriteDeadline(t time.Time) error { - return nil // FIXME -} diff --git a/alpine/packages/proxy/vendor/manifest b/alpine/packages/proxy/vendor/manifest deleted file mode 100644 index 27f87a766..000000000 --- a/alpine/packages/proxy/vendor/manifest +++ /dev/null @@ -1,13 +0,0 @@ -{ - "version": 0, - "dependencies": [ - { - "importpath": "github.com/djs55/vsock", - "repository": "ssh://github.com/djs55/vsock", - "vcs": "git", - "revision": "7ea787de194e9a251ea746cf37f464c1e6cb822a", - "branch": "master", - "notests": true - } - ] -} \ No newline at end of file From ebb5604d71e325255571a942c48596da999276db Mon Sep 17 00:00:00 2001 From: Rolf Neugebauer Date: Tue, 17 May 2016 19:10:41 +0100 Subject: [PATCH 5/5] vsudd: use vendor'ed hvsock/vsock modules Signed-off-by: Rolf Neugebauer --- alpine/packages/vsudd/.gitignore | 1 + alpine/packages/vsudd/Makefile | 9 +- alpine/packages/vsudd/main.go | 219 +++++++------------------------ 3 files changed, 52 insertions(+), 177 deletions(-) diff --git a/alpine/packages/vsudd/.gitignore b/alpine/packages/vsudd/.gitignore index e4461fbd4..50802866b 100644 --- a/alpine/packages/vsudd/.gitignore +++ b/alpine/packages/vsudd/.gitignore @@ -1 +1,2 @@ /vsudd +/vendor \ No newline at end of file diff --git a/alpine/packages/vsudd/Makefile b/alpine/packages/vsudd/Makefile index 43c2ecb95..2a205ed97 100644 --- a/alpine/packages/vsudd/Makefile +++ b/alpine/packages/vsudd/Makefile @@ -1,10 +1,15 @@ all: vsudd -vsudd: Dockerfile main.go +.PHONY: vendor +vendor: + mkdir -p ./vendor + cp -r ../go/vendor/* ./vendor/ + +vsudd: Dockerfile main.go vendor docker build --build-arg GOOS=$(OS) --build-arg GOARCH=$(ARCH) -t vsudd:build . docker run --rm vsudd:build cat /go/bin/vsudd > vsudd chmod 755 vsudd clean: - rm -f vsudd + rm -rf vsudd vendor docker images -q vsudd:build | xargs docker rmi -f diff --git a/alpine/packages/vsudd/main.go b/alpine/packages/vsudd/main.go index f67450623..6e039e851 100644 --- a/alpine/packages/vsudd/main.go +++ b/alpine/packages/vsudd/main.go @@ -2,7 +2,6 @@ package main import ( "flag" - "fmt" "io" "log" "net" @@ -11,59 +10,24 @@ import ( "strings" "syscall" "time" -) -/* No way to teach net or syscall about vsock sockaddr, so go right to C */ - -/* -#include -#include -#include "include/uapi/linux/vm_sockets.h" -int bind_sockaddr_vm(int fd, const struct sockaddr_vm *sa_vm) { - return bind(fd, (const struct sockaddr*)sa_vm, sizeof(*sa_vm)); -} -int connect_sockaddr_vm(int fd, const struct sockaddr_vm *sa_vm) { - return connect(fd, (const struct sockaddr*)sa_vm, sizeof(*sa_vm)); -} -int accept_vm(int fd, struct sockaddr_vm *sa_vm, socklen_t *sa_vm_len) { - return accept4(fd, (struct sockaddr *)sa_vm, sa_vm_len, 0); -} - -struct sockaddr_hv { - unsigned short shv_family; - unsigned short reserved; - unsigned char shv_vm_id[16]; - unsigned char shv_service_id[16]; -}; -int bind_sockaddr_hv(int fd, const struct sockaddr_hv *sa_hv) { - return bind(fd, (const struct sockaddr*)sa_hv, sizeof(*sa_hv)); -} -int connect_sockaddr_hv(int fd, const struct sockaddr_hv *sa_hv) { - return connect(fd, (const struct sockaddr*)sa_hv, sizeof(*sa_hv)); -} -int accept_hv(int fd, struct sockaddr_hv *sa_hv, socklen_t *sa_hv_len) { - return accept4(fd, (struct sockaddr *)sa_hv, sa_hv_len, 0); -} -*/ -import "C" - -type GUID [16]byte - -const ( - AF_VSOCK = 40 - VSOCK_CID_ANY = 4294967295 /* 2^32-1 */ - - AF_HYPERV = 42 - SHV_PROTO_RAW = 1 + "github.com/rneugeba/virtsock/go/hvsock" + "github.com/rneugeba/virtsock/go/vsock" ) var ( - portstr string - sock string - detach bool - SHV_VMID_GUEST = GUID{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + portstr string + sock string + detach bool + useHVsock bool ) +type vConn interface { + net.Conn + CloseRead() error + CloseWrite() error +} + func init() { flag.StringVar(&portstr, "port", "2376", "vsock port to forward") flag.StringVar(&sock, "sock", "/var/run/docker.sock", "path of the local Unix domain socket to forward to") @@ -90,118 +54,53 @@ func main() { syscall.Dup2(int(fd), int(os.Stderr.Fd())) } + var l net.Listener if strings.Contains(portstr, "-") { - guid, err := guidFromString(portstr) + svcid, err := hvsock.GuidFromString(portstr) if err != nil { log.Fatalln("Failed to parse GUID", portstr, err) } - hvsockListen(guid) + l, err = hvsock.Listen(hvsock.HypervAddr{VmId: hvsock.GUID_WILDCARD, ServiceId: svcid}) + if err != nil { + log.Fatalf("Failed to bind to hvsock port: %#v", err) + } + log.Printf("Listening on ServiceId %s", svcid) + useHVsock = true } else { port, err := strconv.ParseUint(portstr, 10, 32) if err != nil { log.Fatalln("Can't convert %s to a uint.", portstr, err) } - vsockListen(uint(port)) + l, err = vsock.Listen(uint(port)) + if err != nil { + log.Fatalf("Failed to bind to vsock port %u: %#v", port, err) + } + log.Printf("Listening on port %u", port) + useHVsock = false } -} - -func hvsockListen(port GUID) { - accept_fd, err := syscall.Socket(AF_HYPERV, syscall.SOCK_STREAM, SHV_PROTO_RAW) - if err != nil { - log.Fatal(err) - } - - sa := C.struct_sockaddr_hv{} - sa.shv_family = AF_HYPERV - sa.reserved = 0 - /* TODO: Turn this into a function */ - for i := 0; i < 16; i++ { - sa.shv_vm_id[i] = C.uchar(SHV_VMID_GUEST[i]) - } - for i := 0; i < 16; i++ { - sa.shv_service_id[i] = C.uchar(port[i]) - } - - if ret := C.bind_sockaddr_hv(C.int(accept_fd), &sa); ret != 0 { - log.Fatal(fmt.Sprintf("failed bind hvsock connection to %s.%s, returned %d", - SHV_VMID_GUEST.toString(), port.toString(), ret)) - } - - err = syscall.Listen(accept_fd, syscall.SOMAXCONN) - if err != nil { - log.Fatalln("Failed to listen to VSOCK", err) - } - - log.Printf("Listening on fd %d", accept_fd) connid := 0 - for { - var accept_sa C.struct_sockaddr_hv - var accept_sa_len C.socklen_t - connid++ - accept_sa_len = C.sizeof_struct_sockaddr_hv - fd, err := C.accept_hv(C.int(accept_fd), &accept_sa, &accept_sa_len) + conn, err := l.Accept() if err != nil { - log.Fatalln("Error accepting connection", err) + log.Printf("Error accepting connection: %#v", err) + return // no more listening } + log.Printf("Connection %d from: %s\n", connid, conn.RemoteAddr()) - accept_vm_id := guidFromC(accept_sa.shv_vm_id) - accept_svc_id := guidFromC(accept_sa.shv_service_id) - log.Printf("%d Accepted connection on fd %d from %s.%s", - connid, fd, accept_vm_id.toString(), accept_svc_id.toString()) - go handleOne(connid, int(fd)) + go handleOne(connid, conn.(vConn)) } } -func vsockListen(port uint) { - accept_fd, err := syscall.Socket(AF_VSOCK, syscall.SOCK_STREAM, 0) - if err != nil { - log.Fatal(err) - } - - sa := C.struct_sockaddr_vm{} - sa.svm_family = AF_VSOCK - sa.svm_port = C.uint(port) - sa.svm_cid = VSOCK_CID_ANY - - if ret := C.bind_sockaddr_vm(C.int(accept_fd), &sa); ret != 0 { - log.Fatal(fmt.Sprintf("failed bind vsock connection to %08x.%08x, returned %d", - sa.svm_cid, sa.svm_port, ret)) - } - - err = syscall.Listen(accept_fd, syscall.SOMAXCONN) - if err != nil { - log.Fatalln("Failed to listen to VSOCK", err) - } - - log.Printf("Listening on fd %d", accept_fd) - - connid := 0 - - for { - var accept_sa C.struct_sockaddr_vm - var accept_sa_len C.socklen_t - - connid++ - accept_sa_len = C.sizeof_struct_sockaddr_vm - fd, err := C.accept_vm(C.int(accept_fd), &accept_sa, &accept_sa_len) - if err != nil { - log.Fatalln("Error accepting connection", err) - } - log.Printf("%d Accepted connection on fd %d from %08x.%08x", - connid, fd, uint(accept_sa.svm_cid), uint(accept_sa.svm_port)) - go handleOne(connid, int(fd)) - } -} - -func handleOne(connid int, fd int) { - vsock := os.NewFile(uintptr(fd), fmt.Sprintf("vsock:%d", fd)) - +func handleOne(connid int, conn vConn) { defer func() { - if err := vsock.Close(); err != nil { - log.Println(connid, "Error closing", vsock, ":", err) + if err := conn.Close(); err != nil { + // On windows we get an EINVAL when the other end already closed + // Don't bother spilling this into the logs + if !(useHVsock && err == syscall.EINVAL) { + log.Println(connid, "Error closing", conn, ":", err) + } } }() @@ -229,7 +128,7 @@ func handleOne(connid int, fd int) { w := make(chan int64) go func() { - n, err := io.Copy(vsock, docker) + n, err := io.Copy(conn, docker) if err != nil { log.Println(connid, "error copying from docker to vsock:", err) } @@ -238,14 +137,14 @@ func handleOne(connid int, fd int) { if err != nil { log.Println(connid, "error CloseRead on docker socket:", err) } - err = syscall.Shutdown(fd, syscall.SHUT_WR) + err = conn.CloseWrite() if err != nil { - log.Println(connid, "error SHUT_WR on vsock:", err) + log.Println(connid, "error CloseWrite on vsock:", err) } w <- n }() - n, err := io.Copy(docker, vsock) + n, err := io.Copy(docker, conn) if err != nil { log.Println(connid, "error copying from vsock to docker:", err) } @@ -255,41 +154,11 @@ func handleOne(connid int, fd int) { if err != nil { log.Println(connid, "error CloseWrite on docker socket:", err) } - err = syscall.Shutdown(fd, syscall.SHUT_RD) + err = conn.CloseRead() if err != nil { - log.Println(connid, "error SHUT_RD on vsock:", err) + log.Println(connid, "error CloseRead on vsock:", err) } totalWritten := <-w log.Println(connid, "Done. read:", totalRead, "written:", totalWritten) } - -func (g *GUID) toString() string { - /* XXX This assume little endian */ - return fmt.Sprintf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - g[3], g[2], g[1], g[0], - g[5], g[4], - g[7], g[6], - g[8], g[9], - g[10], g[11], g[12], g[13], g[14], g[15]) -} - -func guidFromString(s string) (GUID, error) { - var g GUID - var err error - _, err = fmt.Sscanf(s, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - &g[3], &g[2], &g[1], &g[0], - &g[5], &g[4], - &g[7], &g[6], - &g[8], &g[9], - &g[10], &g[11], &g[12], &g[13], &g[14], &g[15]) - return g, err -} - -func guidFromC(cg [16]C.uchar) GUID { - var g GUID - for i := 0; i < 16; i++ { - g[i] = byte(cg[i]) - } - return g -}