Skip to content

Commit

Permalink
save input for later use
Browse files Browse the repository at this point in the history
  • Loading branch information
davidnewhall committed Aug 3, 2024
1 parent 93a0cd0 commit d52a948
Show file tree
Hide file tree
Showing 15 changed files with 1,209 additions and 1,194 deletions.
1,912 changes: 956 additions & 956 deletions pkg/bindata/templates/config.html

Large diffs are not rendered by default.

330 changes: 165 additions & 165 deletions pkg/bindata/templates/triggers.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pkg/client/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func (c *Client) handleAptHook(ctx context.Context) error { //nolint:cyclop
} //nolint:wsl
}

resp, _, err := c.website.RawGetData(ctx, &website.Request{
resp, _, err := c.Config.Services.Website.RawGetData(ctx, &website.Request{
Route: website.PkgRoute,
Event: "apt",
Payload: output,
Expand Down
6 changes: 3 additions & 3 deletions pkg/client/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ func (c *Client) httpGuiHandlers(base string, compress func(handler http.Handler

// httpAPIHandlers initializes API routes.
func (c *Client) httpAPIHandlers() {
c.Config.HandleAPIpath("", "info", c.clientinfo.InfoHandler, "GET", "HEAD")
c.Config.HandleAPIpath("", "version", c.clientinfo.VersionHandler, "GET", "HEAD")
c.Config.HandleAPIpath("", "version/{app}/{instance:[0-9]+}", c.clientinfo.VersionHandlerInstance, "GET", "HEAD")
c.Config.HandleAPIpath("", "info", c.triggers.CI.InfoHandler, "GET", "HEAD")
c.Config.HandleAPIpath("", "version", c.triggers.CI.VersionHandler, "GET", "HEAD")
c.Config.HandleAPIpath("", "version/{app}/{instance:[0-9]+}", c.triggers.CI.VersionHandlerInstance, "GET", "HEAD")
c.Config.HandleAPIpath("", "trigger/{trigger:[0-9a-z-]+}", c.triggers.APIHandler, "GET", "POST")
c.Config.HandleAPIpath("", "trigger/{trigger:[0-9a-z-]+}/{content}", c.triggers.APIHandler, "GET", "POST")
c.Config.HandleAPIpath("", "services/{action}", c.Config.Services.APIHandler, "GET")
Expand Down
22 changes: 16 additions & 6 deletions pkg/client/handlers_gui.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/shirou/gopsutil/v4/disk"
"github.com/swaggo/swag"
"github.com/vearutop/statigz"
"golift.io/cnfgfile"
"golift.io/version"
)

Expand Down Expand Up @@ -716,20 +717,29 @@ func (c *Client) mergeAndValidateNewConfig(config *configfile.Config, request *h
return fmt.Errorf("decoding POST data into Go data structure failed: %w", err)
}

if err := c.validateNewCommandConfig(config); err != nil {
return err
}

return c.validateNewServiceConfig(config)
return c.validateNewConfig(config)
}

func (c *Client) validateNewCommandConfig(config *configfile.Config) error {
func (c *Client) validateNewConfig(config *configfile.Config) error {
for idx, cmd := range config.Commands {
if err := cmd.SetupRegexpArgs(); err != nil {
return fmt.Errorf("command %d '%s' failed setup: %w", idx+1, cmd.Name, err)
}
}

if err := c.validateNewServiceConfig(config); err != nil {
return err
}

copied, err := config.CopyConfig()
if err != nil {
return fmt.Errorf("copying config: %w", err)
}

if _, err := cnfgfile.Parse(copied, nil); err != nil {
return fmt.Errorf("filepath: %w", err)
}

return nil
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/client/handlers_plex.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (c *Client) PlexHandler(w http.ResponseWriter, r *http.Request) { //nolint:
case strings.EqualFold(hook.Event, "admin.database.corrupt"):
c.Printf("Plex Incoming Webhook: %s, %s '%s' ~> %s (relaying to Notifiarr)",
hook.Server.Title, hook.Account.Title, hook.Event, hook.Metadata.Title)
c.website.SendData(&website.Request{
c.Config.Services.Website.SendData(&website.Request{
Route: website.PlexRoute,
Event: website.EventHook,
LogPayload: true,
Expand Down
4 changes: 3 additions & 1 deletion pkg/client/html_templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ func (c *Client) parseCustomTemplates() error {
}

type templateData struct {
Input *configfile.Config `json:"input"`
Config *configfile.Config `json:"config"`
Flags *configfile.Flags `json:"flags"`
Actions *triggers.Actions `json:"actions"`
Expand Down Expand Up @@ -485,7 +486,7 @@ func (c *Client) renderTemplate( //nolint:funlen

binary, _ := os.Executable()
userName, dynamic := c.getUserName(req)
hostInfo, _ := c.website.GetHostInfo(ctx)
hostInfo, _ := c.Config.Services.Website.GetHostInfo(ctx)
backupPath := filepath.Join(filepath.Dir(c.Flags.ConfigFile), "backups", filepath.Base(c.Flags.ConfigFile))
outboundIP := clientinfo.GetOutboundIP()
ifName, netmask := getIfNameAndNetmask(outboundIP)
Expand All @@ -495,6 +496,7 @@ func (c *Client) renderTemplate( //nolint:funlen
UpstreamIP: strings.Trim(req.RemoteAddr[:strings.LastIndex(req.RemoteAddr, ":")], "[]"),
Actions: c.triggers,
Config: c.Config,
Input: c.Input,
Flags: c.Flags,
Username: userName,
Dynamic: dynamic,
Expand Down
6 changes: 3 additions & 3 deletions pkg/client/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (c *Client) PrintStartupInfo(ctx context.Context, clientInfo *clientinfo.Cl
clientInfo = &clientinfo.ClientInfo{}
}

switch host, err := c.website.GetHostInfo(ctx); {
switch host, err := c.Config.Services.Website.GetHostInfo(ctx); {
case err != nil:
c.Errorf("=> Unknown Host Info (this is bad): %v", err)
case c.Config.HostID == "":
Expand Down Expand Up @@ -81,7 +81,7 @@ func (c *Client) PrintStartupInfo(ctx context.Context, clientInfo *clientinfo.Cl
func (c *Client) printVersionChangeInfo(ctx context.Context) {
const clientVersion = "clientVersion"

values, err := c.website.GetState(ctx, clientVersion)
values, err := c.Config.Services.Website.GetState(ctx, clientVersion)
if err != nil {
c.Errorf("XX> Getting version from database: %v", err)
}
Expand All @@ -100,7 +100,7 @@ func (c *Client) printVersionChangeInfo(ctx context.Context) {
c.Printf("==> Detected application version change! %s => %s", previousVersion, currentVersion)
}

err = c.website.SetState(ctx, clientVersion, []byte(currentVersion))
err = c.Config.Services.Website.SetState(ctx, clientVersion, []byte(currentVersion))
if err != nil {
c.Errorf("Updating version in database: %v", err)
}
Expand Down
37 changes: 18 additions & 19 deletions pkg/client/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,11 @@ type Client struct {
plexTimer *cooldown.Timer
Flags *configfile.Flags
Config *configfile.Config
Input *configfile.Config
server *http.Server
sigkil chan os.Signal
sighup chan os.Signal
reload chan customReload
website *website.Server
clientinfo *clientinfo.Config
triggers *triggers.Actions
cookies *securecookie.SecureCookie
template *template.Template
Expand Down Expand Up @@ -203,11 +202,7 @@ func (c *Client) makeNewConfigFile(ctx context.Context, newPassword string) {

// loadConfiguration brings in, and sometimes creates, the initial running configuration.
func (c *Client) loadConfiguration(ctx context.Context) (string, string, error) {
var (
msg string
newPassword string
err error
)
var msg, newPassword string
// Find or write a config file. This does not parse it.
// A config file is only written when none is found on Windows, macOS (GUI App only), or Docker.
// And in the case of Docker, only if `/config` is a mounted volume.
Expand All @@ -221,20 +216,22 @@ func (c *Client) loadConfiguration(ctx context.Context) (string, string, error)
})
}

var err error
// Parse the config file and environment variables.
c.website, c.triggers, err = c.Config.Get(c.Flags, c.Logger)
if err != nil {
if c.Input, err = c.Config.Get(c.Flags); err != nil {
return msg, newPassword, fmt.Errorf("getting config: %w", err)
}

c.clientinfo = c.triggers.Timers.CIC
if c.triggers, err = c.Config.Setup(c.Flags, c.Logger); err != nil {
return msg, newPassword, fmt.Errorf("setting config: %w", err)
}

return msg, newPassword, nil
}

// Load configuration from the website.
func (c *Client) loadSiteConfig(ctx context.Context) *clientinfo.ClientInfo {
clientInfo, err := c.clientinfo.SaveClientInfo(ctx, true)
clientInfo, err := c.triggers.CI.SaveClientInfo(ctx, true)
if err != nil || clientInfo == nil {
if errors.Is(err, website.ErrInvalidAPIKey) {
c.ErrorfNoShare("==> Problem validating API key: %v", err)
Expand All @@ -249,19 +246,19 @@ func (c *Client) loadSiteConfig(ctx context.Context) *clientinfo.ClientInfo {
// Snapshot is a bit complicated because config-file data (plugins) merges with site-data (snapshot config).
clientInfo.Actions.Snapshot.Plugins = c.Config.Snapshot.Plugins
c.Config.Snapshot = &clientInfo.Actions.Snapshot
c.triggers.Timers.Snapshot = c.Config.Snapshot
c.triggers.Snapshot = c.Config.Snapshot
c.Config.Services.Plugins = &c.Config.Snapshot.Plugins

return clientInfo
}

// configureServices is called on startup and on reload, so be careful what goes in here.
func (c *Client) configureServices(ctx context.Context) *clientinfo.ClientInfo {
c.website.Start(ctx)
c.Config.Services.Website.Start(ctx)

clientInfo := c.loadSiteConfig(ctx)
if clientInfo != nil && !clientInfo.User.StopLogs {
share.Setup(c.website)
share.Setup(c.Config.Services.Website)
}

c.configureServicesPlex(ctx)
Expand Down Expand Up @@ -337,14 +334,16 @@ func (c *Client) reloadConfiguration(ctx context.Context, event website.EventTyp

// start over.
c.Config = configfile.NewConfig(c.Logger)
if c.website, c.triggers, err = c.Config.Get(c.Flags, c.Logger); err != nil {
return fmt.Errorf("getting configuration: %w", err)
if c.Input, err = c.Config.Get(c.Flags); err != nil {
return fmt.Errorf("getting config: %w", err)
}

c.clientinfo = c.triggers.Timers.CIC
if c.triggers, err = c.Config.Setup(c.Flags, c.Logger); err != nil {
return fmt.Errorf("setting config: %w", err)
}

if errs := c.Logger.Close(); len(errs) > 0 {
return fmt.Errorf("closing logger(s): %w", errs[0])
return fmt.Errorf("closing logger: %w", errs[0])
}

defer c.StartWebServer(ctx)
Expand Down Expand Up @@ -381,7 +380,7 @@ func (c *Client) stop(ctx context.Context, event website.EventType) error {
defer c.CapturePanic()
c.triggers.Stop(event)
c.Config.Services.Stop()
c.website.Stop()
c.Config.Services.Website.Stop()
c.Print("==> All systems powered down!")
}()

Expand Down
10 changes: 5 additions & 5 deletions pkg/client/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (c *Client) startTunnel(ctx context.Context) {

func (c *Client) makeTunnel(ctx context.Context, info *clientinfo.ClientInfo) {
hostname, _ := os.Hostname()
if hostInfo, err := c.clientinfo.GetHostInfo(ctx); err != nil {
if hostInfo, err := c.triggers.CI.GetHostInfo(ctx); err != nil {
hostname = hostInfo.Hostname
}

Expand All @@ -90,8 +90,8 @@ func (c *Client) makeTunnel(ctx context.Context, info *clientinfo.ClientInfo) {
Targets: getTunnels(info),
PoolIdleSize: 1,
PoolMaxSize: c.poolMax(info),
CleanInterval: time.Second + time.Duration(c.triggers.Timers.Rand().Intn(1000))*time.Millisecond,
Backoff: 600*time.Millisecond + time.Duration(c.triggers.Timers.Rand().Intn(600))*time.Millisecond,
CleanInterval: time.Second + time.Duration(c.triggers.Rand().Intn(1000))*time.Millisecond,
Backoff: 600*time.Millisecond + time.Duration(c.triggers.Rand().Intn(600))*time.Millisecond,
SecretKey: c.Config.APIKey,
Handler: remWs.Wrap(c.prefixURLbase(c.Config.Router), c.Logger.HTTPLog.Writer()).ServeHTTP,
RoundRobinConfig: c.roundRobinConfig(info),
Expand All @@ -117,7 +117,7 @@ func (c *Client) roundRobinConfig(ci *clientinfo.ClientInfo) *mulery.RoundRobinC
Callback: func(_ context.Context, socket string) {
defer data.Save("activeTunnel", socket)
// Tell the website we connected to a new tunnel, so it knows how to reach us.
c.website.SendData(&website.Request{
c.Config.Services.Website.SendData(&website.Request{
Route: website.TunnelRoute,
Event: website.EventSignal,
Payload: map[string]interface{}{"socket": socket, "previous": data.Get("activeTunnel")},
Expand Down Expand Up @@ -311,7 +311,7 @@ func (c *Client) saveTunnels(response http.ResponseWriter, request *http.Request
}
}

c.website.SendData(&website.Request{
c.Config.Services.Website.SendData(&website.Request{
Route: website.TunnelRoute,
Event: website.EventGUI,
Payload: map[string]any{"sockets": sockets},
Expand Down
30 changes: 17 additions & 13 deletions pkg/configfile/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,41 +124,45 @@ func (c *Config) CopyConfig() (*Config, error) {
// Get parses a config file and environment variables.
// Sometimes the app runs without a config file entirely.
// You should only run this after getting a config with NewConfig().
func (c *Config) Get(flag *Flags, logger *logs.Logger) (*website.Server, *triggers.Actions, error) { //nolint:cyclop
func (c *Config) Get(flag *Flags) (*Config, error) {
if flag.ConfigFile != "" {
files := append([]string{flag.ConfigFile}, flag.ExtraConf...)
if err := cnfgfile.Unmarshal(c, files...); err != nil {
return nil, nil, fmt.Errorf("config file: %w", err)
return nil, fmt.Errorf("config file: %w", err)
}
} else if len(flag.ExtraConf) != 0 {
if err := cnfgfile.Unmarshal(c, flag.ExtraConf...); err != nil {
return nil, nil, fmt.Errorf("extra config file: %w", err)
return nil, fmt.Errorf("extra config file: %w", err)
}
}

if _, err := cnfg.UnmarshalENV(c, flag.EnvPrefix); err != nil {
return nil, nil, fmt.Errorf("environment variables: %w", err)
return nil, fmt.Errorf("environment variables: %w", err)
}

return c.CopyConfig()
}

func (c *Config) Setup(flag *Flags, logger *logs.Logger) (*triggers.Actions, error) {
if _, err := cnfgfile.Parse(c, nil); err != nil {
return nil, nil, fmt.Errorf("filepath variables: %w", err)
return nil, fmt.Errorf("filepath variables: %w", err)
}

if err := c.setupPassword(); err != nil {
return nil, nil, err
return nil, err
}

c.fixConfig()
logger.LogConfig = c.LogConfig // this is sorta hacky.

err := c.Services.Setup(c.Service)
if err != nil {
return nil, nil, fmt.Errorf("service checks: %w", err)
if err := c.Services.Setup(c.Service); err != nil {
return nil, fmt.Errorf("service checks: %w", err)
}

// Make sure each app has a sane timeout.
if err := c.Apps.Setup(); err != nil {
return nil, nil, fmt.Errorf("setting up app: %w", err)
err := c.Apps.Setup()
if err != nil {
return nil, fmt.Errorf("setting up app: %w", err)
}

// Make sure the port is not in use before starting the web server.
Expand All @@ -179,7 +183,7 @@ func (c *Config) Get(flag *Flags, logger *logs.Logger) (*website.Server, *trigge
BindAddr: c.BindAddr,
})

return c.Services.Website, c.setup(logger, flag), err
return c.setup(logger, flag), err
}

func (c *Config) fixConfig() {
Expand Down Expand Up @@ -223,7 +227,7 @@ func (c *Config) setup(logger *logs.Logger, flag *Flags) *triggers.Actions {
WatchFiles: c.WatchFiles,
LogFiles: c.LogConfig.GetActiveLogFilePaths(),
Commands: c.Commands,
CIC: cic,
ClientInfo: cic,
ConfigFile: flag.ConfigFile,
AutoUpdate: c.AutoUpdate,
UnstableCh: c.UnstableCh,
Expand Down
2 changes: 1 addition & 1 deletion pkg/triggers/common/triggers.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var ErrNoChannel = errors.New("no channel to send request")
// Config is the input data shared by most triggers.
// Everything is mandatory.
type Config struct {
CIC *clientinfo.Config
CI *clientinfo.Config
*website.Server // send trigger responses to website.
Snapshot *snapshot.Config
Apps *apps.Apps
Expand Down
2 changes: 1 addition & 1 deletion pkg/triggers/crontimer/custom.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func (c *cmd) PollForReload(ctx context.Context, input *common.ActionInput) {
body, err := c.GetData(&website.Request{
Route: website.ClientRoute,
Event: website.EventPoll,
Payload: c.CIC.Info(ctx, true), // true avoids polling tautulli.
Payload: c.CI.Info(ctx, true), // true avoids polling tautulli.
LogPayload: true,
})
if err != nil {
Expand Down
Loading

0 comments on commit d52a948

Please sign in to comment.