storagenode-updater: respond to Windows Service events (#3077)
This commit is contained in:
parent
43846f2074
commit
d860353603
@ -32,6 +32,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
cancel context.CancelFunc
|
||||
|
||||
rootCmd = &cobra.Command{
|
||||
Use: "storagenode-updater",
|
||||
Short: "Version updater for storage node",
|
||||
@ -81,7 +83,8 @@ func cmdRun(cmd *cobra.Command, args []string) (err error) {
|
||||
return errs.New("unable to find storage node executable binary")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
var ctx context.Context
|
||||
ctx, cancel = context.WithCancel(context.Background())
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
|
74
cmd/storagenode-updater/windows.go
Normal file
74
cmd/storagenode-updater/windows.go
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
// Implements support for running the storagenode-updater as a Windows Service.
|
||||
//
|
||||
// The Windows Service can be created with sc.exe, e.g.
|
||||
//
|
||||
// sc.exe create storagenode-updater binpath= "C:\Users\MyUser\storagenode-updater.exe run ..."
|
||||
|
||||
// +build windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
"log"
|
||||
|
||||
"golang.org/x/sys/windows/svc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
interactive, err := svc.IsAnInteractiveSession()
|
||||
if err != nil {
|
||||
panic("Failed to determine if session is interactive:" + err.Error())
|
||||
}
|
||||
|
||||
if interactive {
|
||||
return
|
||||
}
|
||||
|
||||
err = svc.Run("storagenode-updater", &service{})
|
||||
if err != nil {
|
||||
panic("Service failed: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
type service struct{}
|
||||
|
||||
func (m *service) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
|
||||
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
|
||||
|
||||
changes <- svc.Status{State: svc.StartPending}
|
||||
|
||||
go func() {
|
||||
_ = rootCmd.Execute()
|
||||
}()
|
||||
|
||||
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
|
||||
|
||||
for {
|
||||
select {
|
||||
case c := <-r:
|
||||
switch c.Cmd {
|
||||
case svc.Interrogate:
|
||||
log.Println("Interrogate request received.")
|
||||
changes <- c.CurrentStatus
|
||||
// Testing deadlock from https://code.google.com/p/winsvc/issues/detail?id=4
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
changes <- c.CurrentStatus
|
||||
case svc.Stop, svc.Shutdown:
|
||||
log.Println("Stop/Shutdown request received.")
|
||||
changes <- svc.Status{State: svc.StopPending}
|
||||
|
||||
cancel()
|
||||
// Sleep some time to give chance for goroutines finish cleanup after cancelling the context
|
||||
time.Sleep(3 * time.Second)
|
||||
// After returning the Windows Service is stopped and the process terminates
|
||||
return
|
||||
default:
|
||||
log.Println("Unexpected control request:", c)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user