mirror of
https://github.com/fosrl/olm.git
synced 2026-02-08 05:56:41 +00:00
63
README.md
63
README.md
@@ -86,6 +86,69 @@ WantedBy=multi-user.target
|
||||
|
||||
Make sure to `mv ./olm /usr/local/bin/olm`!
|
||||
|
||||
## Windows Service
|
||||
|
||||
On Windows, Olm can be installed and run as a Windows service. This allows it to start automatically at boot and run in the background.
|
||||
|
||||
### Service Management Commands
|
||||
|
||||
```cmd
|
||||
# Install the service
|
||||
olm.exe install
|
||||
|
||||
# Start the service
|
||||
olm.exe start
|
||||
|
||||
# Stop the service
|
||||
olm.exe stop
|
||||
|
||||
# Check service status
|
||||
olm.exe status
|
||||
|
||||
# Remove the service
|
||||
olm.exe remove
|
||||
|
||||
# Run in debug mode (console output)
|
||||
olm.exe debug
|
||||
|
||||
# Show help
|
||||
olm.exe help
|
||||
```
|
||||
|
||||
**Helper Scripts**: For easier service management, you can use the provided helper scripts:
|
||||
- `olm-service.bat` - Batch script (requires Administrator privileges)
|
||||
- `olm-service.ps1` - PowerShell script with better error handling
|
||||
|
||||
Example using the batch script:
|
||||
```cmd
|
||||
# Run as Administrator
|
||||
olm-service.bat install
|
||||
olm-service.bat start
|
||||
olm-service.bat status
|
||||
```
|
||||
|
||||
### Service Configuration
|
||||
|
||||
When running as a service, Olm will read configuration from environment variables or you can modify the service to include command-line arguments:
|
||||
|
||||
1. Install the service: `olm.exe install`
|
||||
2. Configure the service with your credentials using Windows Service Manager or by setting system environment variables:
|
||||
- `PANGOLIN_ENDPOINT=https://example.com`
|
||||
- `OLM_ID=your_olm_id`
|
||||
- `OLM_SECRET=your_secret`
|
||||
3. Start the service: `olm.exe start`
|
||||
|
||||
### Service Logs
|
||||
|
||||
When running as a service, logs are written to:
|
||||
- Windows Event Log (Application log, source: "OlmWireguardService")
|
||||
- Log files in: `%PROGRAMDATA%\Olm\logs\olm.log`
|
||||
|
||||
You can view the Windows Event Log using Event Viewer or PowerShell:
|
||||
```powershell
|
||||
Get-EventLog -LogName Application -Source "OlmWireguardService" -Newest 10
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
### Container
|
||||
|
||||
112
main.go
112
main.go
@@ -1,9 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
@@ -24,6 +26,92 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Check if we're running as a Windows service
|
||||
if isWindowsService() {
|
||||
runService("OlmWireguardService", false)
|
||||
fmt.Println("Service started successfully")
|
||||
return
|
||||
}
|
||||
|
||||
// Handle service management commands on Windows
|
||||
// print the args
|
||||
for i, arg := range os.Args {
|
||||
fmt.Printf("Arg %d: %s\n", i, arg)
|
||||
}
|
||||
if runtime.GOOS == "windows" && len(os.Args) > 1 {
|
||||
fmt.Println("Handling Windows service management command:", os.Args[1])
|
||||
switch os.Args[1] {
|
||||
case "install":
|
||||
err := installService()
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to install service: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("Service installed successfully")
|
||||
return
|
||||
case "remove", "uninstall":
|
||||
err := removeService()
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to remove service: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("Service removed successfully")
|
||||
return
|
||||
case "start":
|
||||
err := startService()
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to start service: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("Service started successfully")
|
||||
return
|
||||
case "stop":
|
||||
err := stopService()
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to stop service: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("Service stopped successfully")
|
||||
return
|
||||
case "status":
|
||||
status, err := getServiceStatus()
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to get service status: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("Service status: %s\n", status)
|
||||
return
|
||||
case "debug":
|
||||
runService("OlmWireguardService", true)
|
||||
return
|
||||
case "help", "--help", "-h":
|
||||
fmt.Println("Olm WireGuard VPN Client")
|
||||
fmt.Println("\nWindows Service Management:")
|
||||
fmt.Println(" install Install the service")
|
||||
fmt.Println(" remove Remove the service")
|
||||
fmt.Println(" start Start the service")
|
||||
fmt.Println(" stop Stop the service")
|
||||
fmt.Println(" status Show service status")
|
||||
fmt.Println(" debug Run service in debug mode")
|
||||
fmt.Println("\nFor console mode, run without arguments or with standard flags.")
|
||||
return
|
||||
default:
|
||||
fmt.Println("Unknown command:", os.Args[1])
|
||||
fmt.Println("Use 'olm --help' for usage information.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Run in console mode
|
||||
runOlmMain(context.Background())
|
||||
}
|
||||
|
||||
func runOlmMain(ctx context.Context) {
|
||||
// Setup Windows event logging if on Windows
|
||||
if runtime.GOOS == "windows" {
|
||||
setupWindowsEventLog()
|
||||
}
|
||||
|
||||
var (
|
||||
endpoint string
|
||||
id string
|
||||
@@ -210,7 +298,7 @@ func main() {
|
||||
var dev *device.Device
|
||||
var wgData WgData
|
||||
var holePunchData HolePunchData
|
||||
var uapi *os.File
|
||||
var uapiListener net.Listener
|
||||
var tdev tun.Device
|
||||
|
||||
sourcePort, err := FindAvailableUDPPort(49152, 65535)
|
||||
@@ -327,7 +415,7 @@ func main() {
|
||||
|
||||
errs := make(chan error)
|
||||
|
||||
uapi, err := uapiListen(interfaceName, fileUAPI)
|
||||
uapiListener, err = uapiListen(interfaceName, fileUAPI)
|
||||
if err != nil {
|
||||
logger.Error("Failed to listen on uapi socket: %v", err)
|
||||
os.Exit(1)
|
||||
@@ -335,7 +423,7 @@ func main() {
|
||||
|
||||
go func() {
|
||||
for {
|
||||
conn, err := uapi.Accept()
|
||||
conn, err := uapiListener.Accept()
|
||||
if err != nil {
|
||||
errs <- err
|
||||
return
|
||||
@@ -622,10 +710,16 @@ func main() {
|
||||
}
|
||||
defer olm.Close()
|
||||
|
||||
// Wait for interrupt signal
|
||||
// Wait for interrupt signal or context cancellation
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-sigCh
|
||||
|
||||
select {
|
||||
case <-sigCh:
|
||||
logger.Info("Received interrupt signal")
|
||||
case <-ctx.Done():
|
||||
logger.Info("Context cancelled")
|
||||
}
|
||||
|
||||
select {
|
||||
case <-stopHolepunch:
|
||||
@@ -648,6 +742,10 @@ func main() {
|
||||
close(stopPing)
|
||||
}
|
||||
|
||||
uapi.Close()
|
||||
dev.Close()
|
||||
if uapiListener != nil {
|
||||
uapiListener.Close()
|
||||
}
|
||||
if dev != nil {
|
||||
dev.Close()
|
||||
}
|
||||
}
|
||||
|
||||
52
olm-service.bat
Normal file
52
olm-service.bat
Normal file
@@ -0,0 +1,52 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
REM Olm Windows Service Management Script
|
||||
REM This script helps manage the Olm WireGuard service on Windows
|
||||
|
||||
if "%1"=="" goto :help
|
||||
if "%1"=="help" goto :help
|
||||
if "%1"=="/?" goto :help
|
||||
if "%1"=="-h" goto :help
|
||||
if "%1"=="--help" goto :help
|
||||
|
||||
REM Check if running as administrator
|
||||
net session >nul 2>&1
|
||||
if %errorLevel% neq 0 (
|
||||
echo Error: This script must be run as Administrator for service management.
|
||||
echo Right-click and select "Run as administrator"
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM Execute the service command
|
||||
olm.exe %*
|
||||
if %errorLevel% neq 0 (
|
||||
echo Command failed with error code %errorLevel%
|
||||
pause
|
||||
exit /b %errorLevel%
|
||||
)
|
||||
|
||||
echo.
|
||||
echo Operation completed successfully.
|
||||
pause
|
||||
exit /b 0
|
||||
|
||||
:help
|
||||
echo Olm WireGuard Service Management
|
||||
echo.
|
||||
echo Usage: %~nx0 [command]
|
||||
echo.
|
||||
echo Commands:
|
||||
echo install Install the Olm service
|
||||
echo remove Remove the Olm service
|
||||
echo start Start the Olm service
|
||||
echo stop Stop the Olm service
|
||||
echo status Show service status
|
||||
echo debug Run in debug mode
|
||||
echo help Show this help
|
||||
echo.
|
||||
echo Note: This script must be run as Administrator for service management.
|
||||
echo Make sure olm.exe is in your PATH or in the same directory.
|
||||
echo.
|
||||
pause
|
||||
85
olm-service.ps1
Normal file
85
olm-service.ps1
Normal file
@@ -0,0 +1,85 @@
|
||||
# Olm Windows Service Management Script
|
||||
# This PowerShell script helps manage the Olm WireGuard service on Windows
|
||||
|
||||
param(
|
||||
[Parameter(Position=0)]
|
||||
[ValidateSet("install", "remove", "uninstall", "start", "stop", "status", "debug", "help")]
|
||||
[string]$Command = "help"
|
||||
)
|
||||
|
||||
function Test-Administrator {
|
||||
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
|
||||
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
}
|
||||
|
||||
function Show-Help {
|
||||
Write-Host "Olm WireGuard Service Management" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Usage: .\olm-service.ps1 [command]" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
Write-Host "Commands:" -ForegroundColor Yellow
|
||||
Write-Host " install Install the Olm service"
|
||||
Write-Host " remove Remove the Olm service"
|
||||
Write-Host " start Start the Olm service"
|
||||
Write-Host " stop Stop the Olm service"
|
||||
Write-Host " status Show service status"
|
||||
Write-Host " debug Run in debug mode"
|
||||
Write-Host " help Show this help"
|
||||
Write-Host ""
|
||||
Write-Host "Note: This script must be run as Administrator for service management." -ForegroundColor Red
|
||||
Write-Host "Make sure olm.exe is in your PATH or in the same directory." -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
function Invoke-OlmCommand {
|
||||
param([string]$cmd)
|
||||
|
||||
if (-not (Test-Administrator) -and $cmd -ne "status" -and $cmd -ne "help") {
|
||||
Write-Error "This script must be run as Administrator for service management."
|
||||
Write-Host "Right-click PowerShell and select 'Run as administrator'" -ForegroundColor Yellow
|
||||
return $false
|
||||
}
|
||||
|
||||
try {
|
||||
$olmPath = Get-Command "olm.exe" -ErrorAction SilentlyContinue
|
||||
if (-not $olmPath) {
|
||||
# Try current directory
|
||||
$olmPath = Join-Path $PSScriptRoot "olm.exe"
|
||||
if (-not (Test-Path $olmPath)) {
|
||||
Write-Error "olm.exe not found in PATH or current directory"
|
||||
return $false
|
||||
}
|
||||
} else {
|
||||
$olmPath = $olmPath.Source
|
||||
}
|
||||
|
||||
Write-Host "Executing: $olmPath $cmd" -ForegroundColor Cyan
|
||||
$result = & $olmPath $cmd
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host $result -ForegroundColor Green
|
||||
Write-Host "Operation completed successfully." -ForegroundColor Green
|
||||
return $true
|
||||
} else {
|
||||
Write-Error "Command failed with exit code: $LASTEXITCODE"
|
||||
Write-Host $result -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
} catch {
|
||||
Write-Error "Failed to execute olm.exe: $($_.Exception.Message)"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
# Main execution
|
||||
switch ($Command.ToLower()) {
|
||||
"help" {
|
||||
Show-Help
|
||||
}
|
||||
default {
|
||||
$success = Invoke-OlmCommand -cmd $Command
|
||||
if (-not $success) {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
}
|
||||
1
olm.exe.REMOVED.git-id
Normal file
1
olm.exe.REMOVED.git-id
Normal file
@@ -0,0 +1 @@
|
||||
e077d9b8b025c4ca28748090a18728f14f60460c
|
||||
40
service_unix.go
Normal file
40
service_unix.go
Normal file
@@ -0,0 +1,40 @@
|
||||
//go:build !windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Service management functions are not available on non-Windows platforms
|
||||
func installService() error {
|
||||
return fmt.Errorf("service management is only available on Windows")
|
||||
}
|
||||
|
||||
func removeService() error {
|
||||
return fmt.Errorf("service management is only available on Windows")
|
||||
}
|
||||
|
||||
func startService() error {
|
||||
return fmt.Errorf("service management is only available on Windows")
|
||||
}
|
||||
|
||||
func stopService() error {
|
||||
return fmt.Errorf("service management is only available on Windows")
|
||||
}
|
||||
|
||||
func getServiceStatus() (string, error) {
|
||||
return "", fmt.Errorf("service management is only available on Windows")
|
||||
}
|
||||
|
||||
func isWindowsService() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func runService(name string, isDebug bool) {
|
||||
// No-op on non-Windows platforms
|
||||
}
|
||||
|
||||
func setupWindowsEventLog() {
|
||||
// No-op on non-Windows platforms
|
||||
}
|
||||
309
service_windows.go
Normal file
309
service_windows.go
Normal file
@@ -0,0 +1,309 @@
|
||||
//go:build windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/windows/svc"
|
||||
"golang.org/x/sys/windows/svc/debug"
|
||||
"golang.org/x/sys/windows/svc/eventlog"
|
||||
"golang.org/x/sys/windows/svc/mgr"
|
||||
)
|
||||
|
||||
const (
|
||||
serviceName = "OlmWireguardService"
|
||||
serviceDisplayName = "Olm WireGuard VPN Service"
|
||||
serviceDescription = "Olm WireGuard VPN client service for secure network connectivity"
|
||||
)
|
||||
|
||||
type olmService struct {
|
||||
elog debug.Log
|
||||
ctx context.Context
|
||||
stop context.CancelFunc
|
||||
}
|
||||
|
||||
func (s *olmService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (bool, uint32) {
|
||||
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
|
||||
changes <- svc.Status{State: svc.StartPending}
|
||||
|
||||
// Start the main olm functionality
|
||||
go s.runOlm()
|
||||
|
||||
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
|
||||
|
||||
for {
|
||||
select {
|
||||
case c := <-r:
|
||||
switch c.Cmd {
|
||||
case svc.Interrogate:
|
||||
changes <- c.CurrentStatus
|
||||
case svc.Stop, svc.Shutdown:
|
||||
s.elog.Info(1, "Service stopping")
|
||||
changes <- svc.Status{State: svc.StopPending}
|
||||
s.stop()
|
||||
return false, 0
|
||||
default:
|
||||
s.elog.Error(1, fmt.Sprintf("Unexpected control request #%d", c))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *olmService) runOlm() {
|
||||
// Create a context that can be cancelled when the service stops
|
||||
s.ctx, s.stop = context.WithCancel(context.Background())
|
||||
|
||||
// Run the main olm logic in a separate goroutine
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
s.elog.Error(1, fmt.Sprintf("Olm panic: %v", r))
|
||||
}
|
||||
}()
|
||||
|
||||
// Call the main olm function
|
||||
runOlmMain(s.ctx)
|
||||
}()
|
||||
|
||||
// Wait for context cancellation
|
||||
<-s.ctx.Done()
|
||||
s.elog.Info(1, "Olm service context cancelled")
|
||||
}
|
||||
|
||||
func runService(name string, isDebug bool) {
|
||||
var err error
|
||||
var elog debug.Log
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
service := &olmService{elog: elog}
|
||||
err = run(name, service)
|
||||
if err != nil {
|
||||
elog.Error(1, fmt.Sprintf("%s service failed: %v", name, err))
|
||||
return
|
||||
}
|
||||
elog.Info(1, fmt.Sprintf("%s service stopped", name))
|
||||
}
|
||||
|
||||
func installService() error {
|
||||
exepath, err := os.Executable()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get executable path: %v", err)
|
||||
}
|
||||
|
||||
m, err := mgr.Connect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect to service manager: %v", err)
|
||||
}
|
||||
defer m.Disconnect()
|
||||
|
||||
s, err := m.OpenService(serviceName)
|
||||
if err == nil {
|
||||
s.Close()
|
||||
return fmt.Errorf("service %s already exists", serviceName)
|
||||
}
|
||||
|
||||
config := mgr.Config{
|
||||
ServiceType: 0x10, // SERVICE_WIN32_OWN_PROCESS
|
||||
StartType: mgr.StartAutomatic,
|
||||
ErrorControl: mgr.ErrorNormal,
|
||||
DisplayName: serviceDisplayName,
|
||||
Description: serviceDescription,
|
||||
BinaryPathName: exepath,
|
||||
}
|
||||
|
||||
s, err = m.CreateService(serviceName, exepath, config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create service: %v", err)
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
err = eventlog.InstallAsEventCreate(serviceName, eventlog.Error|eventlog.Warning|eventlog.Info)
|
||||
if err != nil {
|
||||
s.Delete()
|
||||
return fmt.Errorf("failed to install event log: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func removeService() error {
|
||||
m, err := mgr.Connect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect to service manager: %v", err)
|
||||
}
|
||||
defer m.Disconnect()
|
||||
|
||||
s, err := m.OpenService(serviceName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("service %s is not installed", serviceName)
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
// Stop the service if it's running
|
||||
status, err := s.Query()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to query service status: %v", err)
|
||||
}
|
||||
|
||||
if status.State != svc.Stopped {
|
||||
_, err = s.Control(svc.Stop)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to stop service: %v", err)
|
||||
}
|
||||
|
||||
// Wait for service to stop
|
||||
timeout := time.Now().Add(30 * time.Second)
|
||||
for status.State != svc.Stopped {
|
||||
if timeout.Before(time.Now()) {
|
||||
return fmt.Errorf("timeout waiting for service to stop")
|
||||
}
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
status, err = s.Query()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to query service status: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = s.Delete()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete service: %v", err)
|
||||
}
|
||||
|
||||
err = eventlog.Remove(serviceName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to remove event log: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func startService() error {
|
||||
m, err := mgr.Connect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect to service manager: %v", err)
|
||||
}
|
||||
defer m.Disconnect()
|
||||
|
||||
s, err := m.OpenService(serviceName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("service %s is not installed", serviceName)
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
err = s.Start()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to start service: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func stopService() error {
|
||||
m, err := mgr.Connect()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect to service manager: %v", err)
|
||||
}
|
||||
defer m.Disconnect()
|
||||
|
||||
s, err := m.OpenService(serviceName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("service %s is not installed", serviceName)
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
status, err := s.Control(svc.Stop)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to stop service: %v", err)
|
||||
}
|
||||
|
||||
timeout := time.Now().Add(30 * time.Second)
|
||||
for status.State != svc.Stopped {
|
||||
if timeout.Before(time.Now()) {
|
||||
return fmt.Errorf("timeout waiting for service to stop")
|
||||
}
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
status, err = s.Query()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to query service status: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getServiceStatus() (string, error) {
|
||||
m, err := mgr.Connect()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to connect to service manager: %v", err)
|
||||
}
|
||||
defer m.Disconnect()
|
||||
|
||||
s, err := m.OpenService(serviceName)
|
||||
if err != nil {
|
||||
return "Not Installed", nil
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
status, err := s.Query()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to query service status: %v", err)
|
||||
}
|
||||
|
||||
switch status.State {
|
||||
case svc.Stopped:
|
||||
return "Stopped", nil
|
||||
case svc.StartPending:
|
||||
return "Starting", nil
|
||||
case svc.StopPending:
|
||||
return "Stopping", nil
|
||||
case svc.Running:
|
||||
return "Running", nil
|
||||
case svc.ContinuePending:
|
||||
return "Continue Pending", nil
|
||||
case svc.PausePending:
|
||||
return "Pause Pending", nil
|
||||
case svc.Paused:
|
||||
return "Paused", nil
|
||||
default:
|
||||
return "Unknown", nil
|
||||
}
|
||||
}
|
||||
|
||||
func isWindowsService() bool {
|
||||
interactive, err := svc.IsWindowsService()
|
||||
return err == nil && interactive
|
||||
}
|
||||
|
||||
func setupWindowsEventLog() {
|
||||
// Create log directory if it doesn't exist
|
||||
logDir := filepath.Join(os.Getenv("PROGRAMDATA"), "Olm", "logs")
|
||||
os.MkdirAll(logDir, 0755)
|
||||
|
||||
logFile := filepath.Join(logDir, "olm.log")
|
||||
file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
if err == nil {
|
||||
log.SetOutput(file)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user