From 9429c843c854c0a8d9f9e5710dd6903afabeefb3 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Fri, 5 Jul 2019 09:59:13 -0600 Subject: cmd: New reload command --- cmd/commands.go | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'cmd/commands.go') diff --git a/cmd/commands.go b/cmd/commands.go index f98b401..5e0217a 100644 --- a/cmd/commands.go +++ b/cmd/commands.go @@ -15,12 +15,16 @@ package caddycmd import ( + "bytes" "crypto/rand" + "encoding/json" "flag" "fmt" + "io" "io/ioutil" "log" "net" + "net/http" "os" "os/exec" "path/filepath" @@ -200,6 +204,59 @@ func cmdStop() (int, error) { return 0, nil } +func cmdReload() (int, error) { + reloadCmd := flag.NewFlagSet("load", flag.ExitOnError) + reloadCmdConfigFlag := reloadCmd.String("config", "", "Configuration file") + reloadCmdAddrFlag := reloadCmd.String("address", "", "Address of the administration listener, if different from config") + reloadCmd.Parse(os.Args[2:]) + + // a configuration is required + if *reloadCmdConfigFlag == "" { + return 1, fmt.Errorf("no configuration to load (use --config)") + } + + // load the configuration file + config, err := ioutil.ReadFile(*reloadCmdConfigFlag) + if err != nil { + return 1, fmt.Errorf("reading config file: %v", err) + } + + // get the address of the admin listener and craft endpoint URL + adminAddr := *reloadCmdAddrFlag + if adminAddr == "" { + var tmpStruct struct { + Admin caddy.AdminConfig `json:"admin"` + } + err = json.Unmarshal(config, &tmpStruct) + if err != nil { + return 1, fmt.Errorf("unmarshaling admin listener address from config: %v", err) + } + adminAddr = tmpStruct.Admin.Listen + } + if adminAddr == "" { + adminAddr = caddy.DefaultAdminListen + } + adminEndpoint := fmt.Sprintf("http://%s/load", adminAddr) + + // send the configuration to the instance + resp, err := http.Post(adminEndpoint, "application/json", bytes.NewReader(config)) + if err != nil { + return 1, fmt.Errorf("sending configuration to instance: %v", err) + } + defer resp.Body.Close() + + // if it didn't work, let the user know + if resp.StatusCode >= 400 { + respBody, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1024*10)) + if err != nil { + return 1, fmt.Errorf("HTTP %d: reading error message: %v", resp.StatusCode, err) + } + return 1, fmt.Errorf("caddy responded with error: HTTP %d: %s", resp.StatusCode, respBody) + } + + return 0, nil +} + func cmdVersion() (int, error) { goModule := caddy.GoModule() if goModule.Sum != "" { -- cgit v1.2.3