Skip to content

Commit

Permalink
Merge pull request #286 from Notifiarr/unstable
Browse files Browse the repository at this point in the history
Crash fix
  • Loading branch information
davidnewhall authored Aug 20, 2022
2 parents 7fc1966 + 8ba7f0d commit 3e87d0f
Show file tree
Hide file tree
Showing 15 changed files with 137 additions and 62 deletions.
5 changes: 0 additions & 5 deletions init/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,9 @@ COPY go.mod go.sum .
RUN go mod download
COPY . .

ARG BINARY=application-builder
ARG BUILD_DATE=0
ARG COMMIT=0
ARG VERSION=unknown
ARG TARGETOS
ARG BINARY
ARG TARGETARCH
ARG BUILD_FLAGS

# For megacli. All the *'s are to deal with multiarch. :(
RUN apt update && apt install -y libncurses5 libstdc++6 libtinfo5 apt-utils && \
Expand Down
1 change: 1 addition & 0 deletions init/docker/build
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pushd ../..

source settings.sh

docker buildx create --use

if [ "v$VERSION" = "$SOURCE_BRANCH" ]; then
TAGS="--tag ${DOCKER_REPO}:$VERSION"
Expand Down
2 changes: 1 addition & 1 deletion pkg/bindata/templates/landing.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ <h1 class="text-center text-bold mt-4x">Bienvenidos!</h1>
If you have more ideas for this interface, or find any bugs,
<a href="https://github.com/Notifiarr/notifiarr/issues/new">please let us know!</a>
</p>
<p><b>{{.ClientInfo.String}}</b></p>
<p>{{todaysemoji}} <b>{{.ClientInfo.String}}</b></p>
<p class="text-center"><img src="{{files}}/images/golift.png" style="height:150px;"></p>
</div>
<div class="col-md-1">
Expand Down
2 changes: 1 addition & 1 deletion pkg/bindata/templates/system.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ <h4>Client</h4>
</tr>
<tr>
<td>Version</td>
<td>{{.Version.version}}.{{.Version.revision}}</td>
<td>{{.Version.version}}-{{.Version.revision}}</td>
<td style="display:none;"></td>
</tr>
<tr>
Expand Down
5 changes: 3 additions & 2 deletions pkg/client/html_templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ func (c *Client) getFuncMap() template.FuncMap {

return date.String()
},
"fortune": Fortune,
"todaysemoji": mnd.TodaysEmoji,
"fortune": Fortune,
// returns the current time.
"now": time.Now,
// returns an integer divided by a million.
Expand Down Expand Up @@ -142,7 +143,7 @@ func (c *Client) getFuncMap() template.FuncMap {
}
return "0"
},
"one259": func() (num []float64) {
"one259": func() (num []float64) { // 1 to 59
for i := float64(1); i < 60; i++ {
num = append(num, i)
}
Expand Down
61 changes: 30 additions & 31 deletions pkg/client/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package client

import (
"context"
"errors"
"fmt"
"html/template"
"net/http"
Expand All @@ -24,6 +23,7 @@ import (
"github.com/Notifiarr/notifiarr/pkg/update"
"github.com/Notifiarr/notifiarr/pkg/website"
"github.com/gorilla/securecookie"
"github.com/hako/durafmt"
flag "github.com/spf13/pflag"
"golift.io/version"
)
Expand Down Expand Up @@ -120,8 +120,9 @@ func (c *Client) start() error { //nolint:cyclop
}

c.Logger.SetupLogging(c.Config.LogConfig)
c.Printf("%s v%s-%s Starting! [PID: %v] %v",
c.Flags.Name(), version.Version, version.Revision, os.Getpid(), time.Now())
c.Printf(" %s %s v%s-%s Starting! [PID: %v] %s",
mnd.TodaysEmoji(), c.Flags.Name(), version.Version, version.Revision, os.Getpid(),
version.Started.Format("Monday, January 2, 2006 @ 3:04:05 PM MST -0700"))
c.Printf("==> %s", msg)

c.printUpdateMessage()
Expand Down Expand Up @@ -245,6 +246,12 @@ func (c *Client) triggerConfigReload(event website.EventType, source string) {

// Exit stops the web server and logs our exit messages. Start() calls this.
func (c *Client) Exit() error {
defer func() {
defer c.CapturePanic()
//nolint:gomnd
c.Print(" ❌ Good bye! Uptime:", durafmt.Parse(time.Since(version.Started).Round(time.Second)).LimitFirstN(3))
}()

c.StartWebServer()
c.setSignals()

Expand All @@ -257,7 +264,7 @@ func (c *Client) Exit() error {
}
case sigc := <-c.sigkil:
c.Printf("[%s] Need help? %s\n=====> Exiting! Caught Signal: %v", c.Flags.Name(), mnd.HelpLink, sigc)
return c.exit()
return c.stop(website.EventSignal)
case sigc := <-c.sighup:
if err := c.checkReloadSignal(sigc); err != nil {
return err // reloadConfiguration()
Expand All @@ -266,41 +273,19 @@ func (c *Client) Exit() error {
}
}

// This is called from at least two different exit points.
func (c *Client) exit() error {
if c.server == nil {
return nil
}

ctx, cancel := context.WithTimeout(context.Background(), c.Config.Timeout.Duration)
defer cancel()

if err := c.server.Shutdown(ctx); err != nil {
return fmt.Errorf("server shutdown failed: %w", err)
}

c.server = nil

return nil
}

// reloadConfiguration is called from a menu tray item or when a HUP signal is received.
// Re-reads the configuration file and stops/starts all the internal routines.
// Also closes and re-opens all log files. Any errors cause the application to exit.
func (c *Client) reloadConfiguration(event website.EventType, source string) error {
c.Printf("==> Reloading Configuration (%s): %s", event, source)
c.closeDynamicTimerMenus()
c.triggers.Stop(event)
c.Config.Services.Stop()
c.website.Stop()

err := c.StopWebServer()
if err != nil && !errors.Is(err, ErrNoServer) {
err := c.stop(event)
if err != nil {
return fmt.Errorf("stoping web server: %w", err)
} else if err == nil {
defer c.StartWebServer()
}

defer c.StartWebServer()

// start over.
c.Config = configfile.NewConfig(c.Logger)
if c.website, c.triggers, err = c.Config.Get(c.Flags); err != nil {
Expand All @@ -314,11 +299,25 @@ func (c *Client) reloadConfiguration(event website.EventType, source string) err
c.Logger.SetupLogging(c.Config.LogConfig)
clientInfo := c.configureServices()
c.setupMenus(clientInfo)
c.Print("==> Configuration Reloaded! Config File:", c.Flags.ConfigFile)
c.Print(" 🔄 Configuration Reloaded! Config File:", c.Flags.ConfigFile)

if err = ui.Notify("Configuration Reloaded! Config File: %s", c.Flags.ConfigFile); err != nil {
c.Errorf("Creating Toast Notification: %v", err)
}

return nil
}

// stop is called from at least two different exit points and on reload.
func (c *Client) stop(event website.EventType) error {
defer func() {
defer c.CapturePanic()
c.closeDynamicTimerMenus()
c.triggers.Stop(event)
c.Config.Services.Stop()
c.website.Stop()
c.Print("==> All systems powered down!")
}()

return c.StopWebServer()
}
2 changes: 1 addition & 1 deletion pkg/client/tray.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (c *Client) startTray(clientInfo *website.ClientInfo) {
}
}, func() {
// This code only fires from menu->quit.
if err := c.exit(); err != nil {
if err := c.stop(website.EventUser); err != nil {
c.Errorf("Server: %v", err)
os.Exit(1) // web server problem
}
Expand Down
7 changes: 3 additions & 4 deletions pkg/client/webserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ import (
apachelog "github.com/lestrrat-go/apache-logformat"
)

// ErrNoServer returns when the server is already stopped and a stop req occurs.
var ErrNoServer = fmt.Errorf("the web server is not running, cannot stop it")

// StartWebServer starts the web server.
func (c *Client) StartWebServer() {
c.Lock()
Expand Down Expand Up @@ -81,6 +78,8 @@ func (c *Client) runWebServer() {

// StopWebServer stops the web servers. Panics if that causes an error or timeout.
func (c *Client) StopWebServer() error {
c.Print("==> Stopping Web Server!")

ctx, cancel := context.WithTimeout(context.Background(), c.Config.Timeout.Duration)
defer cancel()

Expand Down Expand Up @@ -125,7 +124,7 @@ func (r *responseWrapper) Write(b []byte) (int, error) {
func (r *responseWrapper) Hijack() (net.Conn, *bufio.ReadWriter, error) {
hijack, ok := r.ResponseWriter.(http.Hijacker)
if !ok {
return nil, nil, ErrNoServer
panic("cannot hijack connection!")
}

conn, buf, err := hijack.Hijack()
Expand Down
2 changes: 1 addition & 1 deletion pkg/mnd/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const (
Bits32 = 32
Windows = "windows"
Disabled = "disabled"
HelpLink = "GoLift Discord: https://golift.io/discord"
HelpLink = "Notifiarr Discord: https://notifiarr.com/discord"
UserRepo = "Notifiarr/notifiarr"
BugIssue = "This is a bug please report it on github: https://github.com/" + UserRepo + "/issues/new"
DockerV = "NOTIFIARR_IN_DOCKER"
Expand Down
64 changes: 64 additions & 0 deletions pkg/mnd/emoji.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package mnd

import (
"time"

"golift.io/version"
)

const (
leapDay = 60 // day of year leap day falls on.
altLeapDay = 366
)

func today(when time.Time) int {
switch today := when.YearDay(); {
case !leapYear(when.Year()), today < leapDay:
return today
case today == leapDay:
return altLeapDay
default:
return today - 1
}
}

func leapYear(year int) bool {
return year%400 == 0 || (year%4 == 0 && year%100 != 0)
}

func emojiMonth(when time.Time) string {
return map[time.Month]string{
time.January: "🤖", //
time.February: "😻", //
time.March: "🗼", //
time.April: "🌧", //
time.May: "🌸", //
time.June: "🍄", //
time.July: "🌵", //
time.August: "🔥", //
time.September: "🐸", //
time.October: "🍁", //
time.November: "👽", //
time.December: "⛄", //
}[when.Month()]
}

// TodaysEmoji returns an emoji specific to the month (or perhaps date).
func TodaysEmoji() string {
if emoji, ok := map[int]string{
1: "🎉", // January 1
45: "💝", // February 14
185: "🧨", // July 4
229: "🏄", // August 17
254: "⛑", // September 11
304: "🎃", // October 31
315: "🪖", // November 11
328: "🦃", // November 24
359: "🎄", // December 25
altLeapDay: "🤹", // February 29 (Leap Day)
}[today(version.Started)]; ok {
return emoji
}

return emojiMonth(version.Started)
}
8 changes: 5 additions & 3 deletions pkg/services/apps.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package services

import (
"net/url"
"strings"

"golift.io/cnfg"
Expand Down Expand Up @@ -193,10 +194,11 @@ func (c *Config) collectDownloadApps(svcs []*Service) []*Service { //nolint:funl
}

prefix := "" // add auth to the url here. woo, hacky, but it works!

if !strings.Contains(app.Config.URL, "@") {
prefix = "http://" + app.User + ":" + app.Pass + "@"
if strings.HasPrefix(app.Config.URL, "https://") {
prefix = "https://" + app.User + ":" + app.Pass + "@"
user := url.PathEscape(app.User) + ":" + url.PathEscape(app.Pass) + "@"
if prefix = "http://" + user; strings.HasPrefix(app.Config.URL, "https://") {
prefix = "https://" + user
}
}

Expand Down
1 change: 1 addition & 0 deletions pkg/services/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type Config struct {
triggerChan chan website.EventType
checkChan chan triggerCheck
stopLock sync.Mutex
lastUpdate time.Time // last time we sent service states to website.
}

// CheckType locks us into a few specific types of checks.
Expand Down
20 changes: 13 additions & 7 deletions pkg/services/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ func (c *Config) runCheck(svc *Service, force bool) bool {
}

// runChecks runs checks that are due. Passing true, runs them even if they're not due.
func (c *Config) runChecks(forceAll bool) {
func (c *Config) runChecks(forceAll bool) bool {
if c.checks == nil || c.done == nil {
return
return false
}

count := 0
Expand All @@ -79,12 +79,14 @@ func (c *Config) runChecks(forceAll bool) {
somethingChanged = <-c.done || somethingChanged
}

if somethingChanged {
c.updateStatesOnSite()
}
return somethingChanged
}

func (c *Config) updateStatesOnSite() {
func (c *Config) updateStatesOnSite(force bool) {
if !force && time.Since(c.lastUpdate) < time.Hour {
return
}

var (
err error
values = make(map[string][]byte)
Expand All @@ -102,11 +104,15 @@ func (c *Config) updateStatesOnSite() {
}

if len(values) == 0 {
c.Printf("No service states to send updates to website? Weird.")
return
}

if err := c.Website.SetValues(values); err != nil {
c.Errorf("Setting Service States on Notifiarr.com: %v", err)
c.Errorf("Setting Service States on website: %v", err)
} else {
c.lastUpdate = time.Now()
c.Printf("==> Updated [internal] Service States on website.")
}
}

Expand Down
Loading

0 comments on commit 3e87d0f

Please sign in to comment.