/
handler.go
66 lines (54 loc) · 1.79 KB
/
handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
package syspolicy
import (
"errors"
"sync/atomic"
"testing"
)
var (
handlerUsed atomic.Bool
handler Handler = defaultHandler{}
)
// Handler reads system policies from OS-specific storage.
type Handler interface {
// ReadString reads the policy settings value string given the key.
ReadString(key string) (string, error)
// ReadUInt64 reads the policy settings uint64 value given the key.
ReadUInt64(key string) (uint64, error)
// ReadBool reads the policy setting's boolean value, given the key.
ReadBoolean(key string) (bool, error)
}
// ErrNoSuchKey is returned when the specified key does not have a value set.
var ErrNoSuchKey = errors.New("no such key")
// defaultHandler is the catch all syspolicy type for anything that isn't windows or apple.
type defaultHandler struct{}
func (defaultHandler) ReadString(_ string) (string, error) {
return "", ErrNoSuchKey
}
func (defaultHandler) ReadUInt64(_ string) (uint64, error) {
return 0, ErrNoSuchKey
}
func (defaultHandler) ReadBoolean(_ string) (bool, error) {
return false, ErrNoSuchKey
}
// markHandlerInUse is called before handler methods are called.
func markHandlerInUse() {
handlerUsed.Store(true)
}
// RegisterHandler initializes the policy handler and ensures registration will happen once.
func RegisterHandler(h Handler) {
// Technically this assignment is not concurrency safe, but in the
// event that there was any risk of a data race, we will panic due to
// the CompareAndSwap failing.
handler = h
if !handlerUsed.CompareAndSwap(false, true) {
panic("handler was already used before registration")
}
}
func SetHandlerForTest(tb testing.TB, h Handler) {
tb.Helper()
oldHandler := handler
handler = h
tb.Cleanup(func() { handler = oldHandler })
}