From 8f0b44b8a436c332d8ca8199e5de05da189c17c7 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Fri, 2 Feb 2018 19:15:28 -0700 Subject: [PATCH] Create diagnostics package; persist UUID --- caddy/caddymain/run.go | 57 ++++++++++++++++++++--- diagnostics/diagnostics.go | 25 ++++++++++ vendor/github.com/google/uuid/hash.go | 2 +- vendor/github.com/google/uuid/node.go | 31 ++++-------- vendor/github.com/google/uuid/node_js.go | 12 +++++ vendor/github.com/google/uuid/node_net.go | 33 +++++++++++++ vendor/github.com/google/uuid/time.go | 6 +-- vendor/github.com/google/uuid/uuid.go | 19 +++++--- vendor/github.com/google/uuid/version4.go | 2 +- vendor/manifest | 2 +- 10 files changed, 148 insertions(+), 41 deletions(-) create mode 100644 diagnostics/diagnostics.go create mode 100644 vendor/github.com/google/uuid/node_js.go create mode 100644 vendor/github.com/google/uuid/node_net.go diff --git a/caddy/caddymain/run.go b/caddy/caddymain/run.go index e6faa0513..f1415b820 100644 --- a/caddy/caddymain/run.go +++ b/caddy/caddymain/run.go @@ -21,19 +21,19 @@ import ( "io/ioutil" "log" "os" + "path/filepath" "runtime" "strconv" "strings" + "github.com/google/uuid" + "github.com/mholt/caddy" + "github.com/mholt/caddy/caddytls" + "github.com/mholt/caddy/diagnostics" + "github.com/xenolf/lego/acme" "gopkg.in/natefinch/lumberjack.v2" - "github.com/xenolf/lego/acme" - - "github.com/mholt/caddy" - // plug in the HTTP server type - _ "github.com/mholt/caddy/caddyhttp" - - "github.com/mholt/caddy/caddytls" + _ "github.com/mholt/caddy/caddyhttp" // plug in the HTTP server type // This is where other plugins get plugged in (imported) ) @@ -87,6 +87,9 @@ func Run() { }) } + // initialize diagnostics client + initDiagnostics() + // Check for one-time actions if revoke != "" { err := caddytls.Revoke(revoke) @@ -266,6 +269,46 @@ func setCPU(cpu string) error { return nil } +// initDiagnostics initializes the diagnostics engine. +func initDiagnostics() { + uuidFilename := filepath.Join(caddy.AssetsPath(), "uuid") + + newUUID := func() uuid.UUID { + id := uuid.New() + err := ioutil.WriteFile(uuidFilename, id[:], 0644) + if err != nil { + log.Printf("[ERROR] Persisting instance UUID: %v", err) + } + return id + } + + var id uuid.UUID + + // load UUID from storage, or create one if we don't have one + if uuidFile, err := os.Open(uuidFilename); os.IsNotExist(err) { + // no UUID exists yet; create a new one and persist it + id = newUUID() + } else if err != nil { + log.Printf("[ERROR] Loading persistent UUID: %v", err) + id = newUUID() + } else { + defer uuidFile.Close() + uuidBytes, err := ioutil.ReadAll(uuidFile) + if err != nil { + log.Printf("[ERROR] Reading persistent UUID: %v", err) + id = newUUID() + } else { + id, err = uuid.FromBytes(uuidBytes) + if err != nil { + log.Printf("[ERROR] Parsing UUID: %v", err) + id = newUUID() + } + } + } + + diagnostics.Init(id) +} + const appName = "Caddy" // Flags that control program flow or startup diff --git a/diagnostics/diagnostics.go b/diagnostics/diagnostics.go new file mode 100644 index 000000000..a1d050d4b --- /dev/null +++ b/diagnostics/diagnostics.go @@ -0,0 +1,25 @@ +// Copyright 2015 Light Code Labs, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package diagnostics + +import ( + "github.com/google/uuid" +) + +func Init(uuid uuid.UUID) { + instanceUUID = uuid +} + +var instanceUUID uuid.UUID diff --git a/vendor/github.com/google/uuid/hash.go b/vendor/github.com/google/uuid/hash.go index 4fc5a77df..b17461631 100644 --- a/vendor/github.com/google/uuid/hash.go +++ b/vendor/github.com/google/uuid/hash.go @@ -27,7 +27,7 @@ var ( func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { h.Reset() h.Write(space[:]) - h.Write([]byte(data)) + h.Write(data) s := h.Sum(nil) var uuid UUID copy(uuid[:], s) diff --git a/vendor/github.com/google/uuid/node.go b/vendor/github.com/google/uuid/node.go index 5f0156a2e..384f07d02 100644 --- a/vendor/github.com/google/uuid/node.go +++ b/vendor/github.com/google/uuid/node.go @@ -5,16 +5,14 @@ package uuid import ( - "net" "sync" ) var ( - nodeMu sync.Mutex - interfaces []net.Interface // cached list of interfaces - ifname string // name of interface being used - nodeID [6]byte // hardware for version 1 UUIDs - zeroID [6]byte // nodeID with only 0's + nodeMu sync.Mutex + ifname string // name of interface being used + nodeID [6]byte // hardware for version 1 UUIDs + zeroID [6]byte // nodeID with only 0's ) // NodeInterface returns the name of the interface from which the NodeID was @@ -39,20 +37,12 @@ func SetNodeInterface(name string) bool { } func setNodeInterface(name string) bool { - if interfaces == nil { - var err error - interfaces, err = net.Interfaces() - if err != nil && name != "" { - return false - } - } - for _, ifs := range interfaces { - if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) { - copy(nodeID[:], ifs.HardwareAddr) - ifname = ifs.Name - return true - } + iname, addr := getHardwareInterface(name) // null implementation for js + if iname != "" && addr != nil { + ifname = iname + copy(nodeID[:], addr) + return true } // We found no interfaces with a valid hardware address. If name @@ -94,9 +84,6 @@ func SetNodeID(id []byte) bool { // NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is // not valid. The NodeID is only well defined for version 1 and 2 UUIDs. func (uuid UUID) NodeID() []byte { - if len(uuid) != 16 { - return nil - } var node [6]byte copy(node[:], uuid[10:]) return node[:] diff --git a/vendor/github.com/google/uuid/node_js.go b/vendor/github.com/google/uuid/node_js.go new file mode 100644 index 000000000..24b78edc9 --- /dev/null +++ b/vendor/github.com/google/uuid/node_js.go @@ -0,0 +1,12 @@ +// Copyright 2017 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build js + +package uuid + +// getHardwareInterface returns nil values for the JS version of the code. +// This remvoves the "net" dependency, because it is not used in the browser. +// Using the "net" library inflates the size of the transpiled JS code by 673k bytes. +func getHardwareInterface(name string) (string, []byte) { return "", nil } diff --git a/vendor/github.com/google/uuid/node_net.go b/vendor/github.com/google/uuid/node_net.go new file mode 100644 index 000000000..0cbbcddbd --- /dev/null +++ b/vendor/github.com/google/uuid/node_net.go @@ -0,0 +1,33 @@ +// Copyright 2017 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !js + +package uuid + +import "net" + +var interfaces []net.Interface // cached list of interfaces + +// getHardwareInterface returns the name and hardware address of interface name. +// If name is "" then the name and hardware address of one of the system's +// interfaces is returned. If no interfaces are found (name does not exist or +// there are no interfaces) then "", nil is returned. +// +// Only addresses of at least 6 bytes are returned. +func getHardwareInterface(name string) (string, []byte) { + if interfaces == nil { + var err error + interfaces, err = net.Interfaces() + if err != nil { + return "", nil + } + } + for _, ifs := range interfaces { + if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) { + return ifs.Name, ifs.HardwareAddr + } + } + return "", nil +} diff --git a/vendor/github.com/google/uuid/time.go b/vendor/github.com/google/uuid/time.go index fd7fe0ac4..e6ef06cdc 100644 --- a/vendor/github.com/google/uuid/time.go +++ b/vendor/github.com/google/uuid/time.go @@ -86,7 +86,7 @@ func clockSequence() int { return int(clockSeq & 0x3fff) } -// SetClockSeq sets the clock sequence to the lower 14 bits of seq. Setting to +// SetClockSequence sets the clock sequence to the lower 14 bits of seq. Setting to // -1 causes a new sequence to be generated. func SetClockSequence(seq int) { defer timeMu.Unlock() @@ -100,9 +100,9 @@ func setClockSequence(seq int) { randomBits(b[:]) // clock sequence seq = int(b[0])<<8 | int(b[1]) } - old_seq := clockSeq + oldSeq := clockSeq clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant - if old_seq != clockSeq { + if oldSeq != clockSeq { lasttime = 0 } } diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go index 23161a86c..7f3643fe9 100644 --- a/vendor/github.com/google/uuid/uuid.go +++ b/vendor/github.com/google/uuid/uuid.go @@ -58,11 +58,11 @@ func Parse(s string) (UUID, error) { 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} { - if v, ok := xtob(s[x], s[x+1]); !ok { + v, ok := xtob(s[x], s[x+1]) + if !ok { return uuid, errors.New("invalid UUID format") - } else { - uuid[i] = v } + uuid[i] = v } return uuid, nil } @@ -88,15 +88,22 @@ func ParseBytes(b []byte) (UUID, error) { 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} { - if v, ok := xtob(b[x], b[x+1]); !ok { + v, ok := xtob(b[x], b[x+1]) + if !ok { return uuid, errors.New("invalid UUID format") - } else { - uuid[i] = v } + uuid[i] = v } return uuid, nil } +// FromBytes creates a new UUID from a byte slice. Returns an error if the slice +// does not have a length of 16. The bytes are copied from the slice. +func FromBytes(b []byte) (uuid UUID, err error) { + err = uuid.UnmarshalBinary(b) + return uuid, err +} + // Must returns uuid if err is nil and panics otherwise. func Must(uuid UUID, err error) UUID { if err != nil { diff --git a/vendor/github.com/google/uuid/version4.go b/vendor/github.com/google/uuid/version4.go index 74c4e6c9f..84af91c9f 100644 --- a/vendor/github.com/google/uuid/version4.go +++ b/vendor/github.com/google/uuid/version4.go @@ -14,7 +14,7 @@ func New() UUID { return Must(NewRandom()) } -// NewRandom returns a Random (Version 4) UUID or panics. +// NewRandom returns a Random (Version 4) UUID. // // The strength of the UUIDs is based on the strength of the crypto/rand // package. diff --git a/vendor/manifest b/vendor/manifest index 5f0d211c0..a44a451e6 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -80,7 +80,7 @@ "importpath": "github.com/google/uuid", "repository": "https://github.com/google/uuid", "vcs": "git", - "revision": "7e072fc3a7be179aee6d3359e46015aa8c995314", + "revision": "dec09d789f3dba190787f8b4454c7d3c936fed9e", "branch": "master", "notests": true },