From bb284c2f37039c2ee05ef5ac6819460138eb94b5 Mon Sep 17 00:00:00 2001 From: ryan Date: Wed, 18 Mar 2026 10:46:19 +0800 Subject: [PATCH] =?UTF-8?q?[=E5=8A=9F=E8=83=BD]=20=E4=BC=98=E5=8C=96Docker?= =?UTF-8?q?Executor=E7=9A=84Reload=E6=96=B9=E6=B3=95=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=8C=82=E8=BD=BD=E6=BA=90=E9=AA=8C=E8=AF=81=E5=B9=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9C=A8=E8=BF=90=E8=A1=8C=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E5=AE=B9=E5=99=A8=E5=86=85=E9=87=8D=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openflare_agent/internal/nginx/manager.go | 18 ++++--- .../internal/nginx/manager_test.go | 53 ++++++++++++++++--- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/openflare_agent/internal/nginx/manager.go b/openflare_agent/internal/nginx/manager.go index 063f654d..c57991fd 100644 --- a/openflare_agent/internal/nginx/manager.go +++ b/openflare_agent/internal/nginx/manager.go @@ -128,7 +128,18 @@ func (e *DockerExecutor) Test(ctx context.Context) error { } func (e *DockerExecutor) Reload(ctx context.Context) error { - return e.EnsureRuntime(ctx, true) + if err := e.validateMountSources(); err != nil { + return err + } + output, err := e.Runner.Run(ctx, e.DockerBinary, "inspect", "-f", "{{.State.Running}}", e.ContainerName) + if err != nil || strings.TrimSpace(string(output)) != "true" { + return e.EnsureRuntime(ctx, false) + } + output, err = e.Runner.Run(ctx, e.DockerBinary, "exec", e.ContainerName, dockerRuntimeCommand, "-s", "reload") + if err != nil { + return fmt.Errorf("docker exec %s reload failed: %w: %s", dockerRuntimeCommand, err, string(output)) + } + return nil } func (e *DockerExecutor) EnsureRuntime(ctx context.Context, recreate bool) error { @@ -301,11 +312,6 @@ func (m *Manager) Apply(ctx context.Context, mainConfig string, routeConfig stri _ = m.restore(backup) return err } - if err = m.Executor.Test(ctx); err != nil { - slog.Error("openresty test failed after config write, restoring backup", "error", err) - _ = m.restore(backup) - return err - } if err = m.Executor.Reload(ctx); err != nil { slog.Error("openresty reload failed after config write, restoring backup", "error", err) _ = m.restore(backup) diff --git a/openflare_agent/internal/nginx/manager_test.go b/openflare_agent/internal/nginx/manager_test.go index 85b0744b..a6d1da3c 100644 --- a/openflare_agent/internal/nginx/manager_test.go +++ b/openflare_agent/internal/nginx/manager_test.go @@ -217,17 +217,56 @@ func TestDockerExecutorStartsStoppedContainer(t *testing.T) { t.Fatalf("Reload failed: %v", err) } - if len(runner.calls) != 3 { - t.Fatalf("expected 3 calls, got %d", len(runner.calls)) + if len(runner.calls) != 4 { + t.Fatalf("expected 4 calls, got %d", len(runner.calls)) } if runner.calls[0].args[0] != "inspect" { t.Fatalf("expected docker inspect on first call, got %#v", runner.calls[0]) } - if runner.calls[1].args[0] != "rm" { - t.Fatalf("expected docker rm on second call, got %#v", runner.calls[1]) + if runner.calls[1].args[0] != "inspect" { + t.Fatalf("expected docker inspect on second call, got %#v", runner.calls[1]) } - if runner.calls[2].args[0] != "run" { - t.Fatalf("expected docker run on third call, got %#v", runner.calls[2]) + if runner.calls[2].args[0] != "rm" { + t.Fatalf("expected docker rm on third call, got %#v", runner.calls[2]) + } + if runner.calls[3].args[0] != "run" { + t.Fatalf("expected docker run on fourth call, got %#v", runner.calls[3]) + } +} + +func TestDockerExecutorReloadsRunningContainerInPlace(t *testing.T) { + mainConfigPath, routeConfigDir, certDir, luaDir := prepareDockerMountSources(t) + runner := &fakeRunner{ + runFn: func(name string, args ...string) ([]byte, error) { + if len(args) >= 1 && args[0] == "inspect" { + return []byte("true"), nil + } + return []byte("ok"), nil + }, + } + executor := &DockerExecutor{ + DockerBinary: "docker", + ContainerName: "openflare-openresty", + Image: "openresty/openresty:alpine", + MainConfigPath: mainConfigPath, + RouteConfigDir: routeConfigDir, + CertDir: certDir, + NginxCertDir: "/etc/nginx/openflare-certs", + LuaDir: luaDir, + NginxLuaDir: "/etc/nginx/openflare-lua", + Runner: runner, + } + + if err := executor.Reload(context.Background()); err != nil { + t.Fatalf("Reload failed: %v", err) + } + + expected := []runCall{ + {name: "docker", args: []string{"inspect", "-f", "{{.State.Running}}", "openflare-openresty"}}, + {name: "docker", args: []string{"exec", "openflare-openresty", "openresty", "-s", "reload"}}, + } + if !reflect.DeepEqual(runner.calls, expected) { + t.Fatalf("unexpected calls: %#v", runner.calls) } } @@ -676,7 +715,7 @@ func TestManagerRollbackRestoresCertFiles(t *testing.T) { LuaDir: filepath.Join(tempDir, "lua"), NginxLuaDir: "/etc/nginx/openflare-lua", Executor: &fakeExecutor{ - testErr: errors.New("openresty test failed"), + reloadErr: errors.New("openresty reload failed"), }, }