mirror of
https://github.com/coredns/coredns.git
synced 2026-04-05 11:45:33 -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 core; go test -race ./... )
|
||||||
( cd coremain; 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:
|
test-plugins:
|
||||||
name: Test Plugins
|
name: Test Plugins
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ Available options:
|
|||||||
**-version**
|
**-version**
|
||||||
: show version and quit.
|
: show version and quit.
|
||||||
|
|
||||||
|
**-windows-service**
|
||||||
|
: run as a Windows service (only available on Windows builds, default false).
|
||||||
|
|
||||||
## Authors
|
## Authors
|
||||||
|
|
||||||
CoreDNS Authors.
|
CoreDNS Authors.
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ func Run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Twiddle your thumbs
|
// Twiddle your thumbs
|
||||||
instance.Wait()
|
runService(instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
// mustLogFatal wraps log.Fatal() in a way that ensures the
|
// mustLogFatal wraps log.Fatal() in a way that ensures the
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ func TestDefaultLoader(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if runtime.GOOS != "windows" {
|
||||||
// Create a file but make it unreadable
|
// Create a file but make it unreadable
|
||||||
tmpFile := filepath.Join(tmpDir, "Corefile")
|
tmpFile := filepath.Join(tmpDir, "Corefile")
|
||||||
if err := os.WriteFile(tmpFile, []byte("test"), 0644); err != nil {
|
if err := os.WriteFile(tmpFile, []byte("test"), 0644); err != nil {
|
||||||
@@ -166,6 +167,7 @@ func TestDefaultLoader(t *testing.T) {
|
|||||||
t.Error("Expected nil input for unreadable Corefile")
|
t.Error("Expected nil input for unreadable Corefile")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestVersionString(t *testing.T) {
|
func TestVersionString(t *testing.T) {
|
||||||
caddy.AppName = "TestApp"
|
caddy.AppName = "TestApp"
|
||||||
|
|||||||
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