Documentation
¶
Overview ¶
Package service provides a simple way to create a system service. Currently supports Windows, Linux/(systemd | Upstart | SysV), and OSX/Launchd.
Windows controls services by setting up callbacks that is non-trivial. This is very different then other systems. This package provides the same API despite the substantial differences. It also can be used to detect how a program is called, from an interactive terminal or from a service manager.
Examples in the example/ folder.
package main import ( "log" "github.com/ianatha/service" ) var logger service.Logger type program struct{} func (p *program) Start(s service.Service) error { // Start should not block. Do the actual work async. go p.run() return nil } func (p *program) run() { // Do work here } func (p *program) Stop(s service.Service) error { // Stop should not block. Return with a few seconds. return nil } func main() { svcConfig := &service.Config{ Name: "GoServiceTest", DisplayName: "Go Service Test", Description: "This is a test Go service.", } prg := &program{} s, err := service.New(prg, svcConfig) if err != nil { log.Fatal(err) } logger, err = s.Logger(nil) if err != nil { log.Fatal(err) } err = s.Run() if err != nil { logger.Error(err) } }
Index ¶
- Constants
- Variables
- func BstrToString(bstr *uint16) string
- func ChooseSystem(a ...System)
- func Control(s Service, action string) error
- func GetElevatedUserToken(hToken windows.Handle) (windows.Handle, error)
- func GetTokenInformation(tokenHandle windows.Handle, tokenInformationClass TOKEN_INFORMATION_CLASS, ...) (err error)
- func GetTokenUser(hToken windows.Handle) (*windows.SID, error)
- func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error)
- func GetUserProfileDirectory(hToken windows.Handle, lpProfileDir *uint16, lpcchSize *uint32) (err error)
- func GetUserSid() (sid *windows.SID, err error)
- func Interactive() bool
- func InteractiveUserToken(timeout time.Duration) (hToken windows.Handle, err error)
- func LpstrToString(lpstr *uint16) string
- func MakeDoubleNullTerminatedLpstr(items ...string) *uint16
- func Platform() string
- func ProfileDirectory(hToken windows.Handle) (string, error)
- func RunAdminCommandAsLoggedInUser()
- func SidToUsername(sid *windows.SID) (string, error)
- func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, ...) (err error)
- func WTSCloseServer(handle syscall.Handle)
- func WTSEnumerateSessions(server syscall.Handle, reserved uint32, version uint32, ...) error
- func WTSFreeMemory(memory *byte)
- func WTSGetActiveConsoleSessionId() (sessionId uint32, err error)
- func WTSLogoffSession(handle syscall.Handle, sessionId uint32, wait bool) error
- func WTSOpenServer(serverName *uint16) syscall.Handle
- func WTSQuerySessionInformation(hServer windows.Handle, sessionId uint32, WTSInfoClass WTS_INFO_CLASS, ...) (err error)
- func WTSQueryUserToken(sessionId uint32, phToken *windows.Handle) (err error)
- type AddressFamily
- type Config
- type Interface
- type KeyValue
- type Logger
- type Service
- type Status
- type System
- type TOKEN_INFORMATION_CLASS
- type TOKEN_LINKED_TOKEN
- type TOKEN_USER
- type WTSCLIENT
- type WTSClientDisplayStruct
- type WTSClientInfoStruct
- type WTSClientProtocolTypeEnum
- type WTSConnectStateEnum
- type WTSINFO
- type WTSInfo
- type WTSSESSION_NOTIFICATION
- type WTSServer
- func (wts *WTSServer) Close()
- func (wts *WTSServer) EnumerateSessions() ([]WTSSessionInfoStruct, error)
- func (wts *WTSServer) LogoffSession(sessionID uint, wait bool) error
- func (wts *WTSServer) QuerySessionAddressV4(sessionID uint) (wrappers.WTS_CLIENT_ADDRESS, error)
- func (wts *WTSServer) QuerySessionApplicationName(sessionID uint) (string, error)
- func (wts *WTSServer) QuerySessionClientAddress(sessionID uint) (net.IP, error)
- func (wts *WTSServer) QuerySessionClientBuildNumber(sessionID uint) (uint32, error)
- func (wts *WTSServer) QuerySessionClientDirectory(sessionID uint) (string, error)
- func (wts *WTSServer) QuerySessionClientDisplay(sessionID uint) (WTSClientDisplayStruct, error)
- func (wts *WTSServer) QuerySessionClientHardwareId(sessionID uint) (uint32, error)
- func (wts *WTSServer) QuerySessionClientInfo(sessionID uint) (WTSClientInfoStruct, error)
- func (wts *WTSServer) QuerySessionClientName(sessionID uint) (string, error)
- func (wts *WTSServer) QuerySessionClientProductId(sessionID uint) (uint16, error)
- func (wts *WTSServer) QuerySessionClientProtocolType(sessionID uint) (WTSClientProtocolTypeEnum, error)
- func (wts *WTSServer) QuerySessionConnectState(sessionID uint) (WTSConnectStateEnum, error)
- func (wts *WTSServer) QuerySessionDomainName(sessionID uint) (string, error)
- func (wts *WTSServer) QuerySessionID(sessionID uint) (uint, error)
- func (wts *WTSServer) QuerySessionInitialProgram(sessionID uint) (string, error)
- func (wts *WTSServer) QuerySessionIsRemoteSession(sessionID uint) (bool, error)
- func (wts *WTSServer) QuerySessionSesionInfo(sessionID uint) (WTSInfo, error)
- func (wts *WTSServer) QuerySessionUserName(sessionID uint) (string, error)
- func (wts *WTSServer) QuerySessionWinStationName(sessionID uint) (string, error)
- func (wts *WTSServer) QuerySessionWorkingDirectory(sessionID uint) (string, error)
- func (wts *WTSServer) QueryUserToken(sessionID uint) (*syscall.Handle, error)
- type WTSSessionInfoStruct
- type WTS_CLIENT_ADDRESS
- type WTS_CLIENT_DISPLAY
- type WTS_INFO_CLASS
- type WTS_SESSION_INFO
Constants ¶
const ( CREATE_BREAKAWAY_FROM_JOB = 0x01000000 CREATE_NEW_CONSOLE = 0x00000010 CREATE_NEW_PROCESS_GROUP = 0x00000200 MAX_PATH = 260 )
const ( CLIENTNAME_LENGTH = 20 DOMAIN_LENGTH = 17 USERNAME_LENGTH = 20 CLIENTADDRESS_LENGTH = 30 WINSTATIONNAME_LENGTH = 32 )
Misc consts from WtsApi32.h
const ( WTSActive = 0 WTSConnected = 1 WTSConnectQuery = 2 WTSShadow = 3 WTSDisconnected = 4 WTSIdle = 5 WTSListen = 6 WTSReset = 7 WTSDown = 8 WTSInit = 9 )
WTS_CONNECTSTATE_CLASS enumeration
const ( WTSInitialProgram = 0 WTSApplicationName = 1 WTSWorkingDirectory = 2 WTSOEMId = 3 WTSSessionId = 4 WTSUserName = 5 WTSWinStationName = 6 WTSDomainName = 7 WTSConnectState = 8 WTSClientBuildNumber = 9 WTSClientName = 10 WTSClientDirectory = 11 WTSClientProductId = 12 WTSClientHardwareId = 13 WTSClientAddress = 14 WTSClientDisplay = 15 WTSClientProtocolType = 16 WTSIdleTime = 17 WTSLogonTime = 18 WTSIncomingBytes = 19 WTSOutgoingBytes = 20 WTSIncomingFrames = 21 WTSOutgoingFrames = 22 WTSClientInfo = 23 WTSSessionInfo = 24 WTSSessionInfoEx = 25 WTSConfigInfo = 26 WTSValidationInfo = 27 WTSSessionAddressV4 = 28 WTSIsRemoteSession = 29 )
WTS_INFO_CLASS enumeration
const ERROR_SUCCESS = 0
Variables ¶
var ( // ErrNameFieldRequired is returned when Config.Name is empty. ErrNameFieldRequired = errors.New("Config.Name field is required.") // ErrNoServiceSystemDetected is returned when no system was detected. ErrNoServiceSystemDetected = errors.New("No service system detected.") // ErrNotInstalled is returned when the service is not installed ErrNotInstalled = errors.New("the service is not installed") )
var ConsoleLogger = consoleLogger{}
ConsoleLogger logs to the std err.
var ControlAction = [5]string{"start", "stop", "restart", "install", "uninstall"}
ControlAction list valid string texts to use in Control.
Functions ¶
func BstrToString ¶
func ChooseSystem ¶
func ChooseSystem(a ...System)
ChooseSystem chooses a system from the given system services. SystemServices are considered in the order they are suggested. Calling this may change what Interactive and Platform return.
func GetElevatedUserToken ¶
func GetTokenInformation ¶
func GetUserNameEx ¶
func GetUserProfileDirectory ¶
func GetUserSid ¶
func Interactive ¶
func Interactive() bool
Interactive returns false if running under the OS service manager and true otherwise.
func InteractiveUserToken ¶
InteractiveUserToken returns a user token (security context) for the interactive desktop session attached to the default console (i.e. what would be seen on a display connected directly to the computer, rather than a remote RDP session). It must be called from a process which is running under LocalSystem account in order to have the necessary privileges (typically a Windows service). Since the service might be running before a local logon occurs, a timeout can be specified for waiting for a successful logon (via winlogon) to occur. The returned token can be used in e.g. CreateProcessAsUser system call, which allows e.g. a Windows service to run a process in the interactive desktop session, as if the logged in user had executed the process directly. The function additionally waits for the user profile directory to exist, before returning.
func LpstrToString ¶
func ProfileDirectory ¶
ProfileDirectory returns the profile directory of the user represented by the given user handle
func RunAdminCommandAsLoggedInUser ¶
func RunAdminCommandAsLoggedInUser()
https://gist.github.com/petemoore/8e43861943d175076e4b365039c8d5cd
func TranslateName ¶
func WTSCloseServer ¶
func WTSEnumerateSessions ¶
func WTSFreeMemory ¶
func WTSFreeMemory(memory *byte)
func WTSLogoffSession ¶
func WTSOpenServer ¶
Types ¶
type AddressFamily ¶
type AddressFamily uint32
const ( AddressFamilyUnspecified AddressFamily = wrappers.AF_UNSPEC AddressFamilyIP AddressFamily = wrappers.AF_INET AddressFamilyIPX AddressFamily = wrappers.AF_IPX AddressFamilyAppleTalk AddressFamily = wrappers.AF_APPLETALK AddressFamilyNetBIOS AddressFamily = wrappers.AF_NETBIOS AddressFamilyIPv6 AddressFamily = wrappers.AF_INET6 AddressFamilyIrDA AddressFamily = wrappers.AF_IRDA AddressFamilyBluetooth AddressFamily = wrappers.AF_BTH )
type Config ¶
type Config struct { Name string // Required name of the service. No spaces suggested. DisplayName string // Display name, spaces allowed. Description string // Long description of service. UserName string // Run as username. Arguments []string // Run with arguments. // Optional field to specify the executable for service. // If empty the current executable is used. Executable string // Array of service dependencies. // Not yet fully implemented on Linux or OS X: // 1. Support linux-systemd dependencies, just put each full line as the // element of the string array, such as // "After=network.target syslog.target" // "Requires=syslog.target" // Note, such lines will be directly appended into the [Unit] of // the generated service config file, will not check their correctness. Dependencies []string // The following fields are not supported on Windows. WorkingDirectory string // Initial working directory. ChRoot string // System specific options. // * OS X // - LaunchdConfig string () - Use custom launchd config // - KeepAlive bool (true) // - RunAtLoad bool (false) // - UserService bool (false) - Install as a current user service. // - SessionCreate bool (false) - Create a full user session. // * POSIX // - SystemdScript string () - Use custom systemd script // - UpstartScript string () - Use custom upstart script // - SysvScript string () - Use custom sysv script // - RunWait func() (wait for SIGNAL) - Do not install signal but wait for this function to return. // - ReloadSignal string () [USR1, ...] - Signal to send on reaload. // - PIDFile string () [/run/prog.pid] - Location of the PID file. // - LogOutput bool (false) - Redirect StdErr & StandardOutPath to files. // - Restart string (always) - How shall service be restarted. // - SuccessExitStatus string () - The list of exit status that shall be considered as successful, // in addition to the default ones. Option KeyValue WindowsExtraEvents chan WindowsEvent }
Config provides the setup for a Service. The Name field is required.
type Interface ¶
type Interface interface { // Start provides a place to initiate the service. The service doesn't not // signal a completed start until after this function returns, so the // Start function must not take more then a few seconds at most. Start(s Service) error // Stop provides a place to clean up program execution before it is terminated. // It should not take more then a few seconds to execute. // Stop should not call os.Exit directly in the function. Stop(s Service) error }
Interface represents the service interface for a program. Start runs before the hosting process is granted control and Stop runs when control is returned.
- OS service manager executes user program.
- User program sees it is executed from a service manager (IsInteractive is false).
- User program calls Service.Run() which blocks.
- Interface.Start() is called and quickly returns.
- User program runs.
- OS service manager signals the user program to stop.
- Interface.Stop() is called and quickly returns. - For a successful exit, os.Exit should not be called in Interface.Stop().
- Service.Run returns.
- User program should quickly exit.
type KeyValue ¶
type KeyValue map[string]interface{}
KeyValue provides a list of platform specific options. See platform docs for more details.
type Logger ¶
type Logger interface { Error(v ...interface{}) error Warning(v ...interface{}) error Info(v ...interface{}) error Errorf(format string, a ...interface{}) error Warningf(format string, a ...interface{}) error Infof(format string, a ...interface{}) error }
Logger writes to the system log.
type Service ¶
type Service interface { // Run should be called shortly after the program entry point. // After Interface.Stop has finished running, Run will stop blocking. // After Run stops blocking, the program must exit shortly after. Run() error // Start signals to the OS service manager the given service should start. Start() error // Stop signals to the OS service manager the given service should stop. Stop() error // Restart signals to the OS service manager the given service should stop then start. Restart() error // Install setups up the given service in the OS service manager. This may require // greater rights. Will return an error if it is already installed. Install() error // Uninstall removes the given service from the OS service manager. This may require // greater rights. Will return an error if the service is not present. Uninstall() error // Opens and returns a system logger. If the user program is running // interactively rather then as a service, the returned logger will write to // os.Stderr. If errs is non-nil errors will be sent on errs as well as // returned from Logger's functions. Logger(errs chan<- error) (Logger, error) // SystemLogger opens and returns a system logger. If errs is non-nil errors // will be sent on errs as well as returned from Logger's functions. SystemLogger(errs chan<- error) (Logger, error) // String displays the name of the service. The display name if present, // otherwise the name. String() string // Platform displays the name of the system that manages the service. // In most cases this will be the same as service.Platform(). Platform() string // Status returns the current service status. Status() (Status, error) }
Service represents a service that can be run or controlled.
type System ¶
type System interface { // String returns a description of the system. String() string // Detect returns true if the system is available to use. Detect() bool // Interactive returns false if running under the system service manager // and true otherwise. Interactive() bool // New creates a new service for this system. New(i Interface, c *Config) (Service, error) }
System represents the service manager that is available.
func AvailableSystems ¶
func AvailableSystems() []System
AvailableSystems returns the list of system services considered when choosing the system service.
func ChosenSystem ¶
func ChosenSystem() System
ChosenSystem returns the system that service will use.
type TOKEN_INFORMATION_CLASS ¶
type TOKEN_INFORMATION_CLASS uint32
type TOKEN_LINKED_TOKEN ¶
https://msdn.microsoft.com/en-us/library/windows/desktop/bb530719(v=vs.85).aspx
typedef struct _TOKEN_LINKED_TOKEN { HANDLE LinkedToken; } TOKEN_LINKED_TOKEN, *PTOKEN_LINKED_TOKEN;
type TOKEN_USER ¶
type TOKEN_USER struct {
User windows.SIDAndAttributes
}
type WTSCLIENT ¶
type WTSCLIENT struct { ClientName [CLIENTNAME_LENGTH + 1]uint16 Domain [DOMAIN_LENGTH + 1]uint16 UserName [USERNAME_LENGTH + 1]uint16 WorkDirectory [MAX_PATH + 1]uint16 InitialProgram [MAX_PATH + 1]uint16 EncryptionLevel byte ClientAddressFamily uint32 ClientAddress [CLIENTADDRESS_LENGTH + 1]uint16 HRes uint16 VRes uint16 ColorDepth uint16 ClientDirectory [MAX_PATH + 1]uint16 ClientBuildNumber uint32 ClientHardwareId uint32 ClientProductId uint16 OutBufCountHost uint16 OutBufCountClient uint16 OutBufLength uint16 DeviceId [MAX_PATH + 1]uint16 }
type WTSClientDisplayStruct ¶
type WTSClientDisplayStruct struct { HorizontalResolution uint VerticalResolution uint ColorDepth uint }
WTSClientDisplayStruct - go version of WTS_CLIENT_DISPLAY structure
type WTSClientInfoStruct ¶
type WTSClientInfoStruct struct { ClientName string Domain string UserName string WorkDirectory string InitialProgram string EncryptionLevel byte ClientAddressFamily AddressFamily HRes uint VRes uint ColorDepth uint ClientDirectory string ClientBuildNumber uint ClientHardwareId uint ClientProductId uint OutBufCountHost uint OutBufCountClient uint OutBufLength uint DeviceID string // contains filtered or unexported fields }
WTSClientInfoStruct - go version of WTSCLIENT structure
func (*WTSClientInfoStruct) ClientAddressToIP ¶
func (ci *WTSClientInfoStruct) ClientAddressToIP() (net.IP, error)
type WTSClientProtocolTypeEnum ¶
type WTSClientProtocolTypeEnum uint32
WTSClientProtocolType enum type go version of WTSClientProtocolType
const ( WTSClientProtocolConsoleSession WTSClientProtocolTypeEnum = 0 WTSClientProtocolInternal WTSClientProtocolTypeEnum = 1 WTSClientProtocolRDP WTSClientProtocolTypeEnum = 2 )
type WTSConnectStateEnum ¶
type WTSConnectStateEnum uint32
WTSConnectState enum type - Go version of WTS_CONNECTSTATE_CLASS
const ( WTSConnectStateActive WTSConnectStateEnum = WTSActive WTSConnectStateConnected WTSConnectStateEnum = WTSConnected WTSConnectStateConnectQuery WTSConnectStateEnum = WTSConnectQuery WTSConnectStateShadow WTSConnectStateEnum = WTSShadow WTSConnectStateDisconnected WTSConnectStateEnum = WTSDisconnected WTSConnectStateIdle WTSConnectStateEnum = WTSIdle WTSConnectStateListen WTSConnectStateEnum = WTSListen WTSConnectStateReset WTSConnectStateEnum = WTSReset WTSConnectStateDown WTSConnectStateEnum = WTSDown WTSConnectStateInit WTSConnectStateEnum = WTSInit )
type WTSINFO ¶
type WTSINFO struct { State uint32 SessionId uint32 IncomingBytes uint32 OutgoingBytes uint32 IncomingFrames uint32 OutgoingFrames uint32 IncomingCompressedBytes uint32 OutgoingCompressedBytes uint32 WinStationName [WINSTATIONNAME_LENGTH]uint16 Domain [DOMAIN_LENGTH]uint16 UserName [USERNAME_LENGTH + 1]uint16 ConnectTime int64 DisconnectTime int64 LastInputTime int64 LogonTime int64 CurrentTime int64 }
type WTSInfo ¶
type WTSInfo struct { State WTSConnectStateEnum SessionID uint IncomingBytes uint OutgoingBytes uint IncomingFrames uint OutgoingFrames uint IncomingCompressedBytes uint OutgoingCompressedBytes uint WinStationName string Domain string UserName string ConnectTime time.Time DisconnectTime time.Time LastInputTime time.Time LogonTime time.Time CurrentTime time.Time }
Info - go version of WTSINFO structure
type WTSSESSION_NOTIFICATION ¶
type WTSServer ¶
type WTSServer struct {
// contains filtered or unexported fields
}
func OpenWTSServer ¶
func (*WTSServer) EnumerateSessions ¶
func (wts *WTSServer) EnumerateSessions() ([]WTSSessionInfoStruct, error)
func (*WTSServer) LogoffSession ¶
func (*WTSServer) QuerySessionAddressV4 ¶
func (wts *WTSServer) QuerySessionAddressV4(sessionID uint) (wrappers.WTS_CLIENT_ADDRESS, error)
func (*WTSServer) QuerySessionApplicationName ¶
func (*WTSServer) QuerySessionClientAddress ¶
func (*WTSServer) QuerySessionClientBuildNumber ¶
func (*WTSServer) QuerySessionClientDirectory ¶
func (*WTSServer) QuerySessionClientDisplay ¶
func (wts *WTSServer) QuerySessionClientDisplay(sessionID uint) (WTSClientDisplayStruct, error)
func (*WTSServer) QuerySessionClientHardwareId ¶
func (*WTSServer) QuerySessionClientInfo ¶
func (wts *WTSServer) QuerySessionClientInfo(sessionID uint) (WTSClientInfoStruct, error)
func (*WTSServer) QuerySessionClientName ¶
func (*WTSServer) QuerySessionClientProductId ¶
func (*WTSServer) QuerySessionClientProtocolType ¶
func (wts *WTSServer) QuerySessionClientProtocolType(sessionID uint) (WTSClientProtocolTypeEnum, error)
func (*WTSServer) QuerySessionConnectState ¶
func (wts *WTSServer) QuerySessionConnectState(sessionID uint) (WTSConnectStateEnum, error)
func (*WTSServer) QuerySessionDomainName ¶
func (*WTSServer) QuerySessionID ¶
func (*WTSServer) QuerySessionInitialProgram ¶
func (*WTSServer) QuerySessionIsRemoteSession ¶
func (*WTSServer) QuerySessionSesionInfo ¶
func (*WTSServer) QuerySessionUserName ¶
func (*WTSServer) QuerySessionWinStationName ¶
func (*WTSServer) QuerySessionWorkingDirectory ¶
type WTSSessionInfoStruct ¶
type WTSSessionInfoStruct struct { SessionID uint WinStationName string State WTSConnectStateEnum }
WTSSessionInfoStruct - go version of WTS_SESSION_INFO structure
type WTS_CLIENT_ADDRESS ¶
type WTS_CLIENT_DISPLAY ¶
type WTS_INFO_CLASS ¶
type WTS_INFO_CLASS uint32
type WTS_SESSION_INFO ¶
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
example
|
|
logging
Simple service that only works by printing a log message every few seconds.
|
Simple service that only works by printing a log message every few seconds. |
runner
Simple service that only works by printing a log message every few seconds.
|
Simple service that only works by printing a log message every few seconds. |
simple
simple does nothing except block while running the service.
|
simple does nothing except block while running the service. |
stopPause
simple does nothing except block while running the service.
|
simple does nothing except block while running the service. |