guvnor
Version:
A node process manager that isn't spanners all the way down
399 lines (286 loc) • 9.57 kB
Markdown
# Help
1. [Starting and stopping processes](processes.md)
1. [Controlling the Daemon](daemon.md)
1. [Managing clusters](clusters.md)
1. [Installing and running apps](apps.md)
1. [Remote access and monitoring (e.g. guv-web)](remote.md)
1. [Web interface](web.md)
1. [Web interface - configuration](web-config.md)
1. [Web interface - user management](web-users.md)
1. [Programmatic access](programmatic-access.md)
1. Programmatic access - local
1. [Programmatic access - remote](programmatic-access-remote.md)
1. [Programmatic access - events](programmatic-access-events.md)
## Programmatic access - local
A interface to an instance of [guvnor](http://github.com/tableflip/guvnor) running on the same host.
## Usage
```javascript
var Local = require('guvnor').Local
```
All methods take an optional config argument and an optional logger argument.
#### `config`
The config argument is a plain object of config settings as loaded from the config file. If omitted, the [default config](../guvnor) file will be loaded and it's properties overwritten by the config file at `/etc/guvnor/guvnor` if available.
#### `logger`
If specified the logger argument must have the following structure:
```javascript
{
info: function() {},
warn: function() {},
error: function() {},
debug: function() {}
}
```
If omitted it defaults to `console.info` and friends with `debug` being a no-op.
### Local.running([config], [logger], callback(running))
The passed callback will receive a boolean value indicating if the daemon is running or not.
```javascript
Local.running(function(running) {
console.info('Daemon is', running ? 'running' : 'not running')
})
```
### Local.connect([config], [logger], callback(error, daemon))
Attempts to connect to an already running daemon. If the daemon is not running the callback will receive an error.
```javascript
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) {
// ...
})
})
})
```
### Local.connectOrStart([config], [logger], callback(error, daemon))
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`](#localconnectconfig-logger-callbackerror-daemon) instead.
```javascript
Local.connectOrStart(function(error, daemon) {
if(error) throw error
daemon.listProcesses(function(error, processes) {
// ...
daemon.disconnect(function (error) {
// ...
})
})
})
```
## Daemon methods
The `daemon` argument passed to `Local.connect` and `Local.connectOrStart` has the following methods:
### disconnect(callback(error))
Disconnect from the local daemon
```javascript
daemon.disconnect(function(error) {
// all sockets should be closed and the process should be able to exit cleanly
})
```
### listProcesses(callback(error, processes))
Get a list of processes.
```javascript
daemon.listProcesses(function(error, processes) {
// processes is an array of processInfo objects
})
```
### startProcess(pathOrName, options, callback(error, processInfo))
Start a process. Pass either the path to a script, the name of a stopped process or installed app.
```javascript
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
}
})
})
```
### stopProcess(id, callback(error))
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](https://github.com/tableflip/guvnor/blob/master/docs/programmatic-access-local.md#killcallbackerror) method on it's RPC service instead.
```javascript
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
```javascript
// id is processInfo.id
daemon.removeProcess(id, function(error) {
})
```
### Find ProcessInfo by id
Every managed process is assigned an id. This id is stable even if the process is restarted.
```javascript
// id is processInfo.id
daemon.findProcessInfoById(id, function(error, processInfo) {
// processInfo is undefined if no process with that id existed
})
```
### Find ProcessInfo by pid
The pid of a managed process is assigned by the operating system and will change when the process is restarted.
```javascript
// pid is the pid of a managed process
daemon.findProcessInfoByPid(pid, function(error, processInfo) {
// processInfo is undefined if no process with that pid existed
})
```
### Find ProcessInfo by name
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.
```javascript
// pid is the pid of a managed process
daemon.findProcessInfoByName(name, function(error, processInfo) {
// processInfo is undefined if no process with that name existed
})
```
### deployApplication(name, url, user, onOut, onErr, callback)
```javascript
daemon.deployApplication(name, url, user, console.info, console.error, function(error, appInfo) {
// ...
})
```
### List applications
```javascript
daemon.listApplications
```
### List applications refs
```javascript
daemon.listApplicationRefs
```
### Current applications ref
Calls the passed callback with the app's current ref name and commit id.
```javascript
daemon.currentRef(appName, function (error, refName, commitHash) {
// ...
})
```
### Switch applications refs
```javascript
daemon.switchApplicationRefs
```
### Update applications refs
```javascript
daemon.updateApplicationRefs
```
### Remove application
```javascript
daemon.removeApplication
```
## Admin methods
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.
## Dump processes
```javascript
daemon.dumpProcesses
```
## Restore processes
```javascript
daemon.restoreProcesses
```
## Generate remote RPC certificates
```javascript
daemon.generateRemoteRpcCertificates
```
## kill
```javascript
daemon.kill
```
### Remote host config
```javascript
daemon.remoteHostConfig
```
### Add remote user
```javascript
daemon.addRemoteUser
```
### Remove remote user
```javascript
daemon.removeRemoteUser
```
### List remote users
```javascript
daemon.listRemoteUsers
```
### Rotate remote user keys
```javascript
daemon.rotateRemoteUserKeys
```
### Start process as user
```javascript
daemon.startProcessAsUser
```
## Process methods
### kill(callback(error))
To stop a process, first connect to the daemon, then use the daemon to connect to the process and kill it.
```javascript
// 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.
```javascript
// 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:
```javascript
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).
```javascript
// 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:
```javascript
process.on('other:event', function(callback) {
callback('hello world')
})
```
### Send a process a signal
```javascript
// 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:
```javascript
process.on('SIGHUP', function() {
// do something
});
```
### Write to stdin for a process
```javascript
// 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:
```javascript
process.stdin.on('data', function(buffer) {
// do something with buffer
});
```