From 170c1ec8873811024e131391f7cc14f6ee0f7fed Mon Sep 17 00:00:00 2001 From: twystd Date: Tue, 6 Dec 2022 10:41:13 -0800 Subject: [PATCH] Reworked service lockfile to use 'flock' syscall (cf. https://github.com/uhppoted/uhppoted-tunnel/issues/7) --- CHANGELOG.md | 3 ++- commands/run.go | 53 +++++++++++++++++++++++++-------------- go.mod | 6 ++--- go.sum | 7 ++++++ log/log.go | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 23 deletions(-) create mode 100644 log/log.go diff --git a/CHANGELOG.md b/CHANGELOG.md index f267b36..544b17c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ ## [Unreleased] ### Changed -1. Updated _systemd_ unit file to wait on `network-online.target` +1. Updated _systemd_ unit file to wait on `network-online.target`. +2. Updated service lockfile to use `flock` _syscall_. ## [0.8.2](https://github.com/uhppoted/uhppoted-rest/releases/tag/v0.8.2) - 2022-10-14 diff --git a/commands/run.go b/commands/run.go index 34e838b..f1519dd 100644 --- a/commands/run.go +++ b/commands/run.go @@ -3,8 +3,7 @@ package commands import ( "errors" "fmt" - "io/ioutil" - "log" + syslog "log" "math" "os" "os/signal" @@ -13,10 +12,13 @@ import ( "syscall" "time" - "github.com/uhppoted/uhppote-core/types" - "github.com/uhppoted/uhppote-core/uhppote" "github.com/uhppoted/uhppoted-lib/config" "github.com/uhppoted/uhppoted-lib/locales" + "github.com/uhppoted/uhppoted-lib/lockfile" + + "github.com/uhppoted/uhppote-core/types" + "github.com/uhppoted/uhppote-core/uhppote" + "github.com/uhppoted/uhppoted-rest/log" "github.com/uhppoted/uhppoted-rest/rest" ) @@ -76,28 +78,41 @@ func (cmd *Run) Help() { func (cmd *Run) execute(f func(*config.Config) error) error { conf := config.NewConfig() if err := conf.Load(cmd.configuration); err != nil { - log.Printf("\n WARN: Could not load configuration (%v)\n\n", err) + log.Warnf("RUN", "Could not load configuration (%v)", err) } if err := os.MkdirAll(cmd.dir, os.ModeDir|os.ModePerm); err != nil { return fmt.Errorf("Unable to create working directory '%v': %v", cmd.dir, err) } - pid := fmt.Sprintf("%d\n", os.Getpid()) + // ... create lockfile + lockFile := config.Lockfile{ + File: cmd.pidFile, + Remove: conf.LockfileRemove, + } - if err := ioutil.WriteFile(cmd.pidFile, []byte(pid), 0644); err != nil { - return fmt.Errorf("Unable to create pid file: %v\n", err) + if lockFile.File == "" { + lockFile.File = filepath.Join(os.TempDir(), fmt.Sprintf("%s.pid", SERVICE)) } - defer func() { - os.Remove(cmd.pidFile) - }() + if kraken, err := lockfile.MakeLockFile(lockFile); err != nil { + return err + } else { + defer func() { + kraken.Release() + }() + + log.AddFatalHook(func() { + kraken.Release() + }) + } + // ... run return f(conf) } -func (cmd *Run) run(c *config.Config, logger *log.Logger) { - logger.Printf("START") +func (cmd *Run) run(c *config.Config, logger *syslog.Logger) { + log.Infof("RUN", "START") // ... set (optional) locale if c.REST.Locale != "" { @@ -122,18 +137,18 @@ func (cmd *Run) run(c *config.Config, logger *log.Logger) { for { err := cmd.listen(c, logger, interrupt) if err != nil { - log.Printf("ERROR: %v", err) + log.Errorf("RUN", "%v", err) continue } - log.Printf("exit\n") + log.Infof("RUN", "exit") break } - logger.Printf("STOP") + log.Infof("RUN", "STOP") } -func (cmd *Run) listen(c *config.Config, logger *log.Logger, interrupt chan os.Signal) error { +func (cmd *Run) listen(c *config.Config, logger *syslog.Logger, interrupt chan os.Signal) error { s := state{ started: time.Now(), @@ -244,7 +259,7 @@ func (cmd *Run) listen(c *config.Config, logger *log.Logger, interrupt chan os.S } } -func healthcheck(u uhppote.IUHPPOTE, st *state, l *log.Logger) { +func healthcheck(u uhppote.IUHPPOTE, st *state, l *syslog.Logger) { l.Printf("health-check") now := time.Now() @@ -278,7 +293,7 @@ func healthcheck(u uhppote.IUHPPOTE, st *state, l *log.Logger) { st.healthcheck.touched = &now } -func watchdog(u uhppote.IUHPPOTE, st *state, l *log.Logger) error { +func watchdog(u uhppote.IUHPPOTE, st *state, l *syslog.Logger) error { warnings := 0 errors := 0 healthCheckRunning := false diff --git a/go.mod b/go.mod index 85b1e65..451ca30 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/uhppoted/uhppoted-rest go 1.19 require ( - github.com/uhppoted/uhppote-core v0.8.2 - github.com/uhppoted/uhppoted-lib v0.8.2 - golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43 + github.com/uhppoted/uhppote-core v0.8.3-0.20221014202027-b01c41cc87cb + github.com/uhppoted/uhppoted-lib v0.8.3-0.20221202193858-995911d08ead + golang.org/x/sys v0.3.0 ) diff --git a/go.sum b/go.sum index 8ccc043..3e86e3f 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,8 @@ github.com/uhppoted/uhppote-core v0.8.2-0.20221012170946-d9f90fb812d0 h1:0Tn/Bev github.com/uhppoted/uhppote-core v0.8.2-0.20221012170946-d9f90fb812d0/go.mod h1:DsKVqUqHPQoZx4C4qp0fmYuyDXfFH8k+ejTriM9pOE4= github.com/uhppoted/uhppote-core v0.8.2 h1:FCf+mm8Sos9HH0Cgh0xVjjmXce1lVKGglYYcm6f5p3k= github.com/uhppoted/uhppote-core v0.8.2/go.mod h1:DsKVqUqHPQoZx4C4qp0fmYuyDXfFH8k+ejTriM9pOE4= +github.com/uhppoted/uhppote-core v0.8.3-0.20221014202027-b01c41cc87cb h1:C52puy+NuWqg9jmARakjn2+CBLAaHdG9QjRB1Y+FpVg= +github.com/uhppoted/uhppote-core v0.8.3-0.20221014202027-b01c41cc87cb/go.mod h1:DsKVqUqHPQoZx4C4qp0fmYuyDXfFH8k+ejTriM9pOE4= github.com/uhppoted/uhppoted-lib v0.7.3-0.20220128210643-c4d9a4bc1660 h1:BRLml03IH5I0wzAOaKrmQ3V/wbRdoBmRb/sBX+uX7Nw= github.com/uhppoted/uhppoted-lib v0.7.3-0.20220128210643-c4d9a4bc1660/go.mod h1:HQChamquwltZIqT+tmMfDLTjaqLXEsokPQf8Utxi9MA= github.com/uhppoted/uhppoted-lib v0.7.3-0.20220531204140-34d8876e5e89 h1:Cwp9o2KzliY85ERUkV9Z9RBFjVotzHLMAQ89EBblQcg= @@ -46,6 +48,8 @@ github.com/uhppoted/uhppoted-lib v0.8.2-0.20221013172451-f2427e352048 h1:EeOg+XY github.com/uhppoted/uhppoted-lib v0.8.2-0.20221013172451-f2427e352048/go.mod h1:9nzfe9mGv0WcIYM7zK2LFG1ypzn9Nya8hf32meWy1Cg= github.com/uhppoted/uhppoted-lib v0.8.2 h1:QrZBUjEAHk2I0h9KhVZaqYiTBMAALpyG38rt/mLGtsM= github.com/uhppoted/uhppoted-lib v0.8.2/go.mod h1:b4kLAd3C6Px4VFlG9Ng+420gQBLgFAS96D38ftL+/pU= +github.com/uhppoted/uhppoted-lib v0.8.3-0.20221202193858-995911d08ead h1:skrAYGcLUx5Xo06zqQki9RGqhiZXzfEpzH04rPTU/XU= +github.com/uhppoted/uhppoted-lib v0.8.3-0.20221202193858-995911d08ead/go.mod h1:+NEqv7+r9tR5E4fU/hv4R3JiQcfKZq5ystW8EfiJf08= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= @@ -64,3 +68,6 @@ golang.org/x/sys v0.0.0-20221010170243-090e33056c14 h1:k5II8e6QD8mITdi+okbbmR/cI golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43 h1:OK7RB6t2WQX54srQQYSXMW8dF5C6/8+oA/s5QBmmto4= golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/log/log.go b/log/log.go new file mode 100644 index 0000000..9c72abe --- /dev/null +++ b/log/log.go @@ -0,0 +1,66 @@ +package log + +import ( + "fmt" + syslog "log" + + "github.com/uhppoted/uhppoted-lib/log" +) + +type LogLevel int + +const ( + none LogLevel = iota + debug + info + warn + errors +) + +const f = "%-12v %v" + +func SetDebug(enabled bool) { + log.SetDebug(enabled) +} + +func SetLevel(level string) { + log.SetLevel(level) +} + +func SetLogger(logger *syslog.Logger) { + log.SetLogger(logger) +} + +func AddFatalHook(f func()) { + log.AddFatalHook(f) +} + +func Debugf(tag string, format string, args ...any) { + s := fmt.Sprintf(f, tag, format) + + log.Debugf(s, args...) +} + +func Infof(tag string, format string, args ...any) { + s := fmt.Sprintf(f, tag, format) + + log.Infof(s, args...) +} + +func Warnf(tag string, format string, args ...any) { + s := fmt.Sprintf(f, tag, format) + + log.Warnf(s, args...) +} + +func Errorf(tag string, format string, args ...any) { + s := fmt.Sprintf(f, tag, format) + + log.Errorf(s, args...) +} + +func Fatalf(tag string, format string, args ...any) { + s := fmt.Sprintf(f, tag, format) + + log.Fatalf(s, args...) +}