From 84dab3c66d38fcb14c0254fe9bff8e48aba41469 Mon Sep 17 00:00:00 2001 From: Luther Monson Date: Wed, 28 Jul 2021 16:14:37 -0700 Subject: [PATCH 1/2] update service watching logic for windows service manager --- go.mod | 1 + pkg/cli/cmds/agent.go | 4 ++ pkg/cli/cmds/agent_service_windows.go | 6 +-- pkg/windows/service_linux.go | 7 +++ pkg/windows/service_windows.go | 71 +++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 pkg/windows/service_linux.go create mode 100644 pkg/windows/service_windows.go diff --git a/go.mod b/go.mod index 47418575f9..c03a3926c5 100644 --- a/go.mod +++ b/go.mod @@ -55,6 +55,7 @@ replace ( ) require ( + github.com/Freman/eventloghook v0.0.0-20191003051739-e4d803b6b48b github.com/Microsoft/hcsshim v0.8.20 github.com/containerd/continuity v0.1.0 github.com/google/go-containerregistry v0.5.0 diff --git a/pkg/cli/cmds/agent.go b/pkg/cli/cmds/agent.go index d216788fe7..15080e73fe 100644 --- a/pkg/cli/cmds/agent.go +++ b/pkg/cli/cmds/agent.go @@ -3,6 +3,7 @@ package cmds import ( "github.com/rancher/k3s/pkg/cli/cmds" "github.com/rancher/rke2/pkg/rke2" + "github.com/rancher/rke2/pkg/windows" "github.com/urfave/cli" ) @@ -80,5 +81,8 @@ func agentSubcommands() cli.Commands { func AgentRun(clx *cli.Context) error { validateCloudProviderName(clx) validateProfile(clx, "agent") + if err := windows.StartService(); err != nil { + return err + } return rke2.Agent(clx, config) } diff --git a/pkg/cli/cmds/agent_service_windows.go b/pkg/cli/cmds/agent_service_windows.go index c5eea6b30a..2d5aec3772 100644 --- a/pkg/cli/cmds/agent_service_windows.go +++ b/pkg/cli/cmds/agent_service_windows.go @@ -13,7 +13,7 @@ import ( "github.com/rancher/k3s/pkg/cli/cmds" "github.com/rancher/k3s/pkg/version" "github.com/urfave/cli" - "golang.org/x/sys/windows" + syswin "golang.org/x/sys/windows" "golang.org/x/sys/windows/svc/mgr" ) @@ -78,7 +78,7 @@ func addWindowService(serviceName, config string) error { defer m.Disconnect() s, err := m.CreateService(serviceName, p, mgr.Config{ - ServiceType: windows.SERVICE_WIN32_OWN_PROCESS, + ServiceType: syswin.SERVICE_WIN32_OWN_PROCESS, StartType: mgr.StartAutomatic, ErrorControl: mgr.ErrorNormal, DisplayName: version.Program, @@ -112,7 +112,7 @@ func addWindowService(serviceName, config string) error { } lpInfo := serviceFailureActions{ResetPeriod: uint32(30), ActionsCount: uint32(1), Actions: uintptr(unsafe.Pointer(&t[0]))} - return windows.ChangeServiceConfig2(s.Handle, serviceConfigFailureActions, (*byte)(unsafe.Pointer(&lpInfo))) + return syswin.ChangeServiceConfig2(s.Handle, serviceConfigFailureActions, (*byte)(unsafe.Pointer(&lpInfo))) } func deleteWindowsService(serviceName string) error { diff --git a/pkg/windows/service_linux.go b/pkg/windows/service_linux.go new file mode 100644 index 0000000000..f1565ffeaa --- /dev/null +++ b/pkg/windows/service_linux.go @@ -0,0 +1,7 @@ +// +build !windows + +package windows + +func StartService() error { + return nil +} diff --git a/pkg/windows/service_windows.go b/pkg/windows/service_windows.go new file mode 100644 index 0000000000..c68767a212 --- /dev/null +++ b/pkg/windows/service_windows.go @@ -0,0 +1,71 @@ +// +build windows + +package windows + +import ( + "os" + "time" + + "github.com/Freman/eventloghook" + "github.com/rancher/k3s/pkg/version" + "github.com/sirupsen/logrus" + "golang.org/x/sys/windows/svc" + "golang.org/x/sys/windows/svc/eventlog" +) + +type service struct{} + +var Service = &service{} + +func (h *service) Execute(_ []string, requests <-chan svc.ChangeRequest, statuses chan<- svc.Status) (bool, uint32) { + statuses <- svc.Status{State: svc.StartPending} + statuses <- svc.Status{State: svc.Running, Accepts: svc.AcceptStop | svc.AcceptShutdown} + for c := range requests { + switch c.Cmd { + case svc.Interrogate: + statuses <- c.CurrentStatus + case svc.Stop, svc.Shutdown: + statuses <- svc.Status{State: svc.StopPending} + logrus.Info("Windows Service is shutting down in 5s") + time.Sleep(5 * time.Second) + return false, 0 + } + } + return false, 0 +} + +func StartService() error { + if ok, err := svc.IsWindowsService(); err != nil || !ok { + return err + } + + elog, err := eventlog.Open(version.Program) + if err != nil { + return err + } + logrus.AddHook(eventloghook.NewHook(elog)) + + stop := make(chan struct{}) + go watchService(stop) + go func() { + defer close(stop) + if err := svc.Run(version.Program, Service); err != nil { + logrus.Fatalf("Windows Service error, exiting: %s", err) + } + }() + + return nil +} + +func watchService(stop chan struct{}) { + <-stop // pause for service to be stopped + ok, err := svc.IsWindowsService() + if err != nil { + logrus.Warnf("Error trying to determine if running as a Windows Service: %s", err) + } + + if ok { + logrus.Infof("Windows Service is shutting down") + os.Exit(0) + } +} From 8b1b7a9f14672341b04525663d65141d55300608 Mon Sep 17 00:00:00 2001 From: Luther Monson Date: Fri, 30 Jul 2021 11:11:03 -0700 Subject: [PATCH 2/2] go mod --- go.sum | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go.sum b/go.sum index 4a30d32d6c..6da7194a00 100644 --- a/go.sum +++ b/go.sum @@ -52,6 +52,8 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Freman/eventloghook v0.0.0-20191003051739-e4d803b6b48b h1:IltY1fRcdIshI/c8KOdmaO8P4lBwDXHJYPymMisvvDs= +github.com/Freman/eventloghook v0.0.0-20191003051739-e4d803b6b48b/go.mod h1:VGwG8f2pQ8SAFjTSH3PEDmLdlvi0XTd7a4C4AZn+pVw= github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20200415212048-7901bc822317 h1:JhyuWIqYrstW7KHMjk/fTqU0xtMpBOHuiTA2FVc7L4E= github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20200415212048-7901bc822317/go.mod h1:DF8FZRxMHMGv/vP2lQP6h+dYzzjpuRn24VeRiYn3qjQ= github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab h1:UKkYhof1njT1/xq4SEg5z+VpTgjmNeHwPGRQl7takDI=