feat: 更新配置,优化时间字段为毫秒,添加 Nginx 版本检测功能

This commit is contained in:
ryan
2026-03-10 19:58:43 +08:00
parent 8aab2b1ba0
commit 65a7331ea9
15 changed files with 334 additions and 109 deletions
+50
View File
@@ -263,6 +263,56 @@ func NewExecutor(options ExecutorOptions) Executor {
}
}
func DetectVersion(ctx context.Context, options ExecutorOptions) string {
version, err := detectVersion(ctx, options, &OSCommandRunner{})
if err != nil {
log.Printf("detect nginx version failed: %v", err)
return ""
}
log.Printf("detected nginx version: %s", version)
return version
}
func detectVersion(ctx context.Context, options ExecutorOptions, runner CommandRunner) (string, error) {
if runner == nil {
runner = &OSCommandRunner{}
}
if options.NginxPath != "" {
output, err := runner.Run(ctx, options.NginxPath, "-v")
if err != nil {
return "", fmt.Errorf("run nginx -v failed: %w: %s", err, string(output))
}
version := parseNginxVersion(string(output))
if version == "" {
return "", errors.New("cannot parse nginx version from binary output")
}
return version, nil
}
output, err := runner.Run(ctx, options.DockerBinary, "run", "--rm", options.Image, "nginx", "-v")
if err != nil {
return "", fmt.Errorf("run docker nginx -v failed: %w: %s", err, string(output))
}
version := parseNginxVersion(string(output))
if version == "" {
return "", errors.New("cannot parse nginx version from docker output")
}
return version, nil
}
func parseNginxVersion(output string) string {
start := strings.Index(output, "nginx/")
if start < 0 {
return ""
}
version := output[start+len("nginx/"):]
for i, r := range version {
if r == ' ' || r == '\n' || r == '\r' || r == '\t' {
return version[:i]
}
}
return version
}
type backupState struct {
RouteExisted bool
RouteData []byte
+41
View File
@@ -203,6 +203,47 @@ func TestNewExecutorUsesAbsoluteDockerMountPath(t *testing.T) {
}
}
func TestDetectVersionFromBinary(t *testing.T) {
version, err := detectVersion(context.Background(), ExecutorOptions{
NginxPath: "/opt/nginx/sbin/nginx",
}, &fakeRunner{
runFn: func(name string, args ...string) ([]byte, error) {
return []byte("nginx version: nginx/1.25.5\n"), nil
},
})
if err != nil {
t.Fatalf("detectVersion failed: %v", err)
}
if version != "1.25.5" {
t.Fatalf("unexpected version: %s", version)
}
}
func TestDetectVersionFromDockerImage(t *testing.T) {
runner := &fakeRunner{
runFn: func(name string, args ...string) ([]byte, error) {
return []byte("nginx version: nginx/1.27.4\n"), nil
},
}
version, err := detectVersion(context.Background(), ExecutorOptions{
DockerBinary: "docker",
Image: "nginx:stable-alpine",
}, runner)
if err != nil {
t.Fatalf("detectVersion failed: %v", err)
}
if version != "1.27.4" {
t.Fatalf("unexpected version: %s", version)
}
if len(runner.calls) != 1 {
t.Fatalf("expected one command call, got %d", len(runner.calls))
}
expectedArgs := []string{"run", "--rm", "nginx:stable-alpine", "nginx", "-v"}
if !reflect.DeepEqual(runner.calls[0].args, expectedArgs) {
t.Fatalf("unexpected docker args: %#v", runner.calls[0].args)
}
}
func TestManagerApplyWritesSupportFilesAndReplacesPlaceholder(t *testing.T) {
tempDir := t.TempDir()
manager := &Manager{