From d7c3c38d2417270074b4d1cc957779098ceaa8a9 Mon Sep 17 00:00:00 2001 From: Laurence Date: Wed, 8 Apr 2026 14:13:13 +0100 Subject: [PATCH] fix: allow empty config file bootstrap before provisioning Treat an empty CONFIG_FILE as initial state instead of failing JSON parse, so provisioning can proceed and credentials can be saved. Ref: fosrl/pangolin#2812 --- websocket/config.go | 5 +++++ websocket/config_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 websocket/config_test.go diff --git a/websocket/config.go b/websocket/config.go index 39f1bd2..f24f65a 100644 --- a/websocket/config.go +++ b/websocket/config.go @@ -71,6 +71,11 @@ func (c *Client) loadConfig() error { } return err } + if len(bytes.TrimSpace(data)) == 0 { + logger.Info("Config file at %s is empty, will initialize it with provided values", configPath) + c.configNeedsSave = true + return nil + } var config Config if err := json.Unmarshal(data, &config); err != nil { diff --git a/websocket/config_test.go b/websocket/config_test.go new file mode 100644 index 0000000..b2d8a24 --- /dev/null +++ b/websocket/config_test.go @@ -0,0 +1,35 @@ +package websocket + +import ( + "os" + "path/filepath" + "testing" +) + +func TestLoadConfig_EmptyFileMarksConfigForSave(t *testing.T) { + t.Setenv("CONFIG_FILE", "") + + tmpDir := t.TempDir() + configPath := filepath.Join(tmpDir, "config.json") + if err := os.WriteFile(configPath, []byte(""), 0o644); err != nil { + t.Fatalf("failed to create empty config file: %v", err) + } + + client := &Client{ + config: &Config{ + Endpoint: "https://example.com", + ProvisioningKey: "spk-test", + }, + clientType: "newt", + configFilePath: configPath, + } + + if err := client.loadConfig(); err != nil { + t.Fatalf("loadConfig returned error for empty file: %v", err) + } + + if !client.configNeedsSave { + t.Fatal("expected empty config file to mark configNeedsSave") + } +} +