- Starting and stopping processes
- Controlling the Daemon
- Managing clusters
- Installing and running apps
- Remote access and monitoring (e.g. guv-web)
- Web interface
- Web interface - configuration
- Web interface - user management
- Programmatic access
- Programmatic access - local
- Programmatic access - remote
- Programmatic access - events
A interface to an instance of guvnor running on the same host.
var Local = require('guvnor').Local
All methods take an optional config argument and an optional logger argument.
The config argument is a plain object of config settings as loaded from the config file. If omitted, the default config file will be loaded and it's properties overwritten by the config file at /etc/guvnor/guvnor
if available.
If specified the logger argument must have the following structure:
{
info: function() {},
warn: function() {},
error: function() {},
debug: function() {}
}
If omitted it defaults to console.info
and friends with debug
being a no-op.
The passed callback will receive a boolean value indicating if the daemon is running or not.
Local.running(function(running) {
console.info('Daemon is', running ? 'running' : 'not running')
})
Attempts to connect to an already running daemon. If the daemon is not running the callback will receive an error.
Local.connect(function(error, daemon) {
if(error) {
if(error.code == 'DAEMON_NOT_RUNNING') {
// .. no daemon was running on this machine
} else {
throw error
}
}
daemon.listProcesses(function(error, processes) {
// ...
daemon.disconnect(function (error) {
// ...
})
})
})
Attempts to connect to an already running daemon. If the daemon is not running it will attempt to start the daemon.
If this fails for any reason, the callback will receive an error.
Since the daemon can only be started as root, code calling this method will need to be run as root.
To connect with a non-privileged user, use Local.connect
instead.
Local.connectOrStart(function(error, daemon) {
if(error) throw error
daemon.listProcesses(function(error, processes) {
// ...
daemon.disconnect(function (error) {
// ...
})
})
})
The daemon
argument passed to Local.connect
and Local.connectOrStart
has the following methods:
Disconnect from the local daemon
daemon.disconnect(function(error) {
// all sockets should be closed and the process should be able to exit cleanly
})
Get a list of processes.
daemon.listProcesses(function(error, processes) {
// processes is an array of processInfo objects
})
Start a process. Pass either the path to a script, the name of a stopped process or installed app.
daemon.startProcess(pathOrName, options, function(error, processInfo) {
// processInfo.id is the process id of the newly started process
daemon.on('process:ready', function(error, readyProcessInfo) {
if(processInfo.id == readyProcessInfo.id) {
// process has now started
}
})
})
Stop a process. N.b. This method is for killing processes that have not started up properly - e.g. if it's status never gets beyond starting
. Otherwise you should use the kill method on it's RPC service instead.
daemon.findProcessInfoByName(name, function(error, processInfo) {
daemon.kill(processInfo.id, function(error) {
// process has now been killed, if it has not finished starting,
// otherwise `error` will be set - instead use processInfo.kill()
})
})
### removeProcess(id, function(error)
Remove a stopped process
// id is processInfo.id
daemon.removeProcess(id, function(error) {
})
Every managed process is assigned an id. This id is stable even if the process is restarted.
// id is processInfo.id
daemon.findProcessInfoById(id, function(error, processInfo) {
// processInfo is undefined if no process with that id existed
})
The pid of a managed process is assigned by the operating system and will change when the process is restarted.
// pid is the pid of a managed process
daemon.findProcessInfoByPid(pid, function(error, processInfo) {
// processInfo is undefined if no process with that pid existed
})
The name of the process is either specified by the -n
argument, it's the name of the script or it's the name
field of an adjacent package.json file.
// pid is the pid of a managed process
daemon.findProcessInfoByName(name, function(error, processInfo) {
// processInfo is undefined if no process with that name existed
})
daemon.deployApplication(name, url, user, console.info, console.error, function(error, appInfo) {
// ...
})
daemon.listApplications
daemon.listApplicationRefs
Calls the passed callback with the app's current ref name and commit id.
daemon.currentRef(appName, function (error, refName, commitHash) {
// ...
})
daemon.switchApplicationRefs
daemon.updateApplicationRefs
daemon.removeApplication
If you are connected as a privileged user (e.g. root or the user that guvnor is configured to run as), you will have these additional methods available.
daemon.dumpProcesses
daemon.restoreProcesses
daemon.generateRemoteRpcCertificates
daemon.kill
daemon.remoteHostConfig
daemon.addRemoteUser
daemon.removeRemoteUser
daemon.listRemoteUsers
daemon.rotateRemoteUserKeys
daemon.startProcessAsUser
### kill(callback(error))
To stop a process, first connect to the daemon, then use the daemon to connect to the process and kill it.
// id is processInfo.id. Alternatively use findProcessInfoByName or findProcessInfoByPid
daemon.findProcessInfoById(id, function(error, managedProcess) {
managedProcess.kill()
managedProcess.disconnect()
})
### Send a process an event
Causes the global process object to emit an event in the managed process.
// id is processInfo.id. Alternatively use findProcessInfoByName or findProcessInfoByPid
daemon.findProcessInfoById(id, function(error, managedProcess) {
managedProcess.send('custom:event', 'arg1', 'arg2')
managedProcess.disconnect()
})
In the managed process:
process.on('custom:event', function(arg1, arg2) {
console.info('received my custom event type with args', arg1, ar2)
})
Functions can be sent too (but note these are executed in the context of the sender, not the receiving process).
// id is processInfo.id. Alternatively use findProcessInfoByName or findProcessInfoByPid
daemon.findProcessInfoById(id, function(error, managedProcess) {
managedProcess.send('other:event', function(message) {
console.info('remote process said', message)
managedProcess.disconnect()
})
})
In the managed process:
process.on('other:event', function(callback) {
callback('hello world')
})
### Send a process a signal
// id is processInfo.id. Alternatively use findProcessInfoByName or findProcessInfoByPid
daemon.findProcessInfoById(id, function(error, managedProcess) {
managedProcess.signal('SIGHUP', managedProcess.disconnect.bind(managedProcess))
})
In the managed process:
process.on('SIGHUP', function() {
// do something
});
### Write to stdin for a process
// id is processInfo.id. Alternatively use findProcessInfoByName or findProcessInfoByPid
daemon.findProcessInfoById(id, function(error, managedProcess) {
managedProcess.write('hello', managedProcess.disconnect.bind(managedProcess))
})
In the managed process:
process.stdin.on('data', function(buffer) {
// do something with buffer
});