diff options
| -rw-r--r-- | admin.go | 40 | ||||
| -rw-r--r-- | caddyconfig/httpcaddyfile/httptype.go | 5 | ||||
| -rw-r--r-- | caddyconfig/httpcaddyfile/options.go | 14 | ||||
| -rw-r--r-- | cmd/commandfuncs.go | 16 | 
4 files changed, 55 insertions, 20 deletions
@@ -18,6 +18,7 @@ import (  	"bytes"  	"context"  	"encoding/json" +	"errors"  	"fmt"  	"io"  	"io/ioutil" @@ -42,6 +43,8 @@ var (  	cfgEndptSrvMu sync.Mutex  ) +var ErrAdminInterfaceNotConfigured = errors.New("no admin configuration has been set") +  // AdminConfig configures the admin endpoint.  type AdminConfig struct {  	Listen string `json:"listen,omitempty"` @@ -60,10 +63,24 @@ var DefaultAdminConfig = &AdminConfig{  // in the format of JSON bytes. It opens a listener  // resource. When no longer needed, StopAdmin should  // be called. +// If no configuration is given, a default listener is +// started. If a configuration is given that does NOT +// specifically configure the admin interface, +// `ErrAdminInterfaceNotConfigured` is returned and no +// listener is initialized.  func StartAdmin(initialConfigJSON []byte) error {  	cfgEndptSrvMu.Lock()  	defer cfgEndptSrvMu.Unlock() +	if cfgEndptSrv != nil { +		ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) +		defer cancel() +		err := cfgEndptSrv.Shutdown(ctx) +		if err != nil { +			return fmt.Errorf("shutting down old admin endpoint: %v", err) +		} +	} +  	adminConfig := DefaultAdminConfig  	if len(initialConfigJSON) > 0 {  		var config *Config @@ -71,16 +88,11 @@ func StartAdmin(initialConfigJSON []byte) error {  		if err != nil {  			return fmt.Errorf("unmarshaling bootstrap config: %v", err)  		} -		if config != nil && config.Admin != nil { -			adminConfig = config.Admin -		} -		if cfgEndptSrv != nil { -			ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) -			defer cancel() -			err := cfgEndptSrv.Shutdown(ctx) -			if err != nil { -				return fmt.Errorf("shutting down old admin endpoint: %v", err) +		if config != nil { +			if config.Admin == nil { +				return ErrAdminInterfaceNotConfigured  			} +			adminConfig = config.Admin  		}  	} @@ -136,15 +148,7 @@ func StartAdmin(initialConfigJSON []byte) error {  	go cfgEndptSrv.Serve(ln) -	fmt.Println("Caddy 2 admin endpoint listening on", adminConfig.Listen) - -	if len(initialConfigJSON) > 0 { -		err := Load(bytes.NewReader(initialConfigJSON)) -		if err != nil { -			return fmt.Errorf("loading initial config: %v", err) -		} -		fmt.Println("Caddy 2 serving initial configuration") -	} +	Log().Named("admin").Info("Caddy 2 admin endpoint started.", zap.String("listenAddress", adminConfig.Listen))  	return nil  } diff --git a/caddyconfig/httpcaddyfile/httptype.go b/caddyconfig/httpcaddyfile/httptype.go index bc546b4..05022d1 100644 --- a/caddyconfig/httpcaddyfile/httptype.go +++ b/caddyconfig/httpcaddyfile/httptype.go @@ -74,6 +74,8 @@ func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,  				val, err = parseOptACMECA(disp)  			case "email":  				val, err = parseOptEmail(disp) +			case "admin": +				val, err = parseOptAdmin(disp)  			default:  				return nil, warnings, fmt.Errorf("unrecognized parameter name: %s", dir)  			} @@ -254,6 +256,9 @@ func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,  			storageCvtr.(caddy.Module).CaddyModule().ID(),  			&warnings)  	} +	if adminConfig, ok := options["admin"].(string); ok && adminConfig != "" { +		cfg.Admin = &caddy.AdminConfig{Listen: adminConfig} +	}  	return cfg, warnings, nil  } diff --git a/caddyconfig/httpcaddyfile/options.go b/caddyconfig/httpcaddyfile/options.go index a60d060..74ec507 100644 --- a/caddyconfig/httpcaddyfile/options.go +++ b/caddyconfig/httpcaddyfile/options.go @@ -132,3 +132,17 @@ func parseOptEmail(d *caddyfile.Dispenser) (string, error) {  	}  	return val, nil  } + +func parseOptAdmin(d *caddyfile.Dispenser) (string, error) { +	if d.Next() { +		var listenAddress string +		d.AllArgs(&listenAddress) + +		if listenAddress == "" { +			listenAddress = caddy.DefaultAdminListen +		} + +		return listenAddress, nil +	} +	return "", nil +} diff --git a/cmd/commandfuncs.go b/cmd/commandfuncs.go index 7c08c2e..d73644c 100644 --- a/cmd/commandfuncs.go +++ b/cmd/commandfuncs.go @@ -161,12 +161,24 @@ func cmdRun(fl Flags) (int, error) {  	certmagic.UserAgent = "Caddy/" + cleanModVersion  	// start the admin endpoint along with any initial config +	// a configuration without admin config is considered fine +	// but does not enable the admin endpoint at all  	err = caddy.StartAdmin(config) -	if err != nil { +	if err == nil { +		defer caddy.StopAdmin() +	} else if err != caddy.ErrAdminInterfaceNotConfigured {  		return caddy.ExitCodeFailedStartup,  			fmt.Errorf("starting caddy administration endpoint: %v", err)  	} -	defer caddy.StopAdmin() + +	// if a config has been supplied, load it as initial config +	if len(config) > 0 { +		err := caddy.Load(bytes.NewReader(config)) +		if err != nil { +			return caddy.ExitCodeFailedStartup, fmt.Errorf("loading initial config: %v", err) +		} +		caddy.Log().Named("admin").Info("Caddy 2 serving initial configuration") +	}  	// if we are to report to another process the successful start  	// of the server, do so now by echoing back contents of stdin  | 
