Migrate a bunch of stuff around to prep for worker command (#2)
Right now it's essentially a copy; it needs some updating, integration into dev, and so on.
This commit is contained in:
1 parent
c2d385d851
commit
1645c3106e
18 files changed
+1200
-157
No files matched your search
@@ -54,7 +54,7 @@ Usage: watchtower controller [options]
|
||||
|
||||
Start a controller with a configuration file:
|
||||
|
||||
$ watchtower controller -config=/etc/controller/config.hcl
|
||||
$ watchtower controller -config=/etc/watchtower/controller.hcl
|
||||
|
||||
For a full list of examples, please see the documentation.
|
||||
|
||||
@@ -147,15 +147,15 @@ func (c *Command) Run(args []string) int {
|
||||
return result
|
||||
}
|
||||
|
||||
if memProfilerEnabled {
|
||||
c.startMemProfiler()
|
||||
}
|
||||
|
||||
if err := c.SetupLogging(c.flagLogLevel, c.flagLogFormat, c.Config.LogLevel, c.Config.LogFormat); err != nil {
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
}
|
||||
|
||||
if memProfilerEnabled {
|
||||
base.StartMemProfiler(c.Logger)
|
||||
}
|
||||
|
||||
if err := c.SetupMetrics(c.UI, c.Config.Telemetry); err != nil {
|
||||
c.UI.Error(err.Error())
|
||||
return 1
|
||||
@@ -259,21 +259,21 @@ func (c *Command) ParseFlagsAndConfig(args []string) int {
|
||||
|
||||
func (c *Command) Start() int {
|
||||
// Instantiate the wait group
|
||||
controllerConfig := &controller.Config{
|
||||
conf := &controller.Config{
|
||||
RawConfig: c.Config,
|
||||
Server: c.Server,
|
||||
}
|
||||
|
||||
// Initialize the core
|
||||
controller, err := controller.New(controllerConfig)
|
||||
ctlr, err := controller.New(conf)
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error initializing controller: %w", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
if err := controller.Start(); err != nil {
|
||||
if err := ctlr.Start(); err != nil {
|
||||
c.UI.Error(fmt.Sprint("Error starting controller: %w", err))
|
||||
if err := controller.Shutdown(); err != nil {
|
||||
if err := ctlr.Shutdown(); err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error with controller shutdown: %w", err))
|
||||
}
|
||||
return 1
|
||||
@@ -287,7 +287,7 @@ func (c *Command) Start() int {
|
||||
case <-c.ShutdownCh:
|
||||
c.UI.Output("==> Watchtower controller shutdown triggered")
|
||||
|
||||
if err := controller.Shutdown(); err != nil {
|
||||
if err := ctlr.Shutdown(); err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error with controller shutdown: %w", err))
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ func (c *Command) Start() int {
|
||||
c.Logger.Error("unknown log level found on reload", "level", newConf.LogLevel)
|
||||
goto RUNRELOADFUNCS
|
||||
}
|
||||
controller.SetLogLevel(level)
|
||||
ctlr.SetLogLevel(level)
|
||||
}
|
||||
|
||||
RUNRELOADFUNCS:
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
// +build !memprofiler
|
||||
|
||||
package controller
|
||||
|
||||
func (c *Command) startMemProfiler() {
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
// +build memprofiler
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
memProfilerEnabled = true
|
||||
}
|
||||
|
||||
func (c *Command) startMemProfiler() {
|
||||
profileDir := filepath.Join(os.TempDir(), "watchtowerprof")
|
||||
if err := os.MkdirAll(profileDir, 0700); err != nil {
|
||||
c.logger.Debug("could not create profile directory", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
filename := filepath.Join(profileDir, time.Now().UTC().Format("20060102_150405")) + ".pprof"
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
c.logger.Debug("could not create memory profile", "error", err)
|
||||
}
|
||||
runtime.GC()
|
||||
if err := pprof.WriteHeapProfile(f); err != nil {
|
||||
c.logger.Debug("could not write memory profile", "error", err)
|
||||
}
|
||||
f.Close()
|
||||
c.logger.Debug("wrote memory profile", "filename", filename)
|
||||
time.Sleep(5 * time.Minute)
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
package listener
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
"github.com/pires/go-proxyproto"
|
||||
|
||||
// We must import sha512 so that it registers with the runtime so that
|
||||
// certificates that use it can be parsed.
|
||||
_ "crypto/sha512"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/hashicorp/go-alpnmux"
|
||||
"github.com/hashicorp/vault/internalshared/configutil"
|
||||
"github.com/hashicorp/vault/internalshared/reloadutil"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
// Factory is the factory function to create a listener.
|
||||
type Factory func(*configutil.Listener, io.Writer, cli.Ui) (*alpnmux.ALPNMux, map[string]string, reloadutil.ReloadFunc, error)
|
||||
|
||||
// BuiltinListeners is the list of built-in listener types.
|
||||
var BuiltinListeners = map[string]Factory{
|
||||
"tcp": tcpListenerFactory,
|
||||
}
|
||||
|
||||
// New creates a new listener of the given type with the given
|
||||
// configuration. The type is looked up in the BuiltinListeners map.
|
||||
func New(l *configutil.Listener, w io.Writer, ui cli.Ui) (*alpnmux.ALPNMux, map[string]string, reloadutil.ReloadFunc, error) {
|
||||
f, ok := BuiltinListeners[l.Type]
|
||||
if !ok {
|
||||
return nil, nil, nil, fmt.Errorf("unknown listener type: %q", l.Type)
|
||||
}
|
||||
|
||||
return f(l, w, ui)
|
||||
}
|
||||
|
||||
func listenerWrapProxy(ln net.Listener, l *configutil.Listener) (net.Listener, error) {
|
||||
behavior := l.ProxyProtocolBehavior
|
||||
if behavior == "" {
|
||||
return ln, nil
|
||||
}
|
||||
|
||||
authorizedAddrs := make([]string, 0, len(l.ProxyProtocolAuthorizedAddrs))
|
||||
for _, v := range l.ProxyProtocolAuthorizedAddrs {
|
||||
authorizedAddrs = append(authorizedAddrs, v.String())
|
||||
}
|
||||
|
||||
var policyFunc proxyproto.PolicyFunc
|
||||
|
||||
switch behavior {
|
||||
case "use_always":
|
||||
policyFunc = func(upstream net.Addr) (proxyproto.Policy, error) {
|
||||
return proxyproto.USE, nil
|
||||
}
|
||||
|
||||
case "allow_authorized":
|
||||
if len(authorizedAddrs) == 0 {
|
||||
return nil, errors.New("proxy_protocol_behavior set but no proxy_protocol_authorized_addrs value")
|
||||
}
|
||||
policyFunc = proxyproto.MustLaxWhiteListPolicy(authorizedAddrs)
|
||||
|
||||
case "deny_unauthorized":
|
||||
if len(authorizedAddrs) == 0 {
|
||||
return nil, errors.New("proxy_protocol_behavior set but no proxy_protocol_authorized_addrs value")
|
||||
}
|
||||
policyFunc = proxyproto.MustStrictWhiteListPolicy(authorizedAddrs)
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown %q value: %q", "proxy_protocol_behavior", behavior)
|
||||
}
|
||||
|
||||
proxyListener := &proxyproto.Listener{
|
||||
Listener: ln,
|
||||
Policy: policyFunc,
|
||||
}
|
||||
|
||||
return proxyListener, nil
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
package listener
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-alpnmux"
|
||||
"github.com/hashicorp/vault/internalshared/configutil"
|
||||
"github.com/hashicorp/vault/internalshared/listenerutil"
|
||||
"github.com/hashicorp/vault/internalshared/reloadutil"
|
||||
"github.com/mitchellh/cli"
|
||||
)
|
||||
|
||||
func tcpListenerFactory(l *configutil.Listener, _ io.Writer, ui cli.Ui) (*alpnmux.ALPNMux, map[string]string, reloadutil.ReloadFunc, error) {
|
||||
if l.Address == "" {
|
||||
l.Address = "127.0.0.1:9200"
|
||||
}
|
||||
|
||||
bindProto := "tcp"
|
||||
|
||||
// If they've passed 0.0.0.0, we only want to bind on IPv4
|
||||
// rather than golang's dual stack default
|
||||
if strings.HasPrefix(l.Address, "0.0.0.0:") {
|
||||
bindProto = "tcp4"
|
||||
}
|
||||
|
||||
ln, err := net.Listen(bindProto, l.Address)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
ln = TCPKeepAliveListener{ln.(*net.TCPListener)}
|
||||
|
||||
ln, err = listenerWrapProxy(ln, l)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
props := map[string]string{
|
||||
"addr": l.Address,
|
||||
}
|
||||
|
||||
alpnMux := alpnmux.New(ln, nil)
|
||||
|
||||
if l.TLSDisable {
|
||||
if _, err = alpnMux.RegisterProto(alpnmux.NoProto, nil); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
return alpnMux, props, nil, nil
|
||||
}
|
||||
|
||||
tlsConfig, reloadFunc, err := listenerutil.GetTLSConfig(ln, l, props, ui)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
// Register no proto, "http/1.1", and "h2", with same TLS config
|
||||
if _, err = alpnMux.RegisterProto("", tlsConfig); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
if _, err = alpnMux.RegisterProto("http/1.1", tlsConfig); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
if _, err = alpnMux.RegisterProto("h2", tlsConfig); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
return alpnMux, props, reloadFunc, nil
|
||||
}
|
||||
|
||||
// TCPKeepAliveListener sets TCP keep-alive timeouts on accepted
|
||||
// connections. It's used by ListenAndServe and ListenAndServeTLS so
|
||||
// dead TCP connections (e.g. closing laptop mid-download) eventually
|
||||
// go away.
|
||||
//
|
||||
// This is copied directly from the Go source code.
|
||||
type TCPKeepAliveListener struct {
|
||||
*net.TCPListener
|
||||
}
|
||||
|
||||
func (ln TCPKeepAliveListener) Accept() (c net.Conn, err error) {
|
||||
tc, err := ln.AcceptTCP()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
tc.SetKeepAlive(true)
|
||||
tc.SetKeepAlivePeriod(3 * time.Minute)
|
||||
return tc, nil
|
||||
}
|
||||
Reference in new issue
Block a user