Documentation
¶
Overview ¶
NOTE: THIS DESCRIBES INTENT, AND DOES NOT REFLECT ACTUAL IMPLEMENTATION (YET!!)
Package govisor provides a pure Go process management framework. This is similar in concept to supervisord, but the implementation and the interfaces are wholly different. Some inspiration is taken from Solaris' SMF facility.
Unlike other frameworks, the intention is that this framework is not a replacement for your system's master process management (i.e. init, upstart, or similar), but rather a tool for user's (or administrators) to manage their own groups of processes as part of application deployment.
Multiple instances of govisor may be deployed, and an instance may be deployed using Go's HTTP handler framework, so that it is possible to register the manager within an existing server instance.
Index ¶
- Constants
- Variables
- type Log
- type LogRecord
- type Manager
- func (m *Manager) AddService(s *Service)
- func (m *Manager) DeleteService(s *Service) error
- func (m *Manager) FindServices(match string) []*Service
- func (m *Manager) GetInfo() *ManagerInfo
- func (m *Manager) GetLog(lastid int64) ([]LogRecord, int64)
- func (m *Manager) Name() string
- func (m *Manager) Serial() int64
- func (m *Manager) Services() ([]*Service, int64, time.Time)
- func (m *Manager) SetLogger(l *log.Logger)
- func (m *Manager) Shutdown()
- func (m *Manager) StartMonitoring()
- func (m *Manager) StopMonitoring()
- func (m *Manager) WatchLog(old int64, expire time.Duration) int64
- func (m *Manager) WatchSerial(old int64, expire time.Duration) int64
- func (m *Manager) WatchServices(old int64, expire time.Duration) int64
- type ManagerInfo
- type MultiLogger
- type Process
- func (p *Process) Check() error
- func (p *Process) Conflicts() []string
- func (p *Process) Depends() []string
- func (p *Process) Description() string
- func (p *Process) Name() string
- func (p *Process) Property(n PropertyName) (interface{}, error)
- func (p *Process) Provides() []string
- func (p *Process) SetProperty(n PropertyName, v interface{}) error
- func (p *Process) Start() error
- func (p *Process) Stop()
- type ProcessManifest
- type PropertyName
- type Provider
- type Service
- func (s *Service) Check() error
- func (s *Service) Clear()
- func (s *Service) Conflicts() []string
- func (s *Service) Depends() []string
- func (s *Service) Description() string
- func (s *Service) Disable() error
- func (s *Service) Enable() error
- func (s *Service) Enabled() bool
- func (s *Service) Failed() bool
- func (s *Service) GetLog(lastid int64) ([]LogRecord, int64)
- func (s *Service) GetProperty(n PropertyName) (interface{}, error)
- func (s *Service) Matches(check string) bool
- func (s *Service) Name() string
- func (s *Service) Provides() []string
- func (s *Service) Restart() error
- func (s *Service) Running() bool
- func (s *Service) Serial() int64
- func (s *Service) SetProperty(n PropertyName, v interface{}) error
- func (s *Service) Status() (string, time.Time)
- func (s *Service) WatchLog(old int64, expire time.Duration) int64
- func (s *Service) WatchService(old int64, expire time.Duration) int64
Constants ¶
const ( PropProcessFailOnExit PropertyName = "_ProcFailOnExit" PropProcessStopCmd = "_ProcStopCmd" PropProcessStopTime = "_ProcStopTime" PropProcessCheckCmd = "_ProcCheckCmd" )
const ( PropLogger PropertyName = "_Logger" // Where logs get sent PropRestart = "_Restart" // Auto-restart on failure PropRateLimit = "_RateLimit" // Max starts per period PropRatePeriod = "_RatePeriod" // Period for RateLimit PropName = "_Name" // Service name PropDescription = "_Description" // Service description PropDepends = "_Depends" // Dependencies list PropConflicts = "_Conflicts" // Conflicts list PropProvides = "_Provides" // Provides list PropNotify = "_Notify" // Notification callback )
const (
MaxLogRecords = 1000
)
Variables ¶
var ( ErrNoManager = errors.New("No manager for service") ErrConflict = errors.New("Conflicting service enabled") ErrIsEnabled = errors.New("Service is enabled") ErrNotRunning = errors.New("Service is not running") ErrBadPropType = errors.New("Bad property type") ErrBadPropName = errors.New("Bad property name") ErrBadPropValue = errors.New("Bad property value") ErrPropReadOnly = errors.New("Property not changeable") ErrRateLimited = errors.New("Restarting too quickly") )
Functions ¶
This section is empty.
Types ¶
type Log ¶
type Log struct {
// contains filtered or unexported fields
}
func (*Log) GetRecords ¶
GetRecords returns the records that are stored, as well as an ID suitable for use as an Etag. The last parameter can be the last ID that was checked, in which case this function will return nil immediately if the log has not changed since that ID was returned, without duplicating any records. These IDs are suitable for use as an Etag in REST APIs. Note that IDs are not unique across different Log instances.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
func NewManager ¶
func (*Manager) AddService ¶
AddService adds a service, registering it, to the manager.
func (*Manager) DeleteService ¶
DeleteService deletes a service from the manager.
func (*Manager) FindServices ¶
FindServices finds the list of services that have either a matching Name, or Provides. That is, they find all of our services, where the service.Match() would return true for the string match.
func (*Manager) GetInfo ¶
func (m *Manager) GetInfo() *ManagerInfo
GetInfo returns top-level information about the Manager. This is done in a manner that ensures that the info is consistent.
func (*Manager) Name ¶
Name returns the name the manager was allocated with. This makes it possible to distinguish between separate manager instances. This name can influence logged messages and file/directory names.
func (*Manager) Serial ¶
Serial returns the global serial number. This is incremented anytime a service has a state change.
func (*Manager) Services ¶
Services returns all of our services. Note that the order is arbitrary. (At present it happens to be done based on order of addition.)
func (*Manager) SetLogger ¶
SetLogger is used to establish a logger. It overrides the default, so it shouldn't be used unless you want to control all logging.
func (*Manager) Shutdown ¶
func (m *Manager) Shutdown()
Shutdown stops all services, and stops monitoring too. Finally, it removes them all from the manager. Think of this as effectively tearing down the entire thing.
func (*Manager) StartMonitoring ¶
func (m *Manager) StartMonitoring()
func (*Manager) StopMonitoring ¶
func (m *Manager) StopMonitoring()
func (*Manager) WatchSerial ¶
WatchSerial monitors for a change in the global serial number.
type ManagerInfo ¶
type MultiLogger ¶
type MultiLogger struct {
// contains filtered or unexported fields
}
MultiLogger implements a wrapper around log.Logger, that permits a single logger interface to be used to fan out multiple logs. The idea is that it implements an io.Writer, which breaks up the lines and delivers them each to the various contained loggers. The contained loggers may have their own Prefix and Flags, and those shall not interfere with the parent.
func NewMultiLogger ¶
func NewMultiLogger() *MultiLogger
func (*MultiLogger) AddLogger ¶
func (l *MultiLogger) AddLogger(logger *log.Logger)
AddLogger adds a logger to the MultiLogger. Once called, all new log entries will be fanned out to this logger, as well as any others that may have been registered earlier. A logger can only be added once.
func (*MultiLogger) DelLogger ¶
func (l *MultiLogger) DelLogger(logger *log.Logger)
DeleteLogger is removes a logger from the list of destinations that logged events are fanned out to.
func (*MultiLogger) Logger ¶
func (l *MultiLogger) Logger() *log.Logger
func (*MultiLogger) SetFlags ¶
func (l *MultiLogger) SetFlags(flags int)
SetFlags applies the flags to every registered logger.
func (*MultiLogger) SetPrefix ¶
func (l *MultiLogger) SetPrefix(prefix string)
SetPrefix applies the prefix to every registered logger.
func (*MultiLogger) Write ¶
func (l *MultiLogger) Write(b []byte) (int, error)
Write implements the io.Writer, suitable for use with Logger. It is expected that the input is text, delimited by newlines, and delivered an entire line at a time. This isn't exactly io.Writer, but it is the semantic to which the log.Logger interface conforms.
type Process ¶
type Process struct {
// contains filtered or unexported fields
}
Process represents an actual operating system level process. This implements the Provider interface, and hence Process objects can used as such.
XXX: is there any reason for this to be public? XXX: Should we support Setsid and other SysProcAttr settings?
func (*Process) Description ¶
func (*Process) Property ¶
func (p *Process) Property(n PropertyName) (interface{}, error)
func (*Process) SetProperty ¶
func (p *Process) SetProperty(n PropertyName, v interface{}) error
type ProcessManifest ¶
type ProcessManifest struct { Name string `json:"name"` Description string `json:"description"` Command []string `json:"command"` Env []string `json:"env"` StopCmd []string `json:"stopCommand"` StopTime time.Duration `json:"stopTime"` FailOnExit bool `json:"failOnExit"` CheckCmd []string `json:"check"` Restart bool `json:"restart"` Provides []string `json:"provides"` Depends []string `json:"depends"` Conflicts []string `json:"conflicts"` }
type PropertyName ¶
type PropertyName string
Property names. Internal names will all start with an underscore. Other, provider specific names, may be supplied. Note that there is no provision for property discovery. Consumers wishing to use a property must know the property name and type.
type Provider ¶
type Provider interface { // Name returns the name of the provider. For example, a // provider for SMTP could return return "smtp" here. // For services that have variants, an optioanl variant can be // returned by appending a colon. For example, "smtp:sendmail" // indicates a variant using Berkeley sendmail, whereas "smtp:qmail" // indicates a variant using qmail. Both of these would satisfy // a dependency of "smtp". Names may include any alpha numeric, // or the underscore. No punctuation (modulo the colon separating // primary name and variant) may be used. Name() string // Description returns what you think. Should be only 32 characters // to avoid UI truncation. Description() string // Provides returns a list of service names that this provides. // The Name is implicitly added, so only additional values need to // be listed. Provides() []string // Depends returns a list of dependencies, that must be satisfied // in order for this service to run. These are names, that can be // either fully qualified (such as "smtp:postfix" or just the // base name (such as "smtp"). Depends() []string // Conflicts returns a list of incompatible values. Note that // the service itself is excluded when checking, so that one could // have a service list conflicts of "smtp", even though it provides // "smtp:postfix". This would ensure that it does not run with any // any other service. Conflicts() []string // Start attempts to start the service. It blocks until the service // is either started successfuly, or has definitively failed. Start() error // Stop attempts to stop the service. As with Start, it blocks until // the operation is complete. This is never allowed to fail. Stop() // Check performs a health check on the service. This can be just // a check that a process is running, or it can include verification // by using test protocol packets or queries, or whatever is // appropriate. It runs synchronously as well. If all is well it // returns nil, otherwise it returns an error. The error message, // provided by Error(), should give some clue as to the reason for the // failed check. Check() error // Property returns the value of a property. Property(PropertyName) (interface{}, error) // SetProperty sets the value of a property. SetProperty(PropertyName, interface{}) error }
Provider is what service providers must implement. Note that except for the Name and Dependencies elements, the service manager promises not to call these methods concurrently. That is, implementers need not worry about locking. Applications should not use this interface.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service describes a generic system service -- such as a process, or group of processes. Applications are expected to use the Service structure to interact with all managed services.
Implementors can provide custom services (which may be any kind of entity) by implementing the Provider interface.
Service methods are not thread safe, until the service is added to a Manager. Once the service is added to a Manager, the Manager's lock will protect concurrent accesses.
Services go through a number of possible states as illustrated in the following state diagram. Note that these states are logical, as there is no formal state machine in the code. This diagram is for illustration purposes only.
+------------+ | | +---------> Disabled <-------+ | | | | | +----+--A----+ | | | | | +-----+----+ +----V--+---+ | | | | | | | Failed +----> DepWait <----+ | | | | | | | +-----A--A-+ +----+------+ | | | | | | | | | +----v-------+ | | | | | | | | | +------+ Starting | | | | | | | | | +----+-------+ | | | | | | | +---V---+ | | | | | | | +----------+ Run +-------+---+ | | +-------+
func NewProcessFromManifest ¶
func NewProcessFromManifest(m ProcessManifest) *Service
func NewService ¶
NewService allocates a service instance from a Provider. The intention is that Providers use this in their own constructors to present only a Service interface to applications.
func (*Service) Check ¶
Check checks if a service is running, and performs any appropriate health checks. It returns nil if the service is running and healthy, or false otherwise. If it returns false, it will stop the service, as well as dependent services, and put the service into failed state.
func (*Service) Clear ¶
func (s *Service) Clear()
Clear clears any error condition in the service, without actually enabling it. It will attempt to start the service if it isn't already running, and is enabled.
func (*Service) Conflicts ¶
Conflicts returns a list of strings or service names that cannot be enabled with this one. The system will make sure that attempts to enable the service are rejected. Note that the scope of conflict is limited to a single Manager; that is the check will not prevent two conflicting services running under the control of different Managers.
func (*Service) Depends ¶
Depends returns a list of service names. See the Name description for how these are used.
func (*Service) Description ¶
Description returns a descriptive name for the service. If possible, user interfaces should try to allocate at least 32 characters of horizontal space when displaying descriptions.
func (*Service) Disable ¶
Disable disables the service, stopping it. It also will stop any services which will no longer have satisfied dependencies as a result of this service being disabled. It also clears the error state.
func (*Service) Enable ¶
Enable enables the service. This will also start any services that may have not been running due to unsatisfied dependencies, but which now are able to (and were otherwise enabled.)
func (*Service) GetProperty ¶
func (s *Service) GetProperty(n PropertyName) (interface{}, error)
func (*Service) Matches ¶
Matches returns true if the service name matches the check. This is true if either the check is a complete match, or if the first part of our name (or Provides) is identical to the check. For example, if our name is "x:y", then this would return true for a check of "x", or "x:y", but not for "x:z", nor "z:y".
func (*Service) Name ¶
The service name. This takes either the form <base> or <base>:<variant>. Except for the colon used to separate the <base> from <variant>, no punctuation characters other than underscores are permitted. When attempting to resolve dependencies, a dependency can list either the full <base>:<variant> name or just <base>. In the former case, the full service name must match. In the latter case, any service with the same <base> component matches.
func (*Service) Provides ¶
Provides is a way to indicate other service names that this service offers. This permits a service instance to support multiple real capabilities, or to provide multiple aliases. For example, a daemon might offer "http" and "ftp" both.
func (*Service) Restart ¶
Restart restarts a service. It also clears any failure condition that may have occurred.
func (*Service) Running ¶
Running checks if a service is running. This will be false if the service has failed for any reason, or is unable to run due to a missing dependency.
func (*Service) SetProperty ¶
func (s *Service) SetProperty(n PropertyName, v interface{}) error
SetProperty sets a property on the service.
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
Command govisor implements a client application that communicate to govisord.
|
Command govisor implements a client application that communicate to govisord. |
util
Package util is used for internal implementation bits in the CLI/UI.
|
Package util is used for internal implementation bits in the CLI/UI. |
Command govisord implements a daemon that can manage proceses from manifest files using Govisor.
|
Command govisord implements a daemon that can manage proceses from manifest files using Govisor. |
Package rest implements REST API methods for remotely managing govisor.
|
Package rest implements REST API methods for remotely managing govisor. |