mirror of
https://github.com/zrepl/zrepl.git
synced 2024-12-12 02:02:16 +01:00
896f31bbf3
Version is autodetected on build using git If it cannot be detected with git, an override must be provided. For tracability of distros, the distroy packagers should override as well, which is why I added a README entry for package mainatiners. refs #35
156 lines
3.0 KiB
Go
156 lines
3.0 KiB
Go
package cmd
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/spf13/cobra"
|
|
"io"
|
|
golog "log"
|
|
"net"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
)
|
|
|
|
var controlCmd = &cobra.Command{
|
|
Use: "control",
|
|
Short: "control zrepl daemon",
|
|
}
|
|
|
|
var pprofCmd = &cobra.Command{
|
|
Use: "pprof cpu OUTFILE",
|
|
Short: "pprof CPU of daemon to OUTFILE (- for stdout)",
|
|
Run: doControlPProf,
|
|
}
|
|
var pprofCmdArgs struct {
|
|
seconds int64
|
|
}
|
|
|
|
var controlVersionCmd = &cobra.Command{
|
|
Use: "version",
|
|
Short: "print version of running zrepl daemon",
|
|
Run: doControLVersionCmd,
|
|
}
|
|
|
|
func init() {
|
|
RootCmd.AddCommand(controlCmd)
|
|
controlCmd.AddCommand(pprofCmd)
|
|
pprofCmd.Flags().Int64Var(&pprofCmdArgs.seconds, "seconds", 30, "seconds to profile")
|
|
controlCmd.AddCommand(controlVersionCmd)
|
|
}
|
|
|
|
func controlHttpClient() (client http.Client, err error) {
|
|
|
|
conf, err := ParseConfig(rootArgs.configFile)
|
|
if err != nil {
|
|
return http.Client{}, err
|
|
}
|
|
|
|
return http.Client{
|
|
Transport: &http.Transport{
|
|
DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
|
|
return net.Dial("unix", conf.Global.Control.Sockpath)
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func doControlPProf(cmd *cobra.Command, args []string) {
|
|
|
|
log := golog.New(os.Stderr, "", 0)
|
|
|
|
die := func() {
|
|
log.Printf("exiting after error")
|
|
os.Exit(1)
|
|
}
|
|
|
|
if cmd.Flags().Arg(0) != "cpu" {
|
|
log.Printf("only CPU profiles are supported")
|
|
log.Printf("%s", cmd.UsageString())
|
|
die()
|
|
}
|
|
|
|
outfn := cmd.Flags().Arg(1)
|
|
if outfn == "" {
|
|
log.Printf("must specify output filename")
|
|
log.Printf("%s", cmd.UsageString())
|
|
die()
|
|
}
|
|
var out io.Writer
|
|
var err error
|
|
if outfn == "-" {
|
|
out = os.Stdout
|
|
} else {
|
|
out, err = os.Create(outfn)
|
|
if err != nil {
|
|
log.Printf("error creating output file: %s", err)
|
|
die()
|
|
}
|
|
}
|
|
|
|
log.Printf("connecting to daemon")
|
|
httpc, err := controlHttpClient()
|
|
if err != nil {
|
|
log.Printf("error parsing config: %s", err)
|
|
die()
|
|
}
|
|
|
|
log.Printf("profiling...")
|
|
v := url.Values{}
|
|
v.Set("seconds", fmt.Sprintf("%d", pprofCmdArgs.seconds))
|
|
v.Encode()
|
|
resp, err := httpc.Get("http://unix" + ControlJobEndpointProfile + "?" + v.Encode())
|
|
if err != nil {
|
|
log.Printf("error: %s", err)
|
|
die()
|
|
}
|
|
|
|
_, err = io.Copy(out, resp.Body)
|
|
if err != nil {
|
|
log.Printf("error writing profile: %s", err)
|
|
die()
|
|
}
|
|
|
|
log.Printf("finished")
|
|
|
|
}
|
|
|
|
func doControLVersionCmd(cmd *cobra.Command, args []string) {
|
|
|
|
log := golog.New(os.Stderr, "", 0)
|
|
|
|
die := func() {
|
|
log.Printf("exiting after error")
|
|
os.Exit(1)
|
|
}
|
|
|
|
httpc, err := controlHttpClient()
|
|
if err != nil {
|
|
log.Printf("could not connect to daemon: %s", err)
|
|
die()
|
|
}
|
|
|
|
resp, err := httpc.Get("http://unix" + ControlJobEndpointVersion)
|
|
if err != nil {
|
|
log.Printf("error: %s", err)
|
|
die()
|
|
} else if resp.StatusCode != http.StatusOK {
|
|
var msg bytes.Buffer
|
|
io.CopyN(&msg, resp.Body, 4096)
|
|
log.Printf("error: %s", msg.String())
|
|
die()
|
|
}
|
|
|
|
var info ZreplVersionInformation
|
|
err = json.NewDecoder(resp.Body).Decode(&info)
|
|
if err != nil {
|
|
log.Printf("error unmarshaling response: %s", err)
|
|
die()
|
|
}
|
|
|
|
fmt.Println(info.String())
|
|
|
|
}
|