From 9fe613b3a496cc0aafbcfa39a0d8874089a182ab Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Fri, 19 Sep 2025 19:57:24 +0200 Subject: [PATCH 1/8] set a "fake" HOME env var when running steamcmd on linux to make it not shit files into the actual users Home --- src/steamcmd/steamcmd.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/steamcmd/steamcmd.go b/src/steamcmd/steamcmd.go index 292ed1ce..7312e714 100644 --- a/src/steamcmd/steamcmd.go +++ b/src/steamcmd/steamcmd.go @@ -101,6 +101,25 @@ func runSteamCMD(steamCMDDir string) (int, error) { cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr + if runtime.GOOS == "linux" { + env := os.Environ() + // Replace or set HOME + newEnv := make([]string, 0, len(env)+1) + foundHome := false + for _, e := range env { + if !strings.HasPrefix(e, "HOME=") { + newEnv = append(newEnv, e) + } else { + newEnv = append(newEnv, "HOME="+currentDir) + foundHome = true + } + } + if !foundHome { + newEnv = append(newEnv, "HOME="+currentDir) + } + cmd.Env = newEnv + } + // Run the command if config.GetLogLevel() == 10 { cmdString := strings.Join(cmd.Args, " ") From ae1269fd71438bc2b4633c3236b80f442ee8403e Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Sat, 20 Sep 2025 11:32:39 +0200 Subject: [PATCH 2/8] added a sanity check to startup, fails gracefully if run as root or cannot write to workdir --- server.go | 7 +++++++ src/core/loader/helpers.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/server.go b/server.go index 5045ee97..475e9967 100644 --- a/server.go +++ b/server.go @@ -22,7 +22,9 @@ package main import ( "embed" + "os" "sync" + "time" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/cli" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/core/loader" @@ -38,6 +40,11 @@ func main() { var wg sync.WaitGroup logger.ConfigureConsole() loader.SetupWorkingDir() + if err := loader.SanityCheck(); err != nil { + logger.Main.Error("Sanity check failed, exiting in 10 secconds: " + err.Error()) + time.Sleep(10 * time.Second) + os.Exit(1) + } logger.Main.Debug("Initializing resources...") loader.InitVirtFS(v1uiFS) logger.Install.Info("Starting setup...") diff --git a/src/core/loader/helpers.go b/src/core/loader/helpers.go index 29e129fa..724c7d37 100644 --- a/src/core/loader/helpers.go +++ b/src/core/loader/helpers.go @@ -195,3 +195,39 @@ func SetupWorkingDir() error { } return nil } + +func SanityCheck() error { + + if runtime.GOOS == "windows" { + return nil + } + // Check if running as root (UID 0) + if os.Geteuid() == 0 { + return fmt.Errorf("root: SSUI should not be run as root") + } + + // Check if current working directory is writable + workDir, err := os.Getwd() + if err != nil { + return fmt.Errorf("failed to get working directory: %w", err) + } + + // Try to create a temporary file to test write permissions + testFile := filepath.Join(workDir, ".write_test") + if err := os.WriteFile(testFile, []byte("test"), 0600); err != nil { + return fmt.Errorf("cannot write to working directory %s: %w", workDir, err) + } + // Clean up test file + if err := os.Remove(testFile); err != nil { + return fmt.Errorf("failed to clean up sanity check writetest file: %w", err) + } + + // Check if steamcmd package is installed (requires further testing, disabled for now) + //cmd := exec.Command("dpkg-query", "-W", "-f='${Status}'", "steamcmd") + //output, err := cmd.CombinedOutput() + //if err == nil && strings.Contains(string(output), "install ok installed") { + // return fmt.Errorf("steamcmd package is installed") + //} + + return nil +} From a978ef4eae43ee7b2c026397d29122c0fda6aabb Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Sat, 20 Sep 2025 11:41:50 +0200 Subject: [PATCH 3/8] added a -SkipSteamCMD (-nosteam) arg --- .vscode/launch.json | 10 ++++++++++ src/config/getters.go | 6 ++++++ src/config/setters.go | 8 ++++++++ src/config/vars.go | 1 + src/core/loader/cmdargs.go | 7 +++++++ src/setup/install.go | 4 +++- 6 files changed, 35 insertions(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 5e1d543e..9b4ebad8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -19,6 +19,16 @@ "program": "${workspaceFolder}/server.go", "console": "integratedTerminal", "showLog": false, // Hides some Go Debugger(Delve) log stuff that is not useful for debugging atm + }, + { + "name": "Debug Go Server noSteamCMD noSvelte", + "type": "go", + "request": "launch", + "mode": "debug", + "program": "${workspaceFolder}/server.go", + "console": "integratedTerminal", + "showLog": false, // Hides some Go Debugger(Delve) log stuff that is not useful for debugging atm + "args": ["--SkipSteamCMD"] } ] } \ No newline at end of file diff --git a/src/config/getters.go b/src/config/getters.go index 936a4bbd..bbc9e402 100644 --- a/src/config/getters.go +++ b/src/config/getters.go @@ -493,3 +493,9 @@ func GetExtractedGameVersion() string { defer ConfigMu.RUnlock() return ExtractedGameVersion } + +func GetSkipSteamCMD() bool { + ConfigMu.RLock() + defer ConfigMu.RUnlock() + return SkipSteamCMD +} diff --git a/src/config/setters.go b/src/config/setters.go index 401b53c5..2f9bd5fd 100644 --- a/src/config/setters.go +++ b/src/config/setters.go @@ -46,6 +46,14 @@ func SetExtractedGameVersion(value string) error { return nil } +func SetSkipSteamCMD(value bool) error { + ConfigMu.Lock() + defer ConfigMu.Unlock() + + SkipSteamCMD = value + return nil +} + // ALL SETTERS BELOW THIS LINE ARE UNUSED AT THE MOMENT // ALL SETTERS BELOW THIS LINE ARE UNUSED AT THE MOMENT // ALL SETTERS BELOW THIS LINE ARE UNUSED AT THE MOMENT diff --git a/src/config/vars.go b/src/config/vars.go index 0ba6fb1a..41c84f42 100644 --- a/src/config/vars.go +++ b/src/config/vars.go @@ -63,6 +63,7 @@ var ( SSUIIdentifier string CurrentBranchBuildID string // ONLY RUNTIME ExtractedGameVersion string // ONLY RUNTIME + SkipSteamCMD bool // ONLY RUNTIME ) // Discord integration diff --git a/src/core/loader/cmdargs.go b/src/core/loader/cmdargs.go index 787d63e9..e1a950b5 100644 --- a/src/core/loader/cmdargs.go +++ b/src/core/loader/cmdargs.go @@ -21,6 +21,7 @@ func LoadCmdArgs() { var createSSUILogFile bool var recoveryPassword string var devMode bool + var skipSteamCMD bool flag.StringVar(&backendEndpointPort, "BackendEndpointPort", "", "Override the backend endpoint port (e.g., 8080)") flag.StringVar(&backendEndpointPort, "p", "", "(Alias) Override the backend endpoint port (e.g., 8080)") @@ -35,6 +36,8 @@ func LoadCmdArgs() { flag.BoolVar(&isDebugMode, "debug", false, "(Alias) Enable debug mode") flag.BoolVar(&createSSUILogFile, "CreateSSUILogFile", false, "Create a log file for SSUI") flag.BoolVar(&createSSUILogFile, "lf", false, "(Alias) Create a log file for SSUI") + flag.BoolVar(&skipSteamCMD, "SkipSteamCMD", false, "Skips SteamCMD installation") + flag.BoolVar(&skipSteamCMD, "nosteam", false, "(Alias) Skips SteamCMD installation") // Parse command-line flags flag.Parse() @@ -47,6 +50,10 @@ func LoadCmdArgs() { logger.Main.Info("Dev mode enabled: Auth enabled, admin user set to admin:admin:superadmin, console enabled") } + if skipSteamCMD { + config.SetSkipSteamCMD(true) + } + if backendEndpointPort != "" && backendEndpointPort != "8443" { oldPort := config.GetSSUIWebPort() config.SetSSUIWebPort(backendEndpointPort) diff --git a/src/setup/install.go b/src/setup/install.go index 12a33e80..dad418ad 100644 --- a/src/setup/install.go +++ b/src/setup/install.go @@ -42,7 +42,9 @@ func Install(wg *sync.WaitGroup) { logger.Install.Info("✅Blacklist.txt verified or created.") // Step 3: Install and run SteamCMD logger.Install.Info("🔄Installing and running SteamCMD...") - if config.GetBranch() != "indev-no-steamcmd" { + if config.GetSkipSteamCMD() { + logger.Install.Info("✅Skipping SteamCMD installation, SkipSteamCMD is true") + } else { steamcmd.InstallAndRunSteamCMD() } logger.Install.Info("✅Setup complete!") From aa8f2309750011c78f32e627e1602535df6c6df3 Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Sat, 20 Sep 2025 12:11:58 +0200 Subject: [PATCH 4/8] added new Steam "home" to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a2349175..ecfce688 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ UIMod/tls/cert.pem UIMod/tls/key.pem steamapps/** steamcmd/** +Steam/** rocketstation_BurstDebugInformation_DoNotShip/** StationeersServerControlv* UnityPlayer.so From 4c1def9d2d5043620f8b5c08917c2f1bb7143f42 Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Sat, 20 Sep 2025 12:13:16 +0200 Subject: [PATCH 5/8] combined SetupWorkingDir and SanityCheck, fixed go builds in /tmp using wrong wd in testing --- server.go | 1 - src/core/loader/helpers.go | 52 +++++++++++++++----------------------- 2 files changed, 21 insertions(+), 32 deletions(-) diff --git a/server.go b/server.go index 475e9967..eaac0cfd 100644 --- a/server.go +++ b/server.go @@ -39,7 +39,6 @@ var v1uiFS embed.FS func main() { var wg sync.WaitGroup logger.ConfigureConsole() - loader.SetupWorkingDir() if err := loader.SanityCheck(); err != nil { logger.Main.Error("Sanity check failed, exiting in 10 secconds: " + err.Error()) time.Sleep(10 * time.Second) diff --git a/src/core/loader/helpers.go b/src/core/loader/helpers.go index 724c7d37..d8497154 100644 --- a/src/core/loader/helpers.go +++ b/src/core/loader/helpers.go @@ -165,47 +165,37 @@ func PrintConfigDetails(logLevel ...string) { logger.Config.Debug("=======================================") } -// SetupWorkingDir sets the working directory to the directory of the executable to prevent user errors -func SetupWorkingDir() error { - if runtime.GOOS == "windows" { - // For now Windows doesn't have symlinking issues so we'll just let is use the current working directory - return nil - } - if runtime.GOOS == "linux" { - // Get the current executable path from /proc/self/exe - exePath, err := os.Readlink("/proc/self/exe") - if err != nil { - return err - } - // Get the directory path of the executable - dirPath := filepath.Dir(exePath) - // Change the working directory to the executable's directory - cwd, err := os.Getwd() - if err != nil { - return err - } - if cwd != dirPath { - logger.Core.Debug("Changing working directory to " + dirPath) - err = os.Chdir(dirPath) - if err != nil { - return err - } - } - return nil - } - return nil -} - func SanityCheck() error { if runtime.GOOS == "windows" { return nil } + // Check if running as root (UID 0) if os.Geteuid() == 0 { return fmt.Errorf("root: SSUI should not be run as root") } + // Get the current executable path from /proc/self/exe + exePath, err := os.Readlink("/proc/self/exe") + if err != nil { + return err + } + // Get the directory path of the executable + dirPath := filepath.Dir(exePath) + // Change the working directory to the executable's directory + cwd, err := os.Getwd() + if err != nil { + return err + } + + if cwd != dirPath && !strings.Contains(dirPath, "/tmp") { + err = os.Chdir(dirPath) + if err != nil { + return err + } + } + // Check if current working directory is writable workDir, err := os.Getwd() if err != nil { From 6581708bb9a76f8945d7d5ae300e58f43ab71f50 Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Sat, 20 Sep 2025 12:18:47 +0200 Subject: [PATCH 6/8] updated getAppInfo to use the new "fake" home in the SSUI dir too --- src/steamcmd/getappinfo.go | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/steamcmd/getappinfo.go b/src/steamcmd/getappinfo.go index ba6c6f89..53e68541 100644 --- a/src/steamcmd/getappinfo.go +++ b/src/steamcmd/getappinfo.go @@ -4,10 +4,12 @@ import ( "bytes" "fmt" "maps" + "os" "os/exec" "path/filepath" "regexp" "runtime" + "strings" "sync" "time" @@ -64,6 +66,13 @@ func AppInfoPoller() { // getAppInfo fetches the branches and their build IDs for the specified app ID using SteamCMD // and stores them in the package-level branches map. func getAppInfo() error { + + currentDir, err := os.Getwd() + if err != nil { + logger.Install.Error("❌ Error getting current working directory: " + err.Error() + "\n") + return err + } + if steamMu.TryLock() { // Successfully acquired the lock; no other func holds it logger.Core.Debug("🔄 Locking SteamMu for SteamCMD AppInfo...") @@ -90,14 +99,32 @@ func getAppInfo() error { cmd.Stdout = &stdout cmd.Stderr = &stderr + if runtime.GOOS == "linux" { + env := os.Environ() + // Replace or set HOME + newEnv := make([]string, 0, len(env)+1) + foundHome := false + for _, e := range env { + if !strings.HasPrefix(e, "HOME=") { + newEnv = append(newEnv, e) + } else { + newEnv = append(newEnv, "HOME="+currentDir) + foundHome = true + } + } + if !foundHome { + newEnv = append(newEnv, "HOME="+currentDir) + } + cmd.Env = newEnv + } + // Log the command //if config.GetLogLevel() == 10 { // cmdString := strings.Join(cmd.Args, " ") // logger.Install.Debug("🕑 Running SteamCMD for app info: " + cmdString) //} - // Run the command - err := cmd.Run() + err = cmd.Run() if err != nil { if exitErr, ok := err.(*exec.ExitError); ok { logger.Install.Errorf("❌ SteamCMD app info failed (code %d): %s\n", exitErr.ExitCode(), stderr.String()) From 70bca7e461d2fc25473bd85b2f8ff241e0051e0a Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Sun, 21 Sep 2025 04:46:32 +0200 Subject: [PATCH 7/8] added IsDockerContainer config var and used it in sanitycheck to allow running as root in docker container. Added getter and setter acordingly. --- server.go | 9 +--- src/config/setters.go | 8 ++++ src/config/vars.go | 12 ++++-- src/core/loader/helpers.go | 79 ++++++++++++---------------------- src/core/loader/loader.go | 12 ++++++ src/core/loader/sanitycheck.go | 69 +++++++++++++++++++++++++++++ 6 files changed, 127 insertions(+), 62 deletions(-) create mode 100644 src/core/loader/sanitycheck.go diff --git a/server.go b/server.go index eaac0cfd..9f8226a4 100644 --- a/server.go +++ b/server.go @@ -22,9 +22,7 @@ package main import ( "embed" - "os" "sync" - "time" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/cli" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/core/loader" @@ -39,11 +37,8 @@ var v1uiFS embed.FS func main() { var wg sync.WaitGroup logger.ConfigureConsole() - if err := loader.SanityCheck(); err != nil { - logger.Main.Error("Sanity check failed, exiting in 10 secconds: " + err.Error()) - time.Sleep(10 * time.Second) - os.Exit(1) - } + loader.SanityCheck(&wg) + wg.Wait() logger.Main.Debug("Initializing resources...") loader.InitVirtFS(v1uiFS) logger.Install.Info("Starting setup...") diff --git a/src/config/setters.go b/src/config/setters.go index 2f9bd5fd..44a3cf9f 100644 --- a/src/config/setters.go +++ b/src/config/setters.go @@ -54,6 +54,14 @@ func SetSkipSteamCMD(value bool) error { return nil } +func SetIsDockerContainer(value bool) error { + ConfigMu.Lock() + defer ConfigMu.Unlock() + + IsDockerContainer = value + return nil +} + // ALL SETTERS BELOW THIS LINE ARE UNUSED AT THE MOMENT // ALL SETTERS BELOW THIS LINE ARE UNUSED AT THE MOMENT // ALL SETTERS BELOW THIS LINE ARE UNUSED AT THE MOMENT diff --git a/src/config/vars.go b/src/config/vars.go index 41c84f42..71a6728d 100644 --- a/src/config/vars.go +++ b/src/config/vars.go @@ -61,9 +61,15 @@ var ( LanguageSetting string AutoStartServerOnStartup bool SSUIIdentifier string - CurrentBranchBuildID string // ONLY RUNTIME - ExtractedGameVersion string // ONLY RUNTIME - SkipSteamCMD bool // ONLY RUNTIME +) + +// Runtime only variables + +var ( + CurrentBranchBuildID string // ONLY RUNTIME + ExtractedGameVersion string // ONLY RUNTIME + SkipSteamCMD bool // ONLY RUNTIME + IsDockerContainer bool // ONLY RUNTIME ) // Discord integration diff --git a/src/core/loader/helpers.go b/src/core/loader/helpers.go index d8497154..98f3ec86 100644 --- a/src/core/loader/helpers.go +++ b/src/core/loader/helpers.go @@ -1,10 +1,9 @@ package loader import ( + "bufio" "fmt" "os" - "path/filepath" - "runtime" "strings" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/config" @@ -165,59 +164,35 @@ func PrintConfigDetails(logLevel ...string) { logger.Config.Debug("=======================================") } -func SanityCheck() error { - - if runtime.GOOS == "windows" { - return nil - } - - // Check if running as root (UID 0) - if os.Geteuid() == 0 { - return fmt.Errorf("root: SSUI should not be run as root") +func IsInsideContainer() bool { + // Check .dockerenv file (Docker-specific) + if _, err := os.Stat("/.dockerenv"); err == nil { + config.SetIsDockerContainer(true) + return true } + // Check cgroup (works for Docker and other container runtimes) + return isContainerFromCGroup() +} - // Get the current executable path from /proc/self/exe - exePath, err := os.Readlink("/proc/self/exe") +func isContainerFromCGroup() bool { + file, err := os.Open("/proc/1/cgroup") if err != nil { - return err - } - // Get the directory path of the executable - dirPath := filepath.Dir(exePath) - // Change the working directory to the executable's directory - cwd, err := os.Getwd() - if err != nil { - return err - } - - if cwd != dirPath && !strings.Contains(dirPath, "/tmp") { - err = os.Chdir(dirPath) - if err != nil { - return err + return false + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := scanner.Text() + // Check for various container runtime indicators + if strings.Contains(line, "docker") || + strings.Contains(line, "containerd") || + strings.Contains(line, "kubepods") || + strings.Contains(line, "crio") || + strings.Contains(line, "libpod") { + config.SetIsDockerContainer(true) + return true } } - - // Check if current working directory is writable - workDir, err := os.Getwd() - if err != nil { - return fmt.Errorf("failed to get working directory: %w", err) - } - - // Try to create a temporary file to test write permissions - testFile := filepath.Join(workDir, ".write_test") - if err := os.WriteFile(testFile, []byte("test"), 0600); err != nil { - return fmt.Errorf("cannot write to working directory %s: %w", workDir, err) - } - // Clean up test file - if err := os.Remove(testFile); err != nil { - return fmt.Errorf("failed to clean up sanity check writetest file: %w", err) - } - - // Check if steamcmd package is installed (requires further testing, disabled for now) - //cmd := exec.Command("dpkg-query", "-W", "-f='${Status}'", "steamcmd") - //output, err := cmd.CombinedOutput() - //if err == nil && strings.Contains(string(output), "install ok installed") { - // return fmt.Errorf("steamcmd package is installed") - //} - - return nil + return false } diff --git a/src/core/loader/loader.go b/src/core/loader/loader.go index 72830a12..de1bc1c5 100644 --- a/src/core/loader/loader.go +++ b/src/core/loader/loader.go @@ -3,7 +3,9 @@ package loader import ( "embed" + "os" "sync" + "time" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/config" "github.com/JacksonTheMaster/StationeersServerUI/v5/src/discordbot" @@ -98,3 +100,13 @@ func ReloadAppInfoPoller() { func InitVirtFS(v1uiFS embed.FS) { config.SetV1UIFS(v1uiFS) } + +func SanityCheck(wg *sync.WaitGroup) { + defer wg.Done() + err := runSanityCheck() + if err != nil { + logger.Main.Error("Sanity check failed, exiting in 10 secconds: " + err.Error()) + time.Sleep(10 * time.Second) + os.Exit(1) + } +} diff --git a/src/core/loader/sanitycheck.go b/src/core/loader/sanitycheck.go new file mode 100644 index 00000000..fc5d2378 --- /dev/null +++ b/src/core/loader/sanitycheck.go @@ -0,0 +1,69 @@ +package loader + +import ( + "fmt" + "os" + "path/filepath" + "runtime" + "strings" +) + +func runSanityCheck() error { + + if runtime.GOOS == "windows" { + return nil + } + + // Check if running as root (UID 0) + if os.Geteuid() == 0 { + // Check if running inside a container + if !IsInsideContainer() { + return fmt.Errorf("root: SSUI should not be run as root") + } + } + + // Get the current executable path from /proc/self/exe + exePath, err := os.Readlink("/proc/self/exe") + if err != nil { + return err + } + // Get the directory path of the executable + dirPath := filepath.Dir(exePath) + // Change the working directory to the executable's directory + cwd, err := os.Getwd() + if err != nil { + return err + } + + if cwd != dirPath && !strings.Contains(dirPath, "/tmp") { + err = os.Chdir(dirPath) + if err != nil { + return err + } + } + + // Check if current working directory is writable + workDir, err := os.Getwd() + if err != nil { + return fmt.Errorf("failed to get working directory: %w", err) + } + + // Try to create a temporary file to test write permissions + testFile := filepath.Join(workDir, ".write_test") + if err := os.WriteFile(testFile, []byte("test"), 0600); err != nil { + return fmt.Errorf("cannot write to working directory, please make sure your user has write permissions in %s: %w", workDir, err) + } + // Clean up test file + if err := os.Remove(testFile); err != nil { + return fmt.Errorf("failed to clean up sanity check writetest file: %w", err) + } + + // Check if steamcmd package is installed (requires further testing, disabled for now) + //cmd := exec.Command("dpkg-query", "-W", "-f='${Status}'", "steamcmd") + //output, err := cmd.CombinedOutput() + //if err == nil && strings.Contains(string(output), "install ok installed") { + // return fmt.Errorf("steamcmd package is installed") + //} + + return nil +} From 362993cf536435a3521990d17ae2468104f0805f Mon Sep 17 00:00:00 2001 From: JacksonTheMaster <81807824+JacksonTheMaster@users.noreply.github.com> Date: Sun, 21 Sep 2025 05:02:09 +0200 Subject: [PATCH 8/8] increment wait group to fix panic --- src/core/loader/loader.go | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/loader/loader.go b/src/core/loader/loader.go index de1bc1c5..a92f8d3b 100644 --- a/src/core/loader/loader.go +++ b/src/core/loader/loader.go @@ -102,6 +102,7 @@ func InitVirtFS(v1uiFS embed.FS) { } func SanityCheck(wg *sync.WaitGroup) { + wg.Add(1) defer wg.Done() err := runSanityCheck() if err != nil {