+ app: add '--pidfile FILE' command-line parameter
This commit is contained in:
parent
08bedacf0a
commit
7746a3e6a9
35
app.go
35
app.go
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -25,6 +26,7 @@ var httpsServer struct {
|
||||||
cond *sync.Cond // reacts to config.TLS.Enabled, PortHTTPS, CertificateChain and PrivateKey
|
cond *sync.Cond // reacts to config.TLS.Enabled, PortHTTPS, CertificateChain and PrivateKey
|
||||||
sync.Mutex // protects config.TLS
|
sync.Mutex // protects config.TLS
|
||||||
}
|
}
|
||||||
|
var pidFileName string // PID file name. Empty if no PID file was created.
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Used in config to indicate that syslog or eventlog (win) should be used for logger output
|
// Used in config to indicate that syslog or eventlog (win) should be used for logger output
|
||||||
|
@ -47,6 +49,7 @@ func main() {
|
||||||
go func() {
|
go func() {
|
||||||
<-signalChannel
|
<-signalChannel
|
||||||
cleanup()
|
cleanup()
|
||||||
|
cleanupAlways()
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -124,6 +127,10 @@ func run(args options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(args.pidFile) != 0 && writePIDFile(args.pidFile) {
|
||||||
|
pidFileName = args.pidFile
|
||||||
|
}
|
||||||
|
|
||||||
// Update filters we've just loaded right away, don't wait for periodic update timer
|
// Update filters we've just loaded right away, don't wait for periodic update timer
|
||||||
go func() {
|
go func() {
|
||||||
refreshFiltersIfNecessary(false)
|
refreshFiltersIfNecessary(false)
|
||||||
|
@ -158,8 +165,8 @@ func run(args options) {
|
||||||
// validate current TLS config and update warnings (it could have been loaded from file)
|
// validate current TLS config and update warnings (it could have been loaded from file)
|
||||||
data := validateCertificates(config.TLS.CertificateChain, config.TLS.PrivateKey, config.TLS.ServerName)
|
data := validateCertificates(config.TLS.CertificateChain, config.TLS.PrivateKey, config.TLS.ServerName)
|
||||||
if !data.ValidPair {
|
if !data.ValidPair {
|
||||||
|
cleanupAlways()
|
||||||
log.Fatal(data.WarningValidation)
|
log.Fatal(data.WarningValidation)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
config.Lock()
|
config.Lock()
|
||||||
config.TLS.tlsConfigStatus = data // update warnings
|
config.TLS.tlsConfigStatus = data // update warnings
|
||||||
|
@ -173,8 +180,8 @@ func run(args options) {
|
||||||
copy(privatekey, []byte(config.TLS.PrivateKey))
|
copy(privatekey, []byte(config.TLS.PrivateKey))
|
||||||
cert, err := tls.X509KeyPair(certchain, privatekey)
|
cert, err := tls.X509KeyPair(certchain, privatekey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
cleanupAlways()
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
httpsServer.cond.L.Unlock()
|
httpsServer.cond.L.Unlock()
|
||||||
|
|
||||||
|
@ -189,8 +196,8 @@ func run(args options) {
|
||||||
printHTTPAddresses("https")
|
printHTTPAddresses("https")
|
||||||
err = httpsServer.server.ListenAndServeTLS("", "")
|
err = httpsServer.server.ListenAndServeTLS("", "")
|
||||||
if err != http.ErrServerClosed {
|
if err != http.ErrServerClosed {
|
||||||
|
cleanupAlways()
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -206,13 +213,24 @@ func run(args options) {
|
||||||
}
|
}
|
||||||
err := httpServer.ListenAndServe()
|
err := httpServer.ListenAndServe()
|
||||||
if err != http.ErrServerClosed {
|
if err != http.ErrServerClosed {
|
||||||
|
cleanupAlways()
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
// We use ErrServerClosed as a sign that we need to rebind on new address, so go back to the start of the loop
|
// We use ErrServerClosed as a sign that we need to rebind on new address, so go back to the start of the loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write PID to a file
|
||||||
|
func writePIDFile(fn string) bool {
|
||||||
|
data := fmt.Sprintf("%d", os.Getpid())
|
||||||
|
err := ioutil.WriteFile(fn, []byte(data), 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Couldn't write PID to file %s: %v", fn, err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// initWorkingDir initializes the ourWorkingDir
|
// initWorkingDir initializes the ourWorkingDir
|
||||||
// if no command-line arguments specified, we use the directory where our binary file is located
|
// if no command-line arguments specified, we use the directory where our binary file is located
|
||||||
func initWorkingDir(args options) {
|
func initWorkingDir(args options) {
|
||||||
|
@ -298,6 +316,13 @@ func cleanup() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function is called before application exits
|
||||||
|
func cleanupAlways() {
|
||||||
|
if len(pidFileName) != 0 {
|
||||||
|
os.Remove(pidFileName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// command-line arguments
|
// command-line arguments
|
||||||
type options struct {
|
type options struct {
|
||||||
verbose bool // is verbose logging enabled
|
verbose bool // is verbose logging enabled
|
||||||
|
@ -306,6 +331,7 @@ type options struct {
|
||||||
bindHost string // host address to bind HTTP server on
|
bindHost string // host address to bind HTTP server on
|
||||||
bindPort int // port to serve HTTP pages on
|
bindPort int // port to serve HTTP pages on
|
||||||
logFile string // Path to the log file. If empty, write to stdout. If "syslog", writes to syslog
|
logFile string // Path to the log file. If empty, write to stdout. If "syslog", writes to syslog
|
||||||
|
pidFile string // File name to save PID to
|
||||||
|
|
||||||
// service control action (see service.ControlAction array + "status" command)
|
// service control action (see service.ControlAction array + "status" command)
|
||||||
serviceControlAction string
|
serviceControlAction string
|
||||||
|
@ -342,6 +368,7 @@ func loadOptions() options {
|
||||||
{"logfile", "l", "path to the log file. If empty, writes to stdout, if 'syslog' -- system log", func(value string) {
|
{"logfile", "l", "path to the log file. If empty, writes to stdout, if 'syslog' -- system log", func(value string) {
|
||||||
o.logFile = value
|
o.logFile = value
|
||||||
}, nil},
|
}, nil},
|
||||||
|
{"pidfile", "", "File name to save PID to", func(value string) { o.pidFile = value }, nil},
|
||||||
{"verbose", "v", "enable verbose output", nil, func() { o.verbose = true }},
|
{"verbose", "v", "enable verbose output", nil, func() { o.verbose = true }},
|
||||||
{"help", "", "print this help", nil, func() {
|
{"help", "", "print this help", nil, func() {
|
||||||
printHelp()
|
printHelp()
|
||||||
|
|
|
@ -32,6 +32,7 @@ func (p *program) Start(s service.Service) error {
|
||||||
func (p *program) Stop(s service.Service) error {
|
func (p *program) Stop(s service.Service) error {
|
||||||
// Stop should not block. Return with a few seconds.
|
// Stop should not block. Return with a few seconds.
|
||||||
cleanup()
|
cleanup()
|
||||||
|
cleanupAlways()
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue