From 501bf12837382b66d5ddb05e83f44a5c4bea6480 Mon Sep 17 00:00:00 2001 From: "Jonathan A. Sternberg" Date: Fri, 20 Oct 2017 10:03:21 -0500 Subject: [PATCH] Remove the pidfile after the server has exited --- CHANGELOG.md | 1 + cmd/kapacitord/run/command.go | 16 +++++-- cmd/kapacitord/run/command_test.go | 70 ++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 cmd/kapacitord/run/command_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index ddd68c1e23..7b6255f3e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ - [#1581](https://github.com/influxdata/kapacitor/pull/1581): Add SNMP sysUpTime to SNMP Trap service - [#1547](https://github.com/influxdata/kapacitor/issues/1547): Fix panic on recording replay with HTTPPostHandler. - [#1623](https://github.com/influxdata/kapacitor/issues/1623): Fix k8s incluster master api dns resolution +- [#1630](https://github.com/influxdata/kapacitor/issues/1630): Remove the pidfile after the server has exited. ## v1.3.3 [2017-08-11] diff --git a/cmd/kapacitord/run/command.go b/cmd/kapacitord/run/command.go index 6f521e2aef..46d7fe6740 100644 --- a/cmd/kapacitord/run/command.go +++ b/cmd/kapacitord/run/command.go @@ -41,6 +41,7 @@ type Command struct { Commit string closing chan struct{} + pidfile string Closed chan struct{} Stdin io.Reader @@ -104,7 +105,7 @@ func (cmd *Command) Run(args ...string) error { // Initialize Logging Services cmd.diagService = diagnostic.NewService(config.Logging, cmd.Stdout, cmd.Stderr) if err := cmd.diagService.Open(); err != nil { - return fmt.Errorf("failed to opend diagnostic service: %v", err) + return fmt.Errorf("failed to open diagnostic service: %v", err) } // Initialize cmd diagnostic @@ -118,6 +119,7 @@ func (cmd *Command) Run(args ...string) error { if err := cmd.writePIDFile(options.PIDFile); err != nil { return fmt.Errorf("write pid file: %s", err) } + cmd.pidfile = options.PIDFile // Create server from config and start it. buildInfo := server.BuildInfo{Version: cmd.Version, Commit: cmd.Commit, Branch: cmd.Branch} @@ -142,6 +144,7 @@ func (cmd *Command) Run(args ...string) error { // Close shuts down the server. func (cmd *Command) Close() error { defer close(cmd.Closed) + defer cmd.removePIDFile() close(cmd.closing) if cmd.Server != nil { return cmd.Server.Close() @@ -165,6 +168,14 @@ func (cmd *Command) monitorServerErrors() { } } +func (cmd *Command) removePIDFile() { + if cmd.pidfile != "" { + if err := os.Remove(cmd.pidfile); err != nil { + cmd.Diag.Error("unable to remove pidfile", err) + } + } +} + // ParseFlags parses the command line flags from args and returns an options set. func (cmd *Command) ParseFlags(args ...string) (Options, error) { var options Options @@ -191,8 +202,7 @@ func (cmd *Command) writePIDFile(path string) error { } // Ensure the required directory structure exists. - err := os.MkdirAll(filepath.Dir(path), 0777) - if err != nil { + if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil { return fmt.Errorf("mkdir: %s", err) } diff --git a/cmd/kapacitord/run/command_test.go b/cmd/kapacitord/run/command_test.go new file mode 100644 index 0000000000..c70edbe13b --- /dev/null +++ b/cmd/kapacitord/run/command_test.go @@ -0,0 +1,70 @@ +package run_test + +import ( + "bytes" + "io/ioutil" + "os" + "path/filepath" + "testing" + "text/template" + "time" + + "fmt" + + "github.com/influxdata/kapacitor/cmd/kapacitord/run" +) + +func TestCommand_PIDFile(t *testing.T) { + tmpdir, err := ioutil.TempDir(os.TempDir(), "kapacitord-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + // Write out a config file that does not attempt to connect to influxdb. + configFile := filepath.Join(tmpdir, "kapacitor.conf") + configTemplate := template.Must(template.New("config_file").Parse(`data_dir = "{{.TempDir}}/data" +[[influxdb]] + enabled = false +[replay] + dir = "{{.TempDir}}/replay" +[storage] + boltdb = "{{.TempDir}}/kapacitor.db" +[task] + dir = "{{.TempDir}}/tasks" +[load] + dir = "{{.TempDir}}/load" +`)) + var buf bytes.Buffer + if err := configTemplate.Execute(&buf, map[string]string{"TempDir": tmpdir}); err != nil { + t.Fatalf("unable to generate config file: %s", err) + } + fmt.Println(buf.String()) + if err := ioutil.WriteFile(configFile, buf.Bytes(), 0600); err != nil { + t.Fatalf("unable to write %s: %s", configFile, err) + } + + pidFile := filepath.Join(tmpdir, "kapacitor.pid") + + cmd := run.NewCommand() + if err := cmd.Run("-config", configFile, "-pidfile", pidFile); err != nil { + t.Fatalf("unexpected error: %s", err) + } + + if _, err := os.Stat(pidFile); err != nil { + t.Fatalf("could not stat pid file: %s", err) + } + go cmd.Close() + + timeout := time.NewTimer(time.Second) + select { + case <-timeout.C: + t.Fatal("unexpected timeout") + case <-cmd.Closed: + timeout.Stop() + } + + if _, err := os.Stat(pidFile); err == nil { + t.Fatal("expected pid file to be removed") + } +}