Commit 8f0b44b8 authored by Matthew Holt's avatar Matthew Holt

Create diagnostics package; persist UUID

parent 50ab4fe1
...@@ -21,19 +21,19 @@ import ( ...@@ -21,19 +21,19 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
"path/filepath"
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"gopkg.in/natefinch/lumberjack.v2" "github.com/google/uuid"
"github.com/xenolf/lego/acme"
"github.com/mholt/caddy" "github.com/mholt/caddy"
// plug in the HTTP server type
_ "github.com/mholt/caddy/caddyhttp"
"github.com/mholt/caddy/caddytls" "github.com/mholt/caddy/caddytls"
"github.com/mholt/caddy/diagnostics"
"github.com/xenolf/lego/acme"
"gopkg.in/natefinch/lumberjack.v2"
_ "github.com/mholt/caddy/caddyhttp" // plug in the HTTP server type
// This is where other plugins get plugged in (imported) // This is where other plugins get plugged in (imported)
) )
...@@ -87,6 +87,9 @@ func Run() { ...@@ -87,6 +87,9 @@ func Run() {
}) })
} }
// initialize diagnostics client
initDiagnostics()
// Check for one-time actions // Check for one-time actions
if revoke != "" { if revoke != "" {
err := caddytls.Revoke(revoke) err := caddytls.Revoke(revoke)
...@@ -266,6 +269,46 @@ func setCPU(cpu string) error { ...@@ -266,6 +269,46 @@ func setCPU(cpu string) error {
return nil 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" const appName = "Caddy"
// Flags that control program flow or startup // Flags that control program flow or startup
......
// 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
...@@ -27,7 +27,7 @@ var ( ...@@ -27,7 +27,7 @@ var (
func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
h.Reset() h.Reset()
h.Write(space[:]) h.Write(space[:])
h.Write([]byte(data)) h.Write(data)
s := h.Sum(nil) s := h.Sum(nil)
var uuid UUID var uuid UUID
copy(uuid[:], s) copy(uuid[:], s)
......
...@@ -5,16 +5,14 @@ ...@@ -5,16 +5,14 @@
package uuid package uuid
import ( import (
"net"
"sync" "sync"
) )
var ( var (
nodeMu sync.Mutex nodeMu sync.Mutex
interfaces []net.Interface // cached list of interfaces ifname string // name of interface being used
ifname string // name of interface being used nodeID [6]byte // hardware for version 1 UUIDs
nodeID [6]byte // hardware for version 1 UUIDs zeroID [6]byte // nodeID with only 0's
zeroID [6]byte // nodeID with only 0's
) )
// NodeInterface returns the name of the interface from which the NodeID was // NodeInterface returns the name of the interface from which the NodeID was
...@@ -39,20 +37,12 @@ func SetNodeInterface(name string) bool { ...@@ -39,20 +37,12 @@ func SetNodeInterface(name string) bool {
} }
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 { iname, addr := getHardwareInterface(name) // null implementation for js
if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) { if iname != "" && addr != nil {
copy(nodeID[:], ifs.HardwareAddr) ifname = iname
ifname = ifs.Name copy(nodeID[:], addr)
return true return true
}
} }
// We found no interfaces with a valid hardware address. If name // We found no interfaces with a valid hardware address. If name
...@@ -94,9 +84,6 @@ func SetNodeID(id []byte) bool { ...@@ -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 // 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. // not valid. The NodeID is only well defined for version 1 and 2 UUIDs.
func (uuid UUID) NodeID() []byte { func (uuid UUID) NodeID() []byte {
if len(uuid) != 16 {
return nil
}
var node [6]byte var node [6]byte
copy(node[:], uuid[10:]) copy(node[:], uuid[10:])
return node[:] return node[:]
......
// 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 }
// 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
}
...@@ -86,7 +86,7 @@ func clockSequence() int { ...@@ -86,7 +86,7 @@ func clockSequence() int {
return int(clockSeq & 0x3fff) 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. // -1 causes a new sequence to be generated.
func SetClockSequence(seq int) { func SetClockSequence(seq int) {
defer timeMu.Unlock() defer timeMu.Unlock()
...@@ -100,9 +100,9 @@ func setClockSequence(seq int) { ...@@ -100,9 +100,9 @@ func setClockSequence(seq int) {
randomBits(b[:]) // clock sequence randomBits(b[:]) // clock sequence
seq = int(b[0])<<8 | int(b[1]) seq = int(b[0])<<8 | int(b[1])
} }
old_seq := clockSeq oldSeq := clockSeq
clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant
if old_seq != clockSeq { if oldSeq != clockSeq {
lasttime = 0 lasttime = 0
} }
} }
......
...@@ -58,11 +58,11 @@ func Parse(s string) (UUID, error) { ...@@ -58,11 +58,11 @@ func Parse(s string) (UUID, error) {
14, 16, 14, 16,
19, 21, 19, 21,
24, 26, 28, 30, 32, 34} { 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") return uuid, errors.New("invalid UUID format")
} else {
uuid[i] = v
} }
uuid[i] = v
} }
return uuid, nil return uuid, nil
} }
...@@ -88,15 +88,22 @@ func ParseBytes(b []byte) (UUID, error) { ...@@ -88,15 +88,22 @@ func ParseBytes(b []byte) (UUID, error) {
14, 16, 14, 16,
19, 21, 19, 21,
24, 26, 28, 30, 32, 34} { 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") return uuid, errors.New("invalid UUID format")
} else {
uuid[i] = v
} }
uuid[i] = v
} }
return uuid, nil 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. // Must returns uuid if err is nil and panics otherwise.
func Must(uuid UUID, err error) UUID { func Must(uuid UUID, err error) UUID {
if err != nil { if err != nil {
......
...@@ -14,7 +14,7 @@ func New() UUID { ...@@ -14,7 +14,7 @@ func New() UUID {
return Must(NewRandom()) 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 // The strength of the UUIDs is based on the strength of the crypto/rand
// package. // package.
......
...@@ -80,7 +80,7 @@ ...@@ -80,7 +80,7 @@
"importpath": "github.com/google/uuid", "importpath": "github.com/google/uuid",
"repository": "https://github.com/google/uuid", "repository": "https://github.com/google/uuid",
"vcs": "git", "vcs": "git",
"revision": "7e072fc3a7be179aee6d3359e46015aa8c995314", "revision": "dec09d789f3dba190787f8b4454c7d3c936fed9e",
"branch": "master", "branch": "master",
"notests": true "notests": true
}, },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment