mirror of
https://github.com/coredns/coredns.git
synced 2026-04-04 19:25:40 -04:00
feat: add support for running CoreDNS as a Windows service (#7962)
* feat: add support for running CoreDNS as a Windows service Signed-off-by: John-Michael Mulesa <jmulesa@gmail.com> * Use non-deprecated service check function. Signed-off-by: John-Michael Mulesa <jmulesa@gmail.com> * refactor: remove deprecated build tags and clean up imports in service files Signed-off-by: John-Michael Mulesa <jmulesa@gmail.com> * ci: add Windows test workflow and fix log field access in service_windows.go Signed-off-by: John-Michael Mulesa <jmulesa@gmail.com> * test: implement cross-platform file permission restriction for Windows compatibility in run_test.go Signed-off-by: John-Michael Mulesa <jmulesa@gmail.com> * refactor: remove Windows-specific icacls test logic and restrict unreadable file test to non-Windows platforms Signed-off-by: John-Michael Mulesa <jmulesa@gmail.com> * docs: add documentation for -windows-service flag in man page Signed-off-by: John-Michael Mulesa <jmulesa@gmail.com> --------- Signed-off-by: John-Michael Mulesa <jmulesa@gmail.com>
This commit is contained in:
committed by
GitHub
parent
12131b7455
commit
1c15569168
25
.github/workflows/go.test.yml
vendored
25
.github/workflows/go.test.yml
vendored
@@ -28,6 +28,31 @@ jobs:
|
||||
( cd core; go test -race ./... )
|
||||
( cd coremain; go test -race ./... )
|
||||
|
||||
test-windows:
|
||||
name: Test Windows
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
|
||||
with:
|
||||
go-version-file: .go-version
|
||||
id: go
|
||||
|
||||
- name: Build
|
||||
run: go build -v ./...
|
||||
|
||||
- name: Test
|
||||
shell: bash
|
||||
run: |
|
||||
( cd request; go test -race ./... )
|
||||
( cd core; go test -race ./... )
|
||||
( cd coremain; go test -race ./... )
|
||||
|
||||
test-plugins:
|
||||
name: Test Plugins
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -39,6 +39,9 @@ Available options:
|
||||
**-version**
|
||||
: show version and quit.
|
||||
|
||||
**-windows-service**
|
||||
: run as a Windows service (only available on Windows builds, default false).
|
||||
|
||||
## Authors
|
||||
|
||||
CoreDNS Authors.
|
||||
|
||||
@@ -80,7 +80,7 @@ func Run() {
|
||||
}
|
||||
|
||||
// Twiddle your thumbs
|
||||
instance.Wait()
|
||||
runService(instance)
|
||||
}
|
||||
|
||||
// mustLogFatal wraps log.Fatal() in a way that ensures the
|
||||
|
||||
@@ -149,21 +149,23 @@ func TestDefaultLoader(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Create a file but make it unreadable
|
||||
tmpFile := filepath.Join(tmpDir, "Corefile")
|
||||
if err := os.WriteFile(tmpFile, []byte("test"), 0644); err != nil {
|
||||
t.Fatalf("Failed to create test file: %v", err)
|
||||
}
|
||||
if err := os.Chmod(tmpFile, 0000); err != nil {
|
||||
t.Fatalf("Failed to change permissions: %v", err)
|
||||
}
|
||||
if runtime.GOOS != "windows" {
|
||||
// Create a file but make it unreadable
|
||||
tmpFile := filepath.Join(tmpDir, "Corefile")
|
||||
if err := os.WriteFile(tmpFile, []byte("test"), 0644); err != nil {
|
||||
t.Fatalf("Failed to create test file: %v", err)
|
||||
}
|
||||
if err := os.Chmod(tmpFile, 0000); err != nil {
|
||||
t.Fatalf("Failed to change permissions: %v", err)
|
||||
}
|
||||
|
||||
input, err = defaultLoader("dns")
|
||||
if err == nil {
|
||||
t.Error("Expected error for unreadable Corefile but got none")
|
||||
}
|
||||
if input != nil {
|
||||
t.Error("Expected nil input for unreadable Corefile")
|
||||
input, err = defaultLoader("dns")
|
||||
if err == nil {
|
||||
t.Error("Expected error for unreadable Corefile but got none")
|
||||
}
|
||||
if input != nil {
|
||||
t.Error("Expected nil input for unreadable Corefile")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
9
coremain/service_other.go
Normal file
9
coremain/service_other.go
Normal file
@@ -0,0 +1,9 @@
|
||||
//go:build !windows
|
||||
|
||||
package coremain
|
||||
|
||||
import "github.com/coredns/caddy"
|
||||
|
||||
func runService(instance *caddy.Instance) {
|
||||
instance.Wait()
|
||||
}
|
||||
63
coremain/service_windows.go
Normal file
63
coremain/service_windows.go
Normal file
@@ -0,0 +1,63 @@
|
||||
//go:build windows
|
||||
|
||||
package coremain
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
|
||||
"github.com/coredns/caddy"
|
||||
|
||||
"golang.org/x/sys/windows/svc"
|
||||
)
|
||||
|
||||
var windowsService bool
|
||||
|
||||
func init() {
|
||||
flag.BoolVar(&windowsService, "windows-service", false, "Run as a Windows service")
|
||||
}
|
||||
|
||||
type corednsService struct {
|
||||
instance *caddy.Instance
|
||||
}
|
||||
|
||||
func (s *corednsService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (svcSpecificEC bool, exitCode uint32) {
|
||||
changes <- svc.Status{State: svc.StartPending}
|
||||
changes <- svc.Status{State: svc.Running, Accepts: svc.AcceptStop | svc.AcceptShutdown}
|
||||
|
||||
for req := range r {
|
||||
switch req.Cmd {
|
||||
case svc.Interrogate:
|
||||
changes <- req.CurrentStatus
|
||||
case svc.Stop, svc.Shutdown:
|
||||
changes <- svc.Status{State: svc.StopPending}
|
||||
if s.instance != nil {
|
||||
s.instance.Stop()
|
||||
}
|
||||
return false, 0
|
||||
default:
|
||||
log.Printf("unexpected control request #%d", req.Cmd)
|
||||
}
|
||||
}
|
||||
|
||||
return false, 0
|
||||
}
|
||||
|
||||
func runService(instance *caddy.Instance) {
|
||||
if windowsService {
|
||||
isService, err := svc.IsWindowsService()
|
||||
if err != nil {
|
||||
log.Fatalf("failed to determine if running as service: %v", err)
|
||||
}
|
||||
if isService {
|
||||
err = svc.Run("CoreDNS", &corednsService{instance: instance})
|
||||
if err != nil {
|
||||
log.Fatalf("failed to start service: %v", err)
|
||||
}
|
||||
return
|
||||
} else {
|
||||
log.Printf("Windows service flag provided, but not running as a Windows service.")
|
||||
}
|
||||
}
|
||||
instance.Wait()
|
||||
}
|
||||
Reference in New Issue
Block a user