Skip to content

Commit fc60871

Browse files
authored
Merge pull request #212 from flatrun/fix/nginx-upgrade-assets
fix(nginx): Refresh Lua assets during upgrades
2 parents 1b6f09c + 5ce850f commit fc60871

2 files changed

Lines changed: 111 additions & 8 deletions

File tree

internal/infra/manager.go

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -712,16 +712,55 @@ func (m *Manager) EnsureBaseNginxConfig() error {
712712
if err != nil {
713713
return err
714714
}
715-
if string(nginxConf) == string(existing) {
716-
return nil
715+
changed, err := writeFileIfChanged(confPath, nginxConf, 0644)
716+
if err != nil {
717+
return err
717718
}
718719

719-
if err := os.WriteFile(confPath, nginxConf, 0644); err != nil {
720-
return err
720+
if luaEnabled {
721+
luaDir := filepath.Join(nginxDir, "lua")
722+
if err := os.MkdirAll(luaDir, 0755); err != nil {
723+
return err
724+
}
725+
agentIP := m.GetDockerHostIP()
726+
agentPort := m.GetAgentPort()
727+
securityLua, err := templates.GetNginxSecurityLuaWithConfig(agentIP, agentPort, m.config.Security.InternalAPIToken, m.config.Security.TrustedProxies, m.config.Security.TrustCFHeader)
728+
if err != nil {
729+
return err
730+
}
731+
securityChanged, err := writeFileIfChanged(filepath.Join(luaDir, "security.lua"), securityLua, 0644)
732+
if err != nil {
733+
return err
734+
}
735+
changed = changed || securityChanged
736+
737+
trafficLua, err := templates.GetNginxTrafficLuaWithConfig(agentIP, agentPort)
738+
if err != nil {
739+
return err
740+
}
741+
trafficChanged, err := writeFileIfChanged(filepath.Join(luaDir, "traffic.lua"), trafficLua, 0644)
742+
if err != nil {
743+
return err
744+
}
745+
changed = changed || trafficChanged
746+
747+
errorPage, err := templates.GetErrorPage()
748+
if err != nil {
749+
return err
750+
}
751+
errorPagePath := filepath.Join(nginxDir, "html", ".flatrun", "error.html")
752+
if err := os.MkdirAll(filepath.Dir(errorPagePath), 0755); err != nil {
753+
return err
754+
}
755+
errorPageChanged, err := writeFileIfChanged(errorPagePath, errorPage, 0644)
756+
if err != nil {
757+
return err
758+
}
759+
changed = changed || errorPageChanged
760+
}
761+
if changed {
762+
_ = m.reloadNginx()
721763
}
722-
// Best-effort reload: the rewritten config also takes effect on the next nginx
723-
// restart, so a reload failure here (e.g. container not yet ready) is not fatal.
724-
_ = m.reloadNginx()
725764
return nil
726765
}
727766

@@ -1456,5 +1495,20 @@ func writeNginxErrorPage(nginxDir string) error {
14561495
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
14571496
return err
14581497
}
1459-
return os.WriteFile(path, content, 0644)
1498+
_, err = writeFileIfChanged(path, content, 0644)
1499+
return err
1500+
}
1501+
1502+
func writeFileIfChanged(path string, content []byte, mode os.FileMode) (bool, error) {
1503+
existing, err := os.ReadFile(path)
1504+
if err == nil && bytes.Equal(existing, content) {
1505+
return false, nil
1506+
}
1507+
if err != nil && !os.IsNotExist(err) {
1508+
return false, err
1509+
}
1510+
if err := os.WriteFile(path, content, mode); err != nil {
1511+
return false, err
1512+
}
1513+
return true, nil
14601514
}

internal/infra/manager_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"testing"
88

99
"github.com/flatrun/agent/pkg/config"
10+
"github.com/flatrun/agent/templates"
1011
)
1112

1213
func TestSetNginxRealtimeCapture(t *testing.T) {
@@ -240,6 +241,54 @@ func TestEnsureBaseNginxConfig(t *testing.T) {
240241
if !strings.Contains(string(content), "server_names_hash_bucket_size") {
241242
t.Errorf("refreshed config should contain server_names_hash_bucket_size, got:\n%s", content)
242243
}
244+
securityLua, err := os.ReadFile(filepath.Join(nginxDir, "lua", "security.lua"))
245+
if err != nil {
246+
t.Fatal(err)
247+
}
248+
if !strings.Contains(string(securityLua), "function _M.prepare_error_response()") {
249+
t.Errorf("refreshed security.lua is missing error response support")
250+
}
251+
if _, err := os.Stat(filepath.Join(nginxDir, "lua", "traffic.lua")); err != nil {
252+
t.Fatal(err)
253+
}
254+
if _, err := os.Stat(filepath.Join(nginxDir, "html", ".flatrun", "error.html")); err != nil {
255+
t.Fatal(err)
256+
}
257+
})
258+
259+
t.Run("refreshes stale lua beside a current config", func(t *testing.T) {
260+
nginxDir := t.TempDir()
261+
confPath := filepath.Join(nginxDir, "nginx.conf")
262+
current, err := templates.GetNginxConfigWithData(true, templates.NginxConfigData{})
263+
if err != nil {
264+
t.Fatal(err)
265+
}
266+
if err := os.WriteFile(confPath, current, 0644); err != nil {
267+
t.Fatal(err)
268+
}
269+
luaDir := filepath.Join(nginxDir, "lua")
270+
if err := os.MkdirAll(luaDir, 0755); err != nil {
271+
t.Fatal(err)
272+
}
273+
if err := os.WriteFile(filepath.Join(luaDir, "security.lua"), []byte("return {}\n"), 0644); err != nil {
274+
t.Fatal(err)
275+
}
276+
277+
cfg := &config.Config{
278+
DeploymentsPath: nginxDir,
279+
Nginx: config.NginxConfig{ConfigPath: filepath.Join(nginxDir, "conf.d")},
280+
}
281+
if err := NewManager(cfg).EnsureBaseNginxConfig(); err != nil {
282+
t.Fatalf("EnsureBaseNginxConfig() = %v", err)
283+
}
284+
285+
securityLua, err := os.ReadFile(filepath.Join(luaDir, "security.lua"))
286+
if err != nil {
287+
t.Fatal(err)
288+
}
289+
if !strings.Contains(string(securityLua), "function _M.prepare_error_response()") {
290+
t.Errorf("stale security.lua was not refreshed")
291+
}
243292
})
244293

245294
t.Run("does not create a config where none exists", func(t *testing.T) {

0 commit comments

Comments
 (0)