Просмотр исходного кода

load env file at application startup

Replace the run scripts run.sh and run.cmd that load settings from the
config files settings.env and settings.bat with a scheme the loads a
single env file from the application at startup for all platforms.

The impetus for this was that there was no way to make starting RAS
one-click under Windows using a script that could be codesigned. The
existing run.cmd file could not be codesigned, so the user was always
confronted with running an application from an "unknown" developer. The
next best option was to rewrite run.cmd as a powershell script, which
can be codesigned. This was not a great option because you can not start
a powershell script by default by double-clicking it. You have to
instead right-click the script and click "run in powershell".

In order to streamline the user experience, I wanted to find a way to
start a codesigned application with a double-click. The best option,
implemented in this commit, is to load the settings file at startup
within the signed golang application.

As a result, we have less configuration to maintain, and Windows users
will be able to more easily start the application, while still retaining
the ability to configure the application via environment variables.
Mike 1 год назад
Родитель
Сommit
bb42dce23c
9 измененных файлов с 39 добавлено и 140 удалено
  1. 4 10
      .goreleaser.yaml
  2. 31 15
      cmd/server/main.go
  3. 0 1
      config/config.go
  4. 0 53
      config/settings.bat
  5. 1 0
      go.mod
  6. 2 0
      go.sum
  7. 0 27
      scripts/run.cmd
  8. 0 25
      scripts/run.sh
  9. 1 9
      scripts/run_dev.sh

+ 4 - 10
.goreleaser.yaml

@@ -6,7 +6,7 @@ before:
 
 builds:
   - id: linux
-    binary: bin/retro_aim_server
+    binary: retro_aim_server
     goos:
       - linux
     goarch:
@@ -21,7 +21,7 @@ builds:
         {{- if eq .Arch "amd64"}}CC=x86_64-linux-gnu-gcc{{- end }}
         {{- if eq .Arch "arm"}}CC=arm-linux-gnueabihf-gcc{{- end }}
   - id: macos
-    binary: bin/retro_aim_server
+    binary: retro_aim_server
     goos:
       - darwin
     goarch:
@@ -34,7 +34,7 @@ builds:
         {{- if eq .Arch "amd64"}}CC=o64-clang{{- end }}
         {{- if eq .Arch "arm64"}}CC=oa64-clang{{- end }}
   - id: windows
-    binary: bin/retro_aim_server
+    binary: retro_aim_server
     goos:
       - windows
     goarch:
@@ -54,8 +54,6 @@ archives:
       - LICENSE
       - src: config/settings.env
         strip_parent: true
-      - src: scripts/run.sh
-        strip_parent: true
     name_template: >-
       {{ .Binary }}.{{ .Version }}.{{ .Os }}.
       {{- if eq .Arch "amd64" }}x86_64{{ else }}arm64_arm7_raspberry_pi{{ end }}
@@ -68,8 +66,6 @@ archives:
       - LICENSE
       - src: config/settings.env
         strip_parent: true
-      - src: scripts/run.sh
-        strip_parent: true
     name_template: >-
       {{ .Binary }}.{{ .Version }}.macos.
       {{- if eq .Arch "amd64" }}intel_x86_64{{ else }}apple_silicon{{ end }}
@@ -80,9 +76,7 @@ archives:
     wrap_in_directory: true
     files:
       - LICENSE
-      - src: config/settings.bat
-        strip_parent: true
-      - src: scripts/run.cmd
+      - src: config/settings.env
         strip_parent: true
     name_template: >-
       {{ .Binary }}.{{ .Version }}.{{ .Os }}.

+ 31 - 15
cmd/server/main.go

@@ -8,6 +8,9 @@ import (
 	"os"
 	"sync"
 
+	"github.com/joho/godotenv"
+	"github.com/kelseyhightower/envconfig"
+
 	"github.com/mk6i/retro-aim-server/config"
 	"github.com/mk6i/retro-aim-server/foodgroup"
 	"github.com/mk6i/retro-aim-server/server/http"
@@ -15,8 +18,6 @@ import (
 	"github.com/mk6i/retro-aim-server/server/oscar/handler"
 	"github.com/mk6i/retro-aim-server/server/oscar/middleware"
 	"github.com/mk6i/retro-aim-server/state"
-
-	"github.com/kelseyhightower/envconfig"
 )
 
 // Default build fields are populated by GoReleaser
@@ -26,23 +27,33 @@ var (
 	date    = "unknown"
 )
 
-func main() {
-	bld := config.Build{
-		Version: version,
-		Commit:  commit,
-		Date:    date,
-	}
-	var showVersion bool
-	flag.BoolVar(&showVersion, "version", false, "Display build information")
-	flag.BoolVar(&showVersion, "v", false, "Display build information")
+func init() {
+	cfgFile := flag.String("config", "settings.env", "Path to config file")
+	showHelp := flag.Bool("help", false, "Display help")
+	showVersion := flag.Bool("version", false, "Display build information")
+
 	flag.Parse()
-	if showVersion {
-		fmt.Printf("%-10s %s\n", "version:", bld.Version)
-		fmt.Printf("%-10s %s\n", "commit:", bld.Commit)
-		fmt.Printf("%-10s %s\n", "date:", bld.Date)
+
+	switch {
+	case *showVersion:
+		fmt.Printf("%-10s %s\n", "version:", version)
+		fmt.Printf("%-10s %s\n", "commit:", commit)
+		fmt.Printf("%-10s %s\n", "date:", date)
+		os.Exit(0)
+	case *showHelp:
+		flag.PrintDefaults()
 		os.Exit(0)
 	}
 
+	// Optionally populate environment variables with config file
+	if err := godotenv.Load(*cfgFile); err != nil {
+		fmt.Printf("Config file not found (%s). Moving on...\n", *cfgFile)
+	} else {
+		fmt.Printf("Successfully loaded config file (%s)\n", *cfgFile)
+	}
+}
+
+func main() {
 	var cfg config.Config
 	err := envconfig.Process("", &cfg)
 	if err != nil {
@@ -71,6 +82,11 @@ func main() {
 	wg.Add(7)
 
 	go func() {
+		bld := config.Build{
+			Version: version,
+			Commit:  commit,
+			Date:    date,
+		}
 		http.StartManagementAPI(bld, cfg, feedbagStore, sessionManager, feedbagStore, feedbagStore, chatSessionManager, sessionManager, feedbagStore, feedbagStore, feedbagStore, feedbagStore, logger)
 		wg.Done()
 	}()

+ 0 - 1
config/config.go

@@ -1,6 +1,5 @@
 package config
 
-//go:generate go run github.com/mk6i/retro-aim-server/cmd/config_generator windows settings.bat
 //go:generate go run github.com/mk6i/retro-aim-server/cmd/config_generator unix settings.env
 type Config struct {
 	ApiHost     string `envconfig:"API_HOST" require:"true" val:"127.0.0.1" description:"The hostname or address at which the management API listens."`

+ 0 - 53
config/settings.bat

@@ -1,53 +0,0 @@
-rem The hostname or address at which the management API listens.
-set API_HOST=127.0.0.1
-
-rem The port that the management API service binds to.
-set API_PORT=8080
-
-rem The port that the Alert service binds to.
-set ALERT_PORT=5194
-
-rem The port that the auth service binds to.
-set AUTH_PORT=5190
-
-rem The port that the BART service binds to.
-set BART_PORT=5195
-
-rem The port that the BOS service binds to.
-set BOS_PORT=5191
-
-rem The port that the chat nav service binds to.
-set CHAT_NAV_PORT=5193
-
-rem The port that the chat service binds to.
-set CHAT_PORT=5192
-
-rem The port that the admin service binds to.
-set ADMIN_PORT=5196
-
-rem The path to the SQLite database file. The file and DB schema are
-rem auto-created if they doesn't exist.
-set DB_PATH=oscar.sqlite
-
-rem Disable password check and auto-create new users at login time. Useful for
-rem quickly creating new accounts during development without having to register
-rem new users via the management API.
-set DISABLE_AUTH=true
-
-rem Crash the server in case it encounters a client message type it doesn't
-rem recognize. This makes failures obvious for debugging purposes.
-set FAIL_FAST=false
-
-rem Set logging granularity. Possible values: 'trace', 'debug', 'info', 'warn',
-rem 'error'.
-set LOG_LEVEL=info
-
-rem The hostname that AIM clients connect to in order to reach OSCAR services
-rem (auth, BOS, BUCP, etc). Make sure the hostname is reachable by all clients.
-rem For local development, the default loopback address should work provided the
-rem server and AIM client(s) are running on the same machine. For LAN-only
-rem clients, a private IP address (e.g. 192.168..) or hostname should suffice.
-rem For clients connecting over the Internet, specify your public IP address and
-rem ensure that TCP ports 5190-5196 are open on your firewall.
-set OSCAR_HOST=127.0.0.1
-

+ 1 - 0
go.mod

@@ -5,6 +5,7 @@ go 1.22
 require (
 	github.com/golang-migrate/migrate/v4 v4.17.1
 	github.com/google/uuid v1.6.0
+	github.com/joho/godotenv v1.5.1
 	github.com/kelseyhightower/envconfig v1.4.0
 	github.com/mattn/go-sqlite3 v1.14.22
 	github.com/mitchellh/go-wordwrap v1.0.1

+ 2 - 0
go.sum

@@ -9,6 +9,8 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY
 github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
 github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
 github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
+github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
+github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
 github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
 github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
 github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=

+ 0 - 27
scripts/run.cmd

@@ -1,27 +0,0 @@
-@echo off
-setlocal enabledelayedexpansion
-
-rem This script launches Retro AIM Server under Windows. Because it assumes
-rem that the executable and settings.bat file are located in the same directory
-rem as this script, the script can be run from any directory.
-
-set SCRIPT_DIR=%~dp0
-set ENV_FILE=%SCRIPT_DIR%settings.bat
-set EXEC_FILE=%SCRIPT_DIR%bin\retro_aim_server.exe
-
-rem Load the settings file.
-if exist "%ENV_FILE%" (
-    call "%ENV_FILE%"
-) else (
-    echo error: environment file '%ENV_FILE%' not found.
-    exit /b 1
-)
-
-rem Start Retro AIM Server.
-if exist "%EXEC_FILE%" (
-    echo starting...
-    start /b "" "%EXEC_FILE%"
-) else (
-    echo error: executable '%EXEC_FILE%' not found.
-    exit /b 1
-)

+ 0 - 25
scripts/run.sh

@@ -1,25 +0,0 @@
-#!/bin/sh
-# This script launches Retro AIM Server under MacOS/Linux. Because it assumes
-# that the executable and settings.env file are located in the same directory
-# as this script, the script can be run from any directory.
-set -e
-
-SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
-ENV_FILE="$SCRIPT_DIR/settings.env"
-EXEC_FILE="$SCRIPT_DIR/bin/retro_aim_server"
-
-# Load the settings file.
-if [ -f "$ENV_FILE" ]; then
-    . "$ENV_FILE"
-else
-    echo "error: environment file '$ENV_FILE' not found."
-    exit 1
-fi
-
-# Start Retro AIM Server.
-if [ -f "$EXEC_FILE" ]; then
-    "$EXEC_FILE"
-else
-    echo "error: executable '$EXEC_FILE' not found."
-    exit 1
-fi

+ 1 - 9
scripts/run_dev.sh

@@ -9,14 +9,6 @@ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
 ENV_FILE="$SCRIPT_DIR/../config/settings.env"
 REPO_ROOT="$SCRIPT_DIR/.."
 
-# Load the settings file.
-if [ -f "$ENV_FILE" ]; then
-    . "$ENV_FILE"
-else
-    echo "error: environment file '$ENV_FILE' not found."
-    exit 1
-fi
-
 # Run Retro AIM Server from repo root.
 cd "$REPO_ROOT"
-go run -v ./cmd/server
+go run -v ./cmd/server -config "$ENV_FILE"