Browse Source

trying to split up modules for windows service wrapper

main
forest 2 months ago
parent
commit
562ade21a6
11 changed files with 156 additions and 39 deletions
  1. +3
    -3
      caddy-config.json
  2. +0
    -0
      child-process-service/child_process_service.go
  3. +5
    -0
      child-process-service/go.mod
  4. +2
    -0
      child-process-service/go.sum
  5. +0
    -0
      child-process-service/log_manager.go
  6. +3
    -2
      go.mod
  7. +2
    -1
      go.sum
  8. +26
    -26
      main.go
  9. +15
    -7
      picopublish.sh
  10. +3
    -0
      windows-service-wrapper/go.mod
  11. +97
    -0
      windows-service-wrapper/main.go

+ 3
- 3
caddy-config.json View File

@ -2,9 +2,9 @@
"admin": {
"disabled": false,
"listen": "127.0.0.1:9574",
"authorized_clients_ca_file": "./greenhouse_daemon_localhost_ca.crt",
"tls_key_file": "./greenhouse-daemon.key",
"tls_cert_file": "./greenhouse-daemon.crt",
"authorized_clients_ca_file": "greenhouse_daemon_localhost_ca.crt",
"tls_key_file": "greenhouse-daemon.key",
"tls_cert_file": "greenhouse-daemon.crt",
"config": {
"persist": false
}


child_process_service.go → child-process-service/child_process_service.go View File


+ 5
- 0
child-process-service/go.mod View File

@ -0,0 +1,5 @@
module git.sequentialread.com/forest/greenhouse-daemon/child-process-service
go 1.16
require git.sequentialread.com/forest/lumberjack v0.0.0-20210825181050-880244457f2e

+ 2
- 0
child-process-service/go.sum View File

@ -0,0 +1,2 @@
git.sequentialread.com/forest/lumberjack v0.0.0-20210825181050-880244457f2e h1:4Jqvham9nIkxx34Ou0KKEE3AXPwXYJLLw1zWTuqbISY=
git.sequentialread.com/forest/lumberjack v0.0.0-20210825181050-880244457f2e/go.mod h1:KeDUOMaz5z/cNWO4zIRrs+1pcLuKVVtxfWsxIxPpCSY=

log_manager.go → child-process-service/log_manager.go View File


+ 3
- 2
go.mod View File

@ -1,11 +1,12 @@
module git.sequentialread.com/forest/greenhouse-desktop/greenhouse-daemon
module git.sequentialread.com/forest/greenhouse-daemon
go 1.16
require (
git.sequentialread.com/forest/easypki.git v1.1.3-0.20210825184937-473ebf3609b4
git.sequentialread.com/forest/go-netstat v0.0.0-20210914205413-73fdb805ec95 // indirect
git.sequentialread.com/forest/go-netstat v0.0.0-20210914205413-73fdb805ec95
git.sequentialread.com/forest/greenhouse/pki v0.0.0-20210825185315-cbbdc0e93a3e
git.sequentialread.com/forest/lumberjack v0.0.0-20210825181050-880244457f2e
git.sequentialread.com/forest/pkg-errors v0.9.2
golang.org/x/sys v0.0.0-20210930141918-969570ce7c6c
)

+ 2
- 1
go.sum View File

@ -8,5 +8,6 @@ git.sequentialread.com/forest/lumberjack v0.0.0-20210825181050-880244457f2e h1:4
git.sequentialread.com/forest/lumberjack v0.0.0-20210825181050-880244457f2e/go.mod h1:KeDUOMaz5z/cNWO4zIRrs+1pcLuKVVtxfWsxIxPpCSY=
git.sequentialread.com/forest/pkg-errors v0.9.2 h1:j6pwbL6E+TmE7TD0tqRtGwuoCbCfO6ZR26Nv5nest9g=
git.sequentialread.com/forest/pkg-errors v0.9.2/go.mod h1:8TkJ/f8xLWFIAid20aoqgDZcCj9QQt+FU+rk415XO1w=
golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 h1:xrCZDmdtoloIiooiA9q0OQb9r8HejIHYoHGhGCe1pGg=
golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210930141918-969570ce7c6c h1:ayiZ33F3u3LIXB03Y5VKNdaFO79a18Fr+SB30o/KFyw=
golang.org/x/sys v0.0.0-20210930141918-969570ce7c6c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

+ 26
- 26
main.go View File

@ -23,6 +23,7 @@ import (
"git.sequentialread.com/forest/easypki.git/pkg/easypki"
easypkiStore "git.sequentialread.com/forest/easypki.git/pkg/store"
netstat "git.sequentialread.com/forest/go-netstat"
child "git.sequentialread.com/forest/greenhouse-daemon/child-process-service"
greenhousePKI "git.sequentialread.com/forest/greenhouse/pki"
errors "git.sequentialread.com/forest/pkg-errors"
)
@ -47,9 +48,9 @@ type DaemonAPI struct {
TLSCertFile string
TLSKeyFile string
ThresholdService *ChildProcessService
CaddyService *ChildProcessService
LogManager *LogManager
ThresholdService *child.ChildProcessService
CaddyService *child.ChildProcessService
LogManager *child.LogManager
ApplyConfigStatuses []string
ApplyConfigStatusIndex int
ApplyConfigStatusError string
@ -74,17 +75,17 @@ type ThresholdConfig struct {
}
type Status struct {
NeedsAPIToken bool `json:"needs_api_token"`
HashedToken string `json:"hashed_api_token"`
Threshold *ChildProcessStatus `json:"threshold"`
Caddy *ChildProcessStatus `json:"caddy"`
ApplyConfigStatuses []string `json:"apply_config_statuses"`
ApplyConfigStatusIndex int `json:"apply_config_status_index"`
ApplyConfigStatusError string `json:"apply_config_status_error"`
TenantInfo *TenantInfo `json:"tenant_info"`
ServerName string `json:"server_name"`
GUITunnels []GUITunnel `json:"tunnels"`
UpdateTenantInfoMessage string `json:"update_tenant_info_message"`
NeedsAPIToken bool `json:"needs_api_token"`
HashedToken string `json:"hashed_api_token"`
Threshold *child.ChildProcessStatus `json:"threshold"`
Caddy *child.ChildProcessStatus `json:"caddy"`
ApplyConfigStatuses []string `json:"apply_config_statuses"`
ApplyConfigStatusIndex int `json:"apply_config_status_index"`
ApplyConfigStatusError string `json:"apply_config_status_error"`
TenantInfo *TenantInfo `json:"tenant_info"`
ServerName string `json:"server_name"`
GUITunnels []GUITunnel `json:"tunnels"`
UpdateTenantInfoMessage string `json:"update_tenant_info_message"`
}
type TenantInfo struct {
@ -192,7 +193,7 @@ const caddyAdminSocketFile = "/var/run/greenhouse-daemon-caddy-admin.sock"
const mainCAName = "greenhouse_daemon_localhost_ca"
var log *LogManager
var log *child.LogManager
func main() {
@ -206,12 +207,11 @@ func main() {
} else if runtime.GOOS == "windows" {
daemonPath = fmt.Sprintf(`%s\greenhouse-daemon`, os.Getenv("ProgramData"))
} else {
fmt.Printf("can't start the greenhouse-daemon because operating system '%+v' is not supported yet\n\n", runtime.GOOS)
os.Exit(1)
log.Fatalf("can't start the greenhouse-daemon because operating system '%s' is not supported yet\n\n", runtime.GOOS)
}
}
log = NewLogManager(daemonPath, path.Join(daemonPath, "daemon"))
log = child.NewLogManager(daemonPath, path.Join(daemonPath, "daemon"))
go log.consumeFromChannel()
cloudURL := os.Getenv("GREENHOUSE_DAEMON_CLOUD_URL")
@ -300,8 +300,8 @@ func main() {
CACertFile: path.Join(daemonPath, fmt.Sprintf("%s.crt", mainCAName)),
TLSCertFile: path.Join(daemonPath, "greenhouse-daemon.crt"),
TLSKeyFile: path.Join(daemonPath, "greenhouse-daemon.key"),
ThresholdService: NewChildProcessService(daemonPath, thresholdExecutable, thresholdArguments, []string{}, nil, daemonConfig.TunnelsEnabled),
CaddyService: NewChildProcessService(daemonPath, caddyExecutable, caddyArguments, caddyEnvironment, caddyOnPreStart, daemonConfig.TunnelsEnabled),
ThresholdService: child.NewChildProcessService(daemonPath, thresholdExecutable, thresholdArguments, []string{}, nil, daemonConfig.TunnelsEnabled),
CaddyService: child.NewChildProcessService(daemonPath, caddyExecutable, caddyArguments, caddyEnvironment, caddyOnPreStart, daemonConfig.TunnelsEnabled),
LogManager: log,
}
@ -459,14 +459,14 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
return
}
logManagerMap := map[string]*LogManager{
logManagerMap := map[string]*child.LogManager{
"caddy": daemon.CaddyService.LogManager,
"threshold": daemon.ThresholdService.LogManager,
"daemon": daemon.LogManager,
}
var logManagers []*LogManager
var logManagers []*child.LogManager
if service == "all" || service == "" {
logManagers = []*LogManager{
logManagers = []*child.LogManager{
logManagerMap["caddy"],
logManagerMap["threshold"],
logManagerMap["daemon"],
@ -477,10 +477,10 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
http.Error(responseWriter, "404 not found, try /log?service=daemon, /log?service=caddy, /log?service=threshold or /log?service=all", http.StatusNotFound)
return
}
logManagers = []*LogManager{logManager}
logManagers = []*child.LogManager{logManager}
}
logIterators := make([]*LogIterator, len(logManagers))
logIterators := make([]*child.LogIterator, len(logManagers))
for i := 0; i < len(logManagers); i++ {
iterator, err := logManagers[i].Iterator()
@ -493,7 +493,7 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
logIterators[i] = iterator
}
logs, err := Joinerate(logIterators, count)
logs, err := child.Joinerate(logIterators, count)
if err != nil {
errorMessage := "greenhouse-daemon: 500 internal server error: failed to read log file(s)"
log.Printf("%s: %+v\n", errorMessage, err)


+ 15
- 7
picopublish.sh View File

@ -9,18 +9,23 @@ function build() {
fi
version="$tag-$(git rev-parse --short HEAD)-$(hexdump -n 2 -ve '1/1 "%.2x"' /dev/urandom)"
echo "building version: $version"
echo "building version: $version GOOS=$GOOS GOARCH=$GOARCH"
rm -rf build
mkdir build
go build -tags 'osusergo netgo' -ldflags='-extldflags=-static' -o build/greenhouse-daemon
binary_suffix=""
if [ "$GOOS" == "windows" ]; then
binary_suffix=".exe"
fi
GOOS=$GOOS GOARCH=$GOARCH go build -tags 'osusergo netgo' -ldflags='-extldflags=-static' -o "build/greenhouse-daemon$binary_suffix"
sha256sum build/greenhouse-daemon
sha256sum "build/greenhouse-daemon$binary_suffix"
gzip_file_name="greenhouse-daemon-$version-$GOOS-$GOARCH.gz"
gzip --stdout build/greenhouse-daemon > "build/$gzip_file_name"
gzip --stdout "build/greenhouse-daemon$binary_suffix" > "build/$gzip_file_name"
curl -X POST "https://picopublish.sequentialread.com/files/$gzip_file_name" \
-H 'Content-Type: application/x-gzip' -H "Authorization: Basic $(cat .picopublish-auth)" \
@ -29,6 +34,9 @@ function build() {
echo "https://picopublish.sequentialread.com/files/$gzip_file_name"
}
#build arm
build linux amd64
#build arm64
#build linux arm
#build linux arm64
#build linux amd64
build windows amd64
#build darwin arm64
#build darwin amd64

+ 3
- 0
windows-service-wrapper/go.mod View File

@ -0,0 +1,3 @@
module git.sequentialread.com/forest/greenhouse-daemon/windows-service-wrapper
go 1.16

+ 97
- 0
windows-service-wrapper/main.go View File

@ -0,0 +1,97 @@
// +build windows
package main
import (
"fmt"
"log"
"strings"
"time"
daemon "git.sequentialread.com/forest/greenhouse-daemon"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/debug"
"golang.org/x/sys/windows/svc/eventlog"
)
var elog debug.Log
type Wrapper struct {
Child *daemon.ChildProcessService
}
func main() {
isWindowsService, err := svc.IsWindowsService()
if err != nil {
log.Fatalf("can't start the windows_service_wrapper, an error occurred while trying to determine if we are running as a windows service or not: %+v\n\n", err)
}
if !isWindowsService {
log.Fatalf("This program is meant to be run as a windows service.\n\n")
}
if strings.ToLower(os.Args[1]) == "debug" {
runService("GreenhouseBackgroundService", true)
} else {
runService("GreenhouseBackgroundService", false)
}
}
func (m *Wrapper) Execute(args []string, requests <-chan svc.ChangeRequest, responses chan<- svc.Status) (ssec bool, errno uint32) {
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
responses <- svc.Status{State: svc.StartPending}
responses <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
loop:
for {
select {
case changeRequest := <-requests:
switch changeRequest.Cmd {
case svc.Interrogate:
responses <- changeRequest.CurrentStatus
// Testing deadlock from https://code.google.com/p/winsvc/issues/detail?id=4
time.Sleep(100 * time.Millisecond)
responses <- changeRequest.CurrentStatus
case svc.Stop, svc.Shutdown:
break loop
case svc.Pause:
responses <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted}
tick = slowtick
case svc.Continue:
responses <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
tick = fasttick
default:
elog.Error(1, fmt.Sprintf("unexpected control request #%d", changeRequest))
}
}
}
responses <- svc.Status{State: svc.StopPending}
return
}
func runService(name string, isDebug bool) {
var err error
if isDebug {
elog = debug.New(name)
} else {
elog, err = eventlog.Open(name)
if err != nil {
return
}
}
defer elog.Close()
elog.Info(1, fmt.Sprintf("starting %s service", name))
run := svc.Run
if isDebug {
run = debug.Run
}
err = run(name, &Wrapper{
Child: daemon.NewChildProcessService(os.GetCwd(), "greenhouse-background-service.exe", []string{}, []string{}, func() error { return nil }),
})
if err != nil {
elog.Error(1, fmt.Sprintf("%s service failed: %v", name, err))
return
}
elog.Info(1, fmt.Sprintf("%s service stopped", name))
}

Loading…
Cancel
Save