Skip to content

Commit

Permalink
update service watching logic for windows service manager
Browse files Browse the repository at this point in the history
  • Loading branch information
luthermonson committed Jul 30, 2021
1 parent 8fd4a51 commit 84dab3c
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 3 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions pkg/cli/cmds/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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)
}
6 changes: 3 additions & 3 deletions pkg/cli/cmds/agent_service_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down
7 changes: 7 additions & 0 deletions pkg/windows/service_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// +build !windows

package windows

func StartService() error {
return nil
}
71 changes: 71 additions & 0 deletions pkg/windows/service_windows.go
Original file line number Diff line number Diff line change
@@ -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)
}
}

0 comments on commit 84dab3c

Please sign in to comment.